diff --git a/analysis_options.yaml b/analysis_options.yaml index 61b6c4d..c42f5ab 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -27,3 +27,6 @@ linter: # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options +analyzer: + exclude: + - assets/** \ No newline at end of file diff --git a/assets/draw/p01/p01.dart b/assets/draw/p01/p01.dart new file mode 100644 index 0000000..0fa7609 --- /dev/null +++ b/assets/draw/p01/p01.dart @@ -0,0 +1 @@ +export 'p01_page.dart'; \ No newline at end of file diff --git a/assets/draw/p01/p01_page.dart b/assets/draw/p01/p01_page.dart new file mode 100644 index 0000000..6c6a607 --- /dev/null +++ b/assets/draw/p01/p01_page.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/gestures/events.dart'; +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; + +class P01Page extends StatelessWidget { + const P01Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p01', + demos: [ + s1.Paper(), + s2.Paper(), + ], + ); + } +} diff --git a/packages/idraw/lib/p01/s01_page.dart b/assets/draw/p01/s01.dart similarity index 100% rename from packages/idraw/lib/p01/s01_page.dart rename to assets/draw/p01/s01.dart diff --git a/packages/idraw/lib/p01/s02_page.dart b/assets/draw/p01/s02.dart similarity index 100% rename from packages/idraw/lib/p01/s02_page.dart rename to assets/draw/p01/s02.dart diff --git a/assets/draw/p02/p02.dart b/assets/draw/p02/p02.dart new file mode 100644 index 0000000..7f4911c --- /dev/null +++ b/assets/draw/p02/p02.dart @@ -0,0 +1 @@ +export 'p02_page.dart'; \ No newline at end of file diff --git a/assets/draw/p02/p02_page.dart b/assets/draw/p02/p02_page.dart new file mode 100644 index 0000000..246512f --- /dev/null +++ b/assets/draw/p02/p02_page.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; +import 's07.dart' as s7; +import 's08.dart' as s8; +import 's09.dart' as s9; +import 's10.dart' as s10; +import 's11.dart' as s11; +import 's12.dart' as s12; +import 's13.dart' as s13; + +class P02Page extends StatelessWidget { + const P02Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p02', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + s7.Paper(), + s8.Paper(), + s9.Paper(), + s10.Paper(), + s11.Paper(), + s12.Paper(), + s13.Paper(), + ], + ); + } +} diff --git a/assets/draw/p02/s01.dart b/assets/draw/p02/s01.dart new file mode 100644 index 0000000..d56336c --- /dev/null +++ b/assets/draw/p02/s01.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + // drawIsAntiAliasColor(canvas); + drawStyleStrokeWidth(canvas); + } + + // 测试 isAntiAlias 和 color属性 + void drawIsAntiAliasColor(Canvas canvas) { + Paint paint = Paint(); + canvas.drawCircle( + Offset(180, 180), + 170, + paint + ..color = Colors.blue + ..strokeWidth = 5); + canvas.drawCircle( + Offset(180 + 360.0, 180), + 170, + paint + ..isAntiAlias = false + ..color = Colors.red); + } + + // 测试 style 和 strokeWidth 属性 + void drawStyleStrokeWidth(Canvas canvas) { + Paint paint = Paint()..color = Colors.red; + canvas.drawCircle( + Offset(180, 180), + 150, + paint + ..style = PaintingStyle.stroke + ..strokeWidth = 50); + canvas.drawCircle( + Offset(180 + 360.0, 180), + 150, + paint + ..strokeWidth = 50 + ..style = PaintingStyle.fill); + //测试线 + canvas.drawLine( + Offset(0, 180 - 150.0), + Offset(1600, 180 - 150.0), + paint + ..strokeWidth = 1 + ..color = Colors.blueAccent); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p02/s02.dart b/assets/draw/p02/s02.dart new file mode 100644 index 0000000..f6a94f3 --- /dev/null +++ b/assets/draw/p02/s02.dart @@ -0,0 +1,115 @@ +import 'package:flutter/material.dart'; + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + // drawStrokeCap(canvas); + // drawStrokeJoin(canvas); + drawStrokeMiterLimit(canvas); + } + + // 测试 strokeCap 属性 + void drawStrokeCap(Canvas canvas) { + Paint paint = Paint(); + paint + ..style = PaintingStyle.stroke + ..color = Colors.blue + ..strokeWidth = 20; + canvas.drawLine( + Offset(50, 50), Offset(50, 150), paint..strokeCap = StrokeCap.butt); + canvas.drawLine(Offset(50 + 50.0, 50), Offset(50 + 50.0, 150), + paint..strokeCap = StrokeCap.round); + canvas.drawLine(Offset(50 + 50.0 * 2, 50), Offset(50 + 50.0 * 2, 150), + paint..strokeCap = StrokeCap.square); + + //测试线 + canvas.drawLine( + Offset(0, 50), + Offset(1600, 50), + paint + ..strokeWidth = 1 + ..color = Colors.cyanAccent); + canvas.drawLine( + Offset(0, 150), + Offset(1600, 150), + paint + ..strokeWidth = 1 + ..color = Colors.cyanAccent); + } + + // 测试 strokeJoin 属性 + void drawStrokeJoin(Canvas canvas) { + Paint paint = Paint(); + Path path = Path(); + paint + ..style = PaintingStyle.stroke + ..color = Colors.blue + ..strokeWidth = 20; + path.moveTo(50, 50); + path.lineTo(50, 150); + path.relativeLineTo(100, -50); + path.relativeLineTo(0, 100); + canvas.drawPath(path, paint..strokeJoin = StrokeJoin.bevel); + + path.reset(); + path.moveTo(50 + 150.0, 50); + path.lineTo(50 + 150.0, 150); + path.relativeLineTo(100, -50); + path.relativeLineTo(0, 100); + canvas.drawPath(path, paint..strokeJoin = StrokeJoin.miter); + + path.reset(); + path.moveTo(50 + 150.0 * 2, 50); + path.lineTo(50 + 150.0 * 2, 150); + path.relativeLineTo(100, -50); + path.relativeLineTo(0, 100); + canvas.drawPath(path, paint..strokeJoin = StrokeJoin.round); + } + + // 测试 strokeMiterLimit 属性 + void drawStrokeMiterLimit(Canvas canvas) { + Paint paint = Paint(); + Path path = Path(); + paint + ..style = PaintingStyle.stroke + ..color = Colors.blue + ..strokeJoin = StrokeJoin.miter + ..strokeWidth = 20; + for (int i = 0; i < 4; i++) { + path.reset(); + path.moveTo(50 + 150.0 * i, 50); + path.lineTo(50 + 150.0 * i, 150); + path.relativeLineTo(100, -(40.0 * i + 20)); + canvas.drawPath(path, paint..strokeMiterLimit = 2); + } + + for (int i = 0; i < 4; i++) { + path.reset(); + path.moveTo(50 + 150.0 * i, 50 + 150.0); + path.lineTo(50 + 150.0 * i, 150 + 150.0); + path.relativeLineTo(100, -(40.0 * i + 20)); + canvas.drawPath( + path, + paint + ..strokeMiterLimit = 3); + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p02/s03.dart b/assets/draw/p02/s03.dart new file mode 100644 index 0000000..e946d93 --- /dev/null +++ b/assets/draw/p02/s03.dart @@ -0,0 +1,78 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + drawShaderLinear(canvas); + } + + void drawShaderLinear(Canvas canvas) { + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + Paint paint = Paint(); + + paint + ..style = PaintingStyle.stroke + ..color = Colors.blue + ..strokeJoin = StrokeJoin.miter + ..strokeWidth = 100; + + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.clamp); + canvas.drawLine( + Offset(0, 100), + Offset(200, 100), + paint, + ); + + paint.shader = ui.Gradient.linear(Offset(0 + 220.0, 0), + Offset(100 + 220.0, 0), colors, pos, TileMode.repeated); + canvas.drawLine( + Offset(0 + 220.0, 100), + Offset(200 + 220.0, 100), + paint, + ); + + paint.shader = ui.Gradient.linear(Offset(0 + 220.0 * 2, 0), + Offset(100 + 220.0 * 2, 0), colors, pos, TileMode.mirror); + canvas.drawLine( + Offset(0 + 220.0 * 2, 100), + Offset(200 + 220.0 * 2, 100), + paint, + ); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s04.dart b/assets/draw/p02/s04.dart new file mode 100644 index 0000000..829132a --- /dev/null +++ b/assets/draw/p02/s04.dart @@ -0,0 +1,80 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget{ + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return CustomPaint( + painter: PaperPainter(), + ); + } + +} + +class PaperPainter extends CustomPainter { + + @override + void paint(Canvas canvas, Size size) { + drawShaderRadial(canvas); + } + + void drawShaderRadial(Canvas canvas) { + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + Paint paint = Paint(); + paint + ..style = PaintingStyle.fill + ..color = Colors.blue; + + paint.shader = ui.Gradient.radial( + Offset(80 + 150.0 * 0, 80), 25, colors, pos, TileMode.clamp); + canvas.drawCircle( + Offset(80 + 150.0 * 0, 80), + 50, + paint, + ); + + paint.shader = ui.Gradient.radial( + Offset(80 + 150.0 * 1, 80), 25, colors, pos, TileMode.repeated); + canvas.drawCircle( + Offset(80 + 150.0 * 1, 80), + 50, + paint, + ); + + paint.shader = ui.Gradient.radial( + Offset(80 + 150.0 * 2, 80), 25, colors, pos, TileMode.mirror); + canvas.drawCircle( + Offset(80 + 150.0 * 2, 80), + 50, + paint, + ); + paint.shader = ui.Gradient.radial(Offset(80 + 150.0 * 3, 80), 25, colors, + pos, TileMode.mirror, null, Offset(80 + 150.0 * 3 - 5, 80 - 5.0), 10); + canvas.drawCircle( + Offset(80 + 150.0 * 3, 80), + 50, + paint, + ); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s05.dart b/assets/draw/p02/s05.dart new file mode 100644 index 0000000..d8d1aa1 --- /dev/null +++ b/assets/draw/p02/s05.dart @@ -0,0 +1,82 @@ +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget{ + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return CustomPaint( + painter: PaperPainter(), + ); + } + +} + +class PaperPainter extends CustomPainter { + + @override + void paint(Canvas canvas, Size size) { + drawShaderSweep(canvas); + } + + void drawShaderSweep(Canvas canvas) { + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + Paint paint = Paint(); + paint + ..style = PaintingStyle.fill + ..color = Colors.blue; + + paint.shader = ui.Gradient.sweep( + Offset(80 + 150.0 * 0, 80), colors, pos, TileMode.clamp, pi / 2, pi); + canvas.drawCircle( + Offset(80 + 150.0 * 0, 80), + 50, + paint, + ); + paint.shader = ui.Gradient.sweep( + Offset(80 + 150.0 * 1, 80), colors, pos, TileMode.repeated, pi / 2, pi); + canvas.drawCircle( + Offset(80 + 150.0 * 1, 80), + 50, + paint, + ); + paint.shader = ui.Gradient.sweep( + Offset(80 + 150.0 * 2, 80), colors, pos, TileMode.mirror, pi / 2, pi); + canvas.drawCircle( + Offset(80 + 150.0 * 2, 80), + 50, + paint, + ); + + paint.shader = ui.Gradient.sweep( + Offset(80 + 150.0 * 3, 80), colors, pos, TileMode.clamp); + canvas.drawCircle( + Offset(80 + 150.0 * 3, 80), + 50, + paint, + ); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} + diff --git a/assets/draw/p02/s06.dart b/assets/draw/p02/s06.dart new file mode 100644 index 0000000..20d5f0f --- /dev/null +++ b/assets/draw/p02/s06.dart @@ -0,0 +1,97 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'dart:ui' as ui; + +import 'package:flutter/services.dart'; + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + bool get hasImage => _img != null; + + @override + void initState() { + _loadImage(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + child: hasImage + ? CustomPaint( + painter: ImageShaderPainter(_img), + ) + : Container(), + ); + } + + void _loadImage() async { + _img = await loadImage(AssetImage('assets/images/wy_200x300.jpg')); + setState(() {}); + } + + late ImageStreamListener listener; + //异步加载图片成为ui.Image + Future loadImage(ImageProvider provider) { + Completer completer = Completer(); + ImageStream stream = provider.resolve(ImageConfiguration()); + listener = ImageStreamListener((info, syno) { + final ui.Image image = info.image; //监听图片流,获取图片 + completer.complete(image); + stream.removeListener(listener); + }); + stream.addListener(listener); + return completer.future; + } +} + +class ImageShaderPainter extends CustomPainter { + ui.Image? img; + late Paint _paint; + + ImageShaderPainter(this.img) { + _paint = Paint(); + } + + @override + void paint(Canvas canvas, Size size) { + if(img==null) return; + _paint.shader = ImageShader( + img!, + TileMode.repeated, + TileMode.repeated, + Float64List.fromList([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + ])); + + canvas.drawCircle(Offset(100, 100), 50, _paint); + canvas.drawCircle( + Offset(100 + 120.0, 100), + 50, + _paint + ..strokeWidth = 10 + ..style = PaintingStyle.stroke); + canvas.drawLine( + Offset(100 + 120.0 * 2, 50), + Offset(100 + 120.0 * 2, 50 + 100.0), + _paint + ..strokeWidth = 30 + ..style = PaintingStyle.stroke); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s07.dart b/assets/draw/p02/s07.dart new file mode 100644 index 0000000..46a9be5 --- /dev/null +++ b/assets/draw/p02/s07.dart @@ -0,0 +1,54 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget{ + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return CustomPaint( + painter: PaperPainter(), + ); + } +} + +class PaperPainter extends CustomPainter { + + @override + void paint(Canvas canvas, Size size) { + drawBlendMode(canvas,BlendMode.lighten); + canvas.translate(150, 0); + drawBlendMode(canvas,BlendMode.hue); + canvas.translate(150, 0); + drawBlendMode(canvas,BlendMode.plus); + canvas.translate(150, 0); + drawBlendMode(canvas,BlendMode.hardLight); + + } + void drawBlendMode(Canvas canvas,BlendMode mode) { + var paint = Paint(); + canvas.drawCircle(Offset(100, 100), 50, paint..color = Color(0x88ff0000)); + + canvas.drawCircle( + Offset(140, 70), + 50, + paint + ..color = Color(0x8800ff00) + ..blendMode = mode); + + canvas.drawCircle( + Offset(140, 130), + 50, + paint + ..color = Color(0x880000ff) + ..blendMode = mode); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s08.dart b/assets/draw/p02/s08.dart new file mode 100644 index 0000000..6926743 --- /dev/null +++ b/assets/draw/p02/s08.dart @@ -0,0 +1,36 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget{ + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return CustomPaint( + painter: PaperPainter(), + ); + } +} + +class PaperPainter extends CustomPainter { + + @override + void paint(Canvas canvas, Size size) { + drawInvertColors(canvas); + } + void drawInvertColors(Canvas canvas) { + var paint = Paint(); + paint..color = Color(0xff009A44); + canvas.drawCircle(Offset(100, 100), 50, paint..invertColors = false); + canvas.drawCircle(Offset(100+120.0, 100), 50, paint..invertColors = true); + } + + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s09.dart b/assets/draw/p02/s09.dart new file mode 100644 index 0000000..8e51fe0 --- /dev/null +++ b/assets/draw/p02/s09.dart @@ -0,0 +1,98 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + Uint8List bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); + return decodeImageFromList(bytes); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(_img), + )); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if (img == null) return; + drawColorFilter(canvas); + } + + double get imgW => img?.width.toDouble()??0; + + double get imgH => img?.height.toDouble()??0; + + void drawColorFilter(Canvas canvas) { + var paint = Paint(); + paint.colorFilter = ColorFilter.linearToSrgbGamma(); + _drawImage(canvas, paint, move: false); + + paint.colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.modulate); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.difference); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.blue, BlendMode.plus); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.blue, BlendMode.lighten); + _drawImage(canvas, paint); + } + + void _drawImage(Canvas canvas, Paint paint, {bool move = true}) { + if (move) { + canvas.translate(120, 0); + } else { + canvas.translate(20, 20); + } + canvas.drawImageRect(img!, Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW / 2, imgH / 2), paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s10.dart b/assets/draw/p02/s10.dart new file mode 100644 index 0000000..bff98fc --- /dev/null +++ b/assets/draw/p02/s10.dart @@ -0,0 +1,123 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + bool get hasImage => _img != null; + + @override + void initState() { + _loadImage(); + super.initState(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + child: hasImage ? CustomPaint( + painter: PaperPainter(_img) , + ): Container(), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if(img!=null) { + drawColorFilter(canvas); + } + } + + double get imgW => img!.width.toDouble(); + double get imgH => img!.height.toDouble(); + + void drawColorFilter(Canvas canvas) { + var paint =Paint(); + const ColorFilter identity = ColorFilter.matrix([ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, + ]); + _drawImage(canvas, paint..colorFilter=identity,move: false); + + const ColorFilter sepia = ColorFilter.matrix([ + 0.393, 0.769, 0.189, 0, 0, + 0.349, 0.686, 0.168, 0, 0, + 0.272, 0.534, 0.131, 0 , 0, + 0, 0, 0, 1, 0, + ]); + _drawImage(canvas, paint..colorFilter=sepia); + + const ColorFilter invert = ColorFilter.matrix([ + -1, 0, 0, 0, 255, + 0, -1, 0, 0, 255, + 0, 0, -1, 0, 255, + 0, 0, 0, 1, 0, + ]); + _drawImage(canvas, paint..colorFilter=invert); + + const ColorFilter greyscale = ColorFilter.matrix([ + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0, 0, 0, 1, 0, + ]); + _drawImage(canvas, paint..colorFilter=greyscale); + + const n = 90.0; + const ColorFilter light = ColorFilter.matrix([ + 1,0,0,0,n, + 0,1,0,0,n, + 0,0,1,0,n, + 0,0,0,1,0 + ]); + _drawImage(canvas, paint..colorFilter=light); + } + + void _drawImage(Canvas canvas, Paint paint,{bool move=true}) { + if(move){ + canvas.translate(120, 0); + }else{ + canvas.translate(20, 20); + } + canvas.drawImageRect(img!, + Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW/2, imgH/2), + paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s11.dart b/assets/draw/p02/s11.dart new file mode 100644 index 0000000..5987e8b --- /dev/null +++ b/assets/draw/p02/s11.dart @@ -0,0 +1,97 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + bool get hasImage => _img != null; + + @override + void initState() { + _loadImage(); + super.initState(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + child: hasImage ? CustomPaint( + painter: PaperPainter(_img) , + ): Container(), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if(img!=null) { + drawMaskFilter(canvas); + } + } + + double get imgW => img!.width.toDouble(); + double get imgH => img!.height.toDouble(); + + void drawMaskFilter(Canvas canvas) { + var paint =Paint(); + _drawImage(canvas, paint,move: false); + + paint.maskFilter=MaskFilter.blur(BlurStyle.inner, 20); + _drawImage(canvas, paint); + + paint.maskFilter=MaskFilter.blur(BlurStyle.outer, 3); + _drawImage(canvas, paint); + + paint.maskFilter=MaskFilter.blur(BlurStyle.solid, 5); + _drawImage(canvas, paint); + + paint.maskFilter=MaskFilter.blur(BlurStyle.normal, 3); + _drawImage(canvas, paint); + + } + + void _drawImage(Canvas canvas, Paint paint,{bool move=true}) { + if(move){ + canvas.translate(120, 0); + }else{ + canvas.translate(20, 20); + } + canvas.drawImageRect(img!, + Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW/2, imgH/2), + paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s12.dart b/assets/draw/p02/s12.dart new file mode 100644 index 0000000..40831ae --- /dev/null +++ b/assets/draw/p02/s12.dart @@ -0,0 +1,100 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + bool get hasImage => _img != null; + + @override + void initState() { + _loadImage(); + super.initState(); + } + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + child: hasImage ? CustomPaint( + painter: PaperPainter(_img) , + ): Container(), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if(img!=null) { + drawImageFilter(canvas); + } + } + + double get imgW => img!.width.toDouble(); + double get imgH => img!.height.toDouble(); + + + + void drawImageFilter(Canvas canvas) { + var paint =Paint(); + _drawImage(canvas, paint,move: false); + + paint.imageFilter=ui.ImageFilter.blur(sigmaX: 0.4,sigmaY: 0.4); + _drawImage(canvas, paint); + + paint.imageFilter=ui.ImageFilter.blur(sigmaX: 0.6,sigmaY: 0.6); + _drawImage(canvas, paint); + + paint.imageFilter=ui.ImageFilter.blur(sigmaX: 0.8,sigmaY: 0.8); + _drawImage(canvas, paint); + + paint.imageFilter=ui.ImageFilter.matrix( + Matrix4.skew(pi/8,0).storage + ); + _drawImage(canvas, paint); + } + + void _drawImage(Canvas canvas, Paint paint,{bool move=true}) { + if(move){ + canvas.translate(120, 0); + }else{ + canvas.translate(20, 20); + } + canvas.drawImageRect(img!, + Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW/2, imgH/2), + paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p02/s13.dart b/assets/draw/p02/s13.dart new file mode 100644 index 0000000..a8ae402 --- /dev/null +++ b/assets/draw/p02/s13.dart @@ -0,0 +1,100 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + bool get hasImage => _img != null; + + @override + void initState() { + _loadImage(); + super.initState(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + child: hasImage ? CustomPaint( + painter: PaperPainter(_img) , + ): Container(), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if(img!=null) { + drawFilterQuality(canvas); + } + } + + double get imgW => img!.width.toDouble(); + double get imgH => img!.height.toDouble(); + + void drawFilterQuality(Canvas canvas) { + var paint =Paint(); + paint.imageFilter=ui.ImageFilter.blur(sigmaX: 0.6,sigmaY: 0.6); + paint.maskFilter=MaskFilter.blur(BlurStyle.inner, 20); + paint.colorFilter=ColorFilter.mode(Colors.yellow, BlendMode.modulate); + + paint.filterQuality=FilterQuality.none; + _drawImage(canvas, paint,move: false); + + paint.filterQuality=FilterQuality.low; + _drawImage(canvas, paint); + + paint.filterQuality=FilterQuality.medium; + _drawImage(canvas, paint); + + paint.filterQuality=FilterQuality.high; + _drawImage(canvas, paint); + + } + + void _drawImage(Canvas canvas, Paint paint,{bool move=true}) { + if(move){ + canvas.translate(120, 0); + }else{ + canvas.translate(20, 20); + } + canvas.drawImageRect(img!, + Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW/2, imgH/2), + paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p03/p03.dart b/assets/draw/p03/p03.dart new file mode 100644 index 0000000..fb5811c --- /dev/null +++ b/assets/draw/p03/p03.dart @@ -0,0 +1 @@ +export 'p03_page.dart'; \ No newline at end of file diff --git a/assets/draw/p03/p03_page.dart b/assets/draw/p03/p03_page.dart new file mode 100644 index 0000000..2c8fdbf --- /dev/null +++ b/assets/draw/p03/p03_page.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; +import 's07.dart' as s7; +import 's08.dart' as s8; +import 's09.dart' as s9; +import 's10.dart' as s10; +import 's11.dart' as s11; +import 's12.dart' as s12; +import 's13.dart' as s13; + +class P03Page extends StatelessWidget { + const P03Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p03', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + s7.Paper(), + s8.Paper(), + s9.Paper(), + s10.Paper(), + s11.Paper(), + s12.Paper(), + s13.Paper(), + ], + ); + } +} diff --git a/assets/draw/p03/s01.dart b/assets/draw/p03/s01.dart new file mode 100644 index 0000000..634563c --- /dev/null +++ b/assets/draw/p03/s01.dart @@ -0,0 +1,45 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + + @override + void paint(Canvas canvas, Size size) { + var paint = Paint() + ..style = PaintingStyle.fill + ..color = Colors.blue; + // 画布起点移到屏幕中心 + canvas.translate(size.width / 2, size.height / 2); + canvas.drawCircle(Offset(0, 0), 50, paint); + canvas.drawLine( + Offset(20, 20), + Offset(50, 50), + paint + ..color = Colors.red + ..strokeWidth = 5 + ..strokeCap = StrokeCap.round + ..style = PaintingStyle.stroke); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s02.dart b/assets/draw/p03/s02.dart new file mode 100644 index 0000000..193f872 --- /dev/null +++ b/assets/draw/p03/s02.dart @@ -0,0 +1,96 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + late Paint _gridPint; // 画笔 + final double step = 20; // 小格边长 + final double strokeWidth = .5; // 线宽 + final Color color = Colors.grey; // 线颜色 + + PaperPainter() { + _gridPint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + canvas.translate(size.width / 2, size.height / 2); + _drawGrid(canvas, size); + _drawPart(canvas); + } + + void _drawPart(Canvas canvas) { + var paint = Paint() + ..style = PaintingStyle.fill + ..color = Colors.blue; + canvas.drawCircle(Offset(0, 0), 50, paint); + canvas.drawLine( + Offset(20, 20), + Offset(50, 50), + paint + ..color = Colors.red + ..strokeWidth = 5 + ..strokeCap = StrokeCap.round + ..style = PaintingStyle.stroke); + } + + void _drawGrid(Canvas canvas, Size size) { + _drawBottomRight(canvas, size); + + canvas.save(); + canvas.scale(1, -1); //沿x轴镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, 1); //沿y轴镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, -1); //沿原点镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + } + + void _drawBottomRight(Canvas canvas, Size size) { + canvas.save(); + for (int i = 0; i < size.height / 2 / step; i++) { + canvas.drawLine(Offset(0, 0), Offset(size.width / 2, 0), _gridPint); + canvas.translate(0, step); + } + canvas.restore(); + + canvas.save(); + for (int i = 0; i < size.width / 2 / step; i++) { + canvas.drawLine(Offset(0, 0), Offset(0, size.height / 2), _gridPint); + canvas.translate(step , 0); + } + canvas.restore(); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p03/s03.dart b/assets/draw/p03/s03.dart new file mode 100644 index 0000000..a560f7b --- /dev/null +++ b/assets/draw/p03/s03.dart @@ -0,0 +1,111 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + late Paint _gridPint; + final double step = 20; + final double strokeWidth = .5; + + PaperPainter() { + _gridPint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = strokeWidth + ..color = Colors.grey; + } + + @override + void paint(Canvas canvas, Size size) { + canvas.translate(size.width / 2, size.height / 2); + _drawGrid(canvas, size); + + var paint = Paint() + ..style = PaintingStyle.fill + ..color = Colors.blue; + + _drawPart(canvas, paint); + _drawDot(canvas, paint); + } + + void _drawPart(Canvas canvas, Paint paint) { + canvas.drawCircle(Offset(0, 0), 50, paint); + canvas.drawLine( + Offset(20, 20), + Offset(50, 50), + paint + ..color = Colors.red + ..strokeWidth = 5 + ..strokeCap = StrokeCap.round + ..style = PaintingStyle.stroke); + } + + void _drawDot(Canvas canvas, Paint paint) { + final int count = 12; + paint + ..color = Colors.orangeAccent + ..style = PaintingStyle.stroke; + canvas.save(); + for (int i = 0; i < count; i++) { + var step = 2 * pi / count; + canvas.drawLine(Offset(80, 0), Offset(100, 0), paint); + canvas.rotate(step); + } + canvas.restore(); + } + + void _drawGrid(Canvas canvas, Size size) { + _drawBottomRight(canvas, size); + + canvas.save(); + canvas.scale(1, -1); //沿x轴镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, 1); //沿y轴镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, -1); //沿原点镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + } + + void _drawBottomRight(Canvas canvas, Size size) { + canvas.save(); + for (int i = 0; i < size.height / 2 / step; i++) { + canvas.drawLine(Offset(0, 0), Offset(size.width / 2, 0), _gridPint); + canvas.translate(0, step); + } + canvas.restore(); + + canvas.save(); + for (int i = 0; i < size.width / 2 / step; i++) { + canvas.drawLine(Offset(0, 0), Offset(0, size.height / 2), _gridPint); + canvas.translate(step , 0); + } + canvas.restore(); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s04.dart b/assets/draw/p03/s04.dart new file mode 100644 index 0000000..df393f0 --- /dev/null +++ b/assets/draw/p03/s04.dart @@ -0,0 +1,156 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + late Paint _gridPint; + final double step = 20; + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + _gridPint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = strokeWidth + ..color = Colors.grey; + } + + @override + void paint(Canvas canvas, Size size) { + canvas.translate(size.width / 2, size.height / 2); + _drawGrid(canvas, size); + _drawAxis(canvas,size); + + _drawPointsWithPoints(canvas); + // _drawPointsWithLines(canvas); + _drawPointLineWithPolygon(canvas); + _drawRawPoints(canvas); + } + + final List points = [ + Offset(-120, -20), + Offset(-80, -80), + Offset(-40, -40), + Offset(0, -100), + Offset(40, -140), + Offset(80, -160), + Offset(120, -100), + ]; + + void _drawPointsWithPoints(Canvas canvas) { + _paint + ..color = Colors.red + ..style = PaintingStyle.stroke..strokeWidth=10 + ..strokeCap = StrokeCap.round; + canvas.drawPoints(PointMode.points, points, _paint); + } + + void _drawPointsWithLines(Canvas canvas) { + _paint + ..color = Colors.red + ..style = PaintingStyle.stroke + ..strokeWidth = 1 + ..strokeCap = StrokeCap.round; + canvas.drawPoints(PointMode.lines, points, _paint); + } + + void _drawPointLineWithPolygon(Canvas canvas) { + _paint + ..color = Colors.red + ..style = PaintingStyle.stroke + ..strokeWidth = 1 + ..strokeCap = StrokeCap.round; + canvas.drawPoints(PointMode.polygon, points, _paint); + } + + void _drawRawPoints(Canvas canvas) { + Float32List pos = Float32List.fromList([ + -120, -20,-80, -80,-40, + -40,0, -100,40, -140, + 80, -160,120, -100]); + _paint + ..color = Colors.red + ..style = PaintingStyle.stroke + ..strokeWidth = 10 + ..strokeCap = StrokeCap.round; + canvas.drawRawPoints(PointMode.points, pos, _paint); + } + + void _drawAxis(Canvas canvas, Size size) { + _paint..color=Colors.blue..strokeWidth=1.5; + canvas.drawLine(Offset(-size.width/2, 0) , Offset(size.width/2, 0),_paint); + canvas.drawLine(Offset( 0,-size.height/2) , Offset( 0,size.height/2),_paint); + canvas.drawLine(Offset( 0,size.height/2) , Offset( 0-7.0,size.height/2-10),_paint); + canvas.drawLine(Offset( 0,size.height/2) , Offset( 0+7.0,size.height/2-10),_paint); + canvas.drawLine(Offset(size.width/2, 0) , Offset(size.width/2-10, 7),_paint); + canvas.drawLine(Offset(size.width/2, 0) , Offset(size.width/2-10, -7),_paint); + } + + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; + + void _drawGrid(Canvas canvas, Size size) { + _drawBottomRight(canvas, size); + canvas.save(); + canvas.scale(1, -1); //沿x轴镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, 1); //沿y轴镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, -1); //沿原点镜像 + _drawBottomRight(canvas, size); + canvas.restore(); + } + + void _drawBottomRight(Canvas canvas, Size size) { + canvas.save(); + for (int i = 0; i < size.height / 2 / step; i++) { + canvas.drawLine(Offset(0, 0), Offset(size.width / 2, 0), _gridPint); + canvas.translate(0, step); + } + canvas.restore(); + + canvas.save(); + for (int i = 0; i < size.width / 2 / step; i++) { + canvas.drawLine(Offset(0, 0), Offset(0, size.height / 2), _gridPint); + canvas.translate(step , 0); + } + canvas.restore(); + } + + +} diff --git a/assets/draw/p03/s05.dart b/assets/draw/p03/s05.dart new file mode 100644 index 0000000..1d44c4e --- /dev/null +++ b/assets/draw/p03/s05.dart @@ -0,0 +1,133 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + + canvas.translate(size.width / 2, size.height / 2); + + _drawDRRect(canvas); + + canvas.translate(-240, 0); + _drawRect(canvas); + + canvas.translate(480, 0); + _drawRRect(canvas); + } + + void _drawRect(Canvas canvas) { + _paint + ..color = Colors.blue + ..strokeWidth = 1.5; + //【1】.矩形中心构造 + Rect rectFromCenter = + Rect.fromCenter(center: Offset(0, 0), width: 160, height: 160); + canvas.drawRect(rectFromCenter, _paint); + //【2】.矩形左上右下构造 + Rect rectFromLTRB = Rect.fromLTRB(-120, -120, -80, -80); + canvas.drawRect(rectFromLTRB, _paint..color = Colors.red); + //【3】. 矩形左上宽高构造 + Rect rectFromLTWH = Rect.fromLTWH(80, -120, 40, 40); + canvas.drawRect(rectFromLTWH, _paint..color = Colors.orange); + //【4】. 矩形内切圆构造 + Rect rectFromCircle = Rect.fromCircle(center: Offset(100, 100), radius: 20); + canvas.drawRect(rectFromCircle, _paint..color = Colors.green); + //【5】. 矩形两点构造 + Rect rectFromPoints = Rect.fromPoints(Offset(-120, 80), Offset(-80, 120)); + canvas.drawRect(rectFromPoints, _paint..color = Colors.purple); + } + + void _drawRRect(Canvas canvas) { + _paint + ..color = Colors.blue + ..strokeWidth = 1.5; + //【1】.圆角矩形fromRectXY构造 + Rect rectFromCenter = + Rect.fromCenter(center: Offset(0, 0), width: 160, height: 160); + canvas.drawRRect(RRect.fromRectXY(rectFromCenter, 40, 20), _paint); + + //【2】.圆角矩形fromLTRBXY构造 + canvas.drawRRect(RRect.fromLTRBXY(-120, -120, -80, -80, 10, 10), + _paint..color = Colors.red); + + //【3】. 圆角矩形fromLTRBR构造 + canvas.drawRRect(RRect.fromLTRBR(80, -120, 120, -80, Radius.circular(10)), + _paint..color = Colors.orange); + + //【4】. 圆角矩形fromLTRBAndCorners构造 + canvas.drawRRect( + RRect.fromLTRBAndCorners(80, 80, 120, 120, + bottomRight: Radius.elliptical(10, 10)), + _paint..color = Colors.green); + + //【5】. 矩形两点构造 + Rect rectFromPoints = Rect.fromPoints(Offset(-120, 80), Offset(-80, 120)); + canvas.drawRRect( + RRect.fromRectAndCorners(rectFromPoints, + bottomLeft: Radius.elliptical(10, 10)), + _paint..color = Colors.purple); + } + + void _drawDRRect(Canvas canvas) { + _paint + ..color = Colors.blue + ..strokeWidth = 1.5; + Rect outRect = + Rect.fromCenter(center: Offset(0, 0), width: 160, height: 160); + Rect inRect = + Rect.fromCenter(center: Offset(0, 0), width: 100, height: 100); + + canvas.drawDRRect(RRect.fromRectXY(outRect, 20, 20), + RRect.fromRectXY(inRect, 20, 20), _paint); + + Rect outRect2 = + Rect.fromCenter(center: Offset(0, 0), width: 60, height: 60); + Rect inRect2 = Rect.fromCenter(center: Offset(0, 0), width: 40, height: 40); + canvas.drawDRRect(RRect.fromRectXY(outRect2, 15, 15), + RRect.fromRectXY(inRect2, 10, 10), _paint..color = Colors.green); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s06.dart b/assets/draw/p03/s06.dart new file mode 100644 index 0000000..4d28c6b --- /dev/null +++ b/assets/draw/p03/s06.dart @@ -0,0 +1,91 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + _draw(canvas); + } + + void _draw(Canvas canvas) { + canvas.save(); + canvas.translate(-200, 0); + canvas.drawCircle(Offset(0, 0), 60, _paint); + canvas.restore(); + + var rect = Rect.fromCenter(center: Offset(0, 0), height: 100, width: 120); + canvas.drawOval(rect, _paint); + + canvas.save(); + canvas.translate(200, 0); + //drawArc(矩形区域,起始弧度,扫描弧度,是否连中心,画笔) + canvas.drawArc(rect, 0, pi / 2 * 3, true, _paint); + canvas.restore(); + } + + void _drawArcDetail(Canvas canvas) { + var rect = Rect.fromCenter(center: Offset(0, 0), height: 100, width: 100); + _paint + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + canvas.save(); + canvas.translate(-200, 0); + canvas.drawArc(rect, 0, pi / 2 * 3, false, _paint); + canvas.restore(); + canvas.drawArc(rect, 0, pi / 2 * 3, true, _paint); + canvas.save(); + canvas.translate(200, 0); + var a = pi / 8; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, _paint..color=Colors.yellowAccent..style=PaintingStyle.fill); + canvas.translate(40, 0); + canvas.drawCircle(Offset(0, 0), 6, _paint); + canvas.translate(25, 0); + canvas.drawCircle(Offset(0, 0), 6, _paint); + canvas.restore(); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s07.dart b/assets/draw/p03/s07.dart new file mode 100644 index 0000000..b51cee4 --- /dev/null +++ b/assets/draw/p03/s07.dart @@ -0,0 +1,45 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.drawColor(Colors.blue, BlendMode.lighten); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s08.dart b/assets/draw/p03/s08.dart new file mode 100644 index 0000000..6b5be7d --- /dev/null +++ b/assets/draw/p03/s08.dart @@ -0,0 +1,74 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + + _paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(size.width, 0), + colors, pos, TileMode.clamp); + + _paint.blendMode=BlendMode.lighten; + + canvas.drawPaint(_paint); + } + + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s09.dart b/assets/draw/p03/s09.dart new file mode 100644 index 0000000..850e4b4 --- /dev/null +++ b/assets/draw/p03/s09.dart @@ -0,0 +1,73 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + @override + void paint(Canvas canvas, Size size) { + // coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Paint paint = Paint() + ..style = PaintingStyle.fill + ..color = Colors.white + ..isAntiAlias = true; + double relativeX = 100; + double angle = 0; + double width = 10; + double height = 10; + double center = relativeX + width / 2; + if(angle == 0) { + center = relativeX + width/4; + } else if (angle == 2) { + center = relativeX + width/4*3; + } + + Path trianglePath = Path() + ..addPolygon([Offset(relativeX, height), Offset(relativeX + width, height), Offset(center, 0),], false)..close(); + + Path rectanglePath = Path() + ..addRRect(RRect.fromLTRBR(0, 10, 160, 100, Radius.circular(8)))..close(); + + + canvas.drawShadow(Path.combine(PathOperation.xor, trianglePath, rectanglePath), Colors.black, 3, false); + canvas.drawPath(Path.combine(PathOperation.xor, trianglePath, rectanglePath), paint..color = Colors.white); + paint.maskFilter = MaskFilter.blur(BlurStyle.inner, 20); + canvas.drawPath(Path.combine(PathOperation.xor, trianglePath, rectanglePath), paint..color=Color(0xffBEC4C0)); + + } + + + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s10.dart b/assets/draw/p03/s10.dart new file mode 100644 index 0000000..541495f --- /dev/null +++ b/assets/draw/p03/s10.dart @@ -0,0 +1,68 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + path.lineTo(60, 60); + path.lineTo(-60, 60); + path.lineTo(60, -60); + path.lineTo(-60, -60); + path.close(); + + canvas.drawPath(path, _paint); + canvas.translate(140, 0); + canvas.drawPath( + path, + _paint + ..style = PaintingStyle.stroke + ..strokeWidth = 2); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s11.dart b/assets/draw/p03/s11.dart new file mode 100644 index 0000000..68ff835 --- /dev/null +++ b/assets/draw/p03/s11.dart @@ -0,0 +1,79 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + // canvas.save(); + var rect = Rect.fromCenter(center: Offset.zero,width: 360,height: 240); + canvas.clipRect(rect,doAntiAlias: true,clipOp: ui.ClipOp.intersect); + + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + + _paint.shader = ui.Gradient.linear( + rect.centerLeft, rect.centerRight, + colors, pos, TileMode.clamp); + + _paint.blendMode=BlendMode.lighten; + + canvas.drawPaint(_paint); + // canvas.restore(); + // canvas.drawColor(Colors.blue, BlendMode.lighten); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s12.dart b/assets/draw/p03/s12.dart new file mode 100644 index 0000000..01a1521 --- /dev/null +++ b/assets/draw/p03/s12.dart @@ -0,0 +1,49 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + // canvas.save(); + var rect = Rect.fromCenter(center: Offset.zero,width: 200,height: 100); + canvas.clipRRect(RRect.fromRectAndRadius(rect, Radius.circular(30))); + canvas.drawColor(Colors.red, BlendMode.darken); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p03/s13.dart b/assets/draw/p03/s13.dart new file mode 100644 index 0000000..5e33345 --- /dev/null +++ b/assets/draw/p03/s13.dart @@ -0,0 +1,52 @@ +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + path.lineTo(80, 80); + path.lineTo(-80, 80); + path.close(); + + canvas.clipPath(path); + canvas.drawColor(Colors.red, BlendMode.darken); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p04/p04.dart b/assets/draw/p04/p04.dart new file mode 100644 index 0000000..8a11e69 --- /dev/null +++ b/assets/draw/p04/p04.dart @@ -0,0 +1 @@ +export 'p04_page.dart'; \ No newline at end of file diff --git a/assets/draw/p04/p04_page.dart b/assets/draw/p04/p04_page.dart new file mode 100644 index 0000000..f9a8b0d --- /dev/null +++ b/assets/draw/p04/p04_page.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; +import 's07.dart' as s7; + + +class P04Page extends StatelessWidget { + const P04Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p04', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + s7.Paper(), + ], + ); + } +} diff --git a/assets/draw/p04/s01.dart b/assets/draw/p04/s01.dart new file mode 100644 index 0000000..8347d5b --- /dev/null +++ b/assets/draw/p04/s01.dart @@ -0,0 +1,83 @@ +import 'dart:async'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _image; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _image = + await loadImageFromAssets('assets/images/wy_300x200.jpg'); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, child: CustomPaint(painter: PaperPainter(_image))); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final ui.Image? image; + final Coordinate coordinate = Coordinate(); + + PaperPainter(this.image) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + _drawImage(canvas); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => + image != oldDelegate.image; + + void _drawImage(Canvas canvas) { + if (image != null) { + canvas.drawImage( + image!, Offset(-image!.width / 2, -image!.height / 2), _paint); + } + } +} diff --git a/assets/draw/p04/s02.dart b/assets/draw/p04/s02.dart new file mode 100644 index 0000000..0b87f70 --- /dev/null +++ b/assets/draw/p04/s02.dart @@ -0,0 +1,118 @@ +import 'dart:async'; +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _image = + await loadImageFromAssets('assets/images/wy_300x200.jpg'); + setState(() {}); + } + + ui.Image? _image; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter( + _image, + ))); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final ui.Image? image; + final Coordinate coordinate = Coordinate(); + + PaperPainter(this.image) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + _drawImage(canvas); + _drawImageRect(canvas); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => image != oldDelegate.image; + + void _drawImage(Canvas canvas) { + if (image != null) { + canvas.drawImage( + image!, Offset(-image!.width / 2, -image!.height / 2), _paint); + } + } + + void _drawImageRect(Canvas canvas) { + if (image != null) { + canvas.drawImageRect( + image!, + Rect.fromCenter( + center: Offset(image!.width / 2, image!.height / 2), + width: 60, + height: 60), + Rect.fromLTRB(0, 0, 100, 100).translate(200, 0), + _paint); + + canvas.drawImageRect( + image!, + Rect.fromCenter( + center: Offset(image!.width / 2, image!.height / 2 - 60), + width: 60, + height: 60), + Rect.fromLTRB(0, 0, 100, 100).translate(-280, -100), + _paint); + + canvas.drawImageRect( + image!, + Rect.fromCenter( + center: Offset(image!.width / 2 + 60, image!.height / 2), + width: 60, + height: 60), + Rect.fromLTRB(0, 0, 100, 100).translate(-280, 50), + _paint); + } + } +} diff --git a/assets/draw/p04/s03.dart b/assets/draw/p04/s03.dart new file mode 100644 index 0000000..b2d5dec --- /dev/null +++ b/assets/draw/p04/s03.dart @@ -0,0 +1,129 @@ +import 'dart:async'; +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +/// +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + @override + void initState() { + super.initState(); + _loadImage(); + } + + + void _loadImage() async { + _image = + await loadImageFromAssets('assets/images/right_chat.png'); + setState(() {}); + } + + ui.Image? _image; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter( + _image, + ))); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final ui.Image? image; + final Coordinate coordinate = Coordinate(); + + PaperPainter(this.image) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + _drawImageNine(canvas); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => image != oldDelegate.image; + + void _drawImageNine(Canvas canvas) { + if (image != null) { + canvas.drawImageNine( + image!, + Rect.fromCenter( + center: Offset(image!.width / 2, image!.height - 6.0), + width: image!.width - 20.0, + height: 2.0), + Rect.fromCenter( + center: Offset( + 0, + 0, + ), + width: 300, + height: 120), + _paint); + + canvas.drawImageNine( + image!, + Rect.fromCenter( + center: Offset(image!.width / 2, image!.height - 6.0), + width: image!.width - 20.0, + height: 2.0), + Rect.fromCenter( + center: Offset( + 0, + 0, + ), + width: 100, + height: 50) + .translate(250, 0), + _paint); + + canvas.drawImageNine( + image!, + Rect.fromCenter( + center: Offset(image!.width / 2, image!.height - 6.0), + width: image!.width - 20.0, + height: 2.0), + Rect.fromCenter( + center: Offset( + 0, + 0, + ), + width: 80, + height: 250) + .translate(-250, 0), + _paint); + } + } +} diff --git a/assets/draw/p04/s04.dart b/assets/draw/p04/s04.dart new file mode 100644 index 0000000..4fcd18b --- /dev/null +++ b/assets/draw/p04/s04.dart @@ -0,0 +1,121 @@ +import 'dart:async'; +import 'dart:math'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +/// +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + @override + void initState() { + super.initState(); + _loadImage(); + } + + + void _loadImage() async { + _image = + await loadImageFromAssets('assets/images/shoot.png'); + setState(() {}); + } + + ui.Image? _image; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter( + _image, + ))); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final ui.Image? image; + final Coordinate coordinate = Coordinate(); + + final List allSprites = []; + + PaperPainter(this.image) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + if (image == null) { + return; + } + coordinate.paint(canvas, size); + + allSprites.add(Sprite( + position: Rect.fromLTWH(0, 325, 257, 166), + offset: Offset(0, 0), + alpha: 255, + rotation: 0)); + + allSprites.add(Sprite( + position: Rect.fromLTWH(0, 325, 257, 166), + offset: Offset(257, 130), + alpha: 255, + rotation: 0)); + + final List transforms = allSprites + .map((sprite) => RSTransform.fromComponents( + rotation: sprite.rotation, + scale: 1.0, + anchorX: sprite.anchor.dx, + anchorY: sprite.anchor.dy, + translateX: sprite.offset.dx, + translateY: sprite.offset.dy, + )) + .toList(); + + final List rects = + allSprites.map((sprite) => sprite.position).toList(); + + canvas.drawAtlas(image!, transforms, rects, null, null, null, _paint); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => image != oldDelegate.image; +} + +class Sprite { + Rect position; // 雪碧图 中 图片矩形区域 + Offset offset; // 移动偏倚 + Offset anchor; // 移动偏倚 + int alpha; // 透明度 + double rotation; // 旋转角度 + + Sprite({this.offset=Offset.zero,this.anchor=Offset.zero, this.alpha=255, this.rotation=0,required this.position}); +} diff --git a/assets/draw/p04/s05.dart b/assets/draw/p04/s05.dart new file mode 100644 index 0000000..87f9897 --- /dev/null +++ b/assets/draw/p04/s05.dart @@ -0,0 +1,135 @@ +import 'dart:async'; +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +/// +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _image = + await loadImageFromAssets('assets/images/shoot.png'); + setState(() {}); + } + + ui.Image? _image; + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter( + _image, + ))); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final ui.Image? image; + final Coordinate coordinate = Coordinate(); + + final List allSprites = []; + + PaperPainter(this.image) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + if (image == null) { + return; + } + + coordinate.paint(canvas, size); + + allSprites.add(Sprite( + position: Rect.fromLTWH(0, 325, 257, 166), + offset: Offset(0, 0), + alpha: 255, + rotation: 0)); + + allSprites.add(Sprite( + position: Rect.fromLTWH(0, 325, 257, 166), + offset: Offset(257, 130), + alpha: 255, + rotation: 0)); + + Float32List rectList = Float32List(allSprites.length * 4); + Float32List transformList = Float32List(allSprites.length * 4); + + for (int i = 0; i < allSprites.length; i++) { + final Sprite sprite = allSprites[i]; + + rectList[i * 4 + 0] = sprite.position.left; + rectList[i * 4 + 1] = sprite.position.top; + rectList[i * 4 + 2] = sprite.position.right; + rectList[i * 4 + 3] = sprite.position.bottom; + + final RSTransform transform = RSTransform.fromComponents( + rotation: sprite.rotation, + scale: 1.0, + anchorX: sprite.anchor.dx, + anchorY: sprite.anchor.dy, + translateX: sprite.offset.dx, + translateY: sprite.offset.dy, + ); + + transformList[i * 4 + 0] = transform.scos; + transformList[i * 4 + 1] = transform.ssin; + transformList[i * 4 + 2] = transform.tx; + transformList[i * 4 + 3] = transform.ty; + + } + + canvas.drawRawAtlas(image!, transformList, rectList, null, null, null, _paint); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => image != oldDelegate.image; +} + +class Sprite { + Rect position; // 雪碧图 中 图片矩形区域 + Offset offset; // 移动偏倚 + Offset anchor; // 移动偏倚 + int alpha; // 透明度 + double rotation; // 旋转角度 + + Sprite({this.offset=Offset.zero,this.anchor=Offset.zero, this.alpha=255, this.rotation=0,required this.position}); +} \ No newline at end of file diff --git a/assets/draw/p04/s06.dart b/assets/draw/p04/s06.dart new file mode 100644 index 0000000..05793ca --- /dev/null +++ b/assets/draw/p04/s06.dart @@ -0,0 +1,137 @@ +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + // _drawTextWithParagraph(canvas,TextAlign.left); + // _drawTextWithParagraph(canvas,TextAlign.center); + // _drawTextWithParagraph(canvas,TextAlign.right); + + // _drawWithTextPaint(canvas); + // _drawTextPaintShowSize(canvas); + _drawTextPaintWithPaint(canvas); + } + + void _drawTextWithParagraph(Canvas canvas, TextAlign textAlign) { + var builder = ui.ParagraphBuilder(ui.ParagraphStyle( + textAlign: textAlign, + fontSize: 40, + textDirection: TextDirection.ltr, + maxLines: 1, + )); + builder.pushStyle( + ui.TextStyle( + color: Colors.black87, textBaseline: ui.TextBaseline.alphabetic), + ); + builder.addText("Flutter Unit"); + ui.Paragraph paragraph = builder.build(); + paragraph.layout(ui.ParagraphConstraints(width: 300)); + canvas.drawParagraph(paragraph, Offset(0, 0)); + + canvas.drawRect(Rect.fromLTRB(0, 0, 300, 40), + _paint..color = Colors.blue.withAlpha(33)); + } + + void _drawWithTextPaint(Canvas canvas) { + var textPainter = TextPainter( + text: TextSpan( + text: 'Flutter Unit', + style: TextStyle(fontSize: 40, color: Colors.black)), + textAlign: TextAlign.center, + textDirection: TextDirection.ltr); + + // 进行布局 + textPainter.layout(); + textPainter.paint(canvas, Offset.zero); + } + + void _drawTextPaintShowSize(Canvas canvas) { + TextPainter textPainter = TextPainter( + text: TextSpan( + text: 'Flutter Unit', + style: TextStyle( + // foreground: Paint()..style=PaintingStyle.stroke, + fontSize: 40, + color: Colors.black)), + textAlign: TextAlign.center, + textDirection: TextDirection.ltr); + + textPainter.layout(); // 进行布局 + Size size = textPainter.size; // 尺寸必须在布局后获取 + textPainter.paint(canvas, Offset(-size.width / 2, -size.height / 2)); + + canvas.drawRect( + Rect.fromLTRB(0, 0, size.width, size.height) + .translate(-size.width / 2, -size.height / 2), + _paint..color = Colors.blue.withAlpha(33)); + } + + void _drawTextPaintWithPaint(Canvas canvas) { + Paint textPaint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 1; + TextPainter textPainter = TextPainter( + text: TextSpan( + text: 'Flutter Unit by 张风捷特烈', + style: TextStyle( + foreground: textPaint, fontSize: 40)), + textAlign: TextAlign.center, + textDirection: TextDirection.ltr); + + textPainter.layout(maxWidth: 280); // 进行布局 + Size size = textPainter.size; // 尺寸必须在布局后获取 + textPainter.paint(canvas, Offset(-size.width / 2, -size.height / 2)); + + canvas.drawRect( + Rect.fromLTRB(0, 0, size.width, size.height) + .translate(-size.width / 2, -size.height / 2), + _paint..color = Colors.blue.withAlpha(33)); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => false; +} diff --git a/assets/draw/p04/s07.dart b/assets/draw/p04/s07.dart new file mode 100644 index 0000000..f211ddf --- /dev/null +++ b/assets/draw/p04/s07.dart @@ -0,0 +1,125 @@ +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(step: 25); + + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + PaperPainter() { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + _drawTextLeft(canvas); + _drawTextTextAlignRight(canvas); + _drawTextPaint(canvas, "100", offset: Offset(0, 0)); + } + + void _drawTextLeft(Canvas canvas) { + var builder = ui.ParagraphBuilder(ui.ParagraphStyle( + textAlign: TextAlign.left, + fontSize: 40, + textDirection: TextDirection.ltr, + maxLines: 1, + )) + ..pushStyle( + ui.TextStyle( + color: Colors.black87, textBaseline: ui.TextBaseline.alphabetic), + ) + ..addText("Flutter Unit"); + + canvas.drawParagraph( + builder.build()..layout(ui.ParagraphConstraints(width: 300)), + Offset(0, -100)); + canvas.drawRect(Rect.fromLTRB(0, 0 - 100.0, 300, 40 - 100.0), + _paint..color = Colors.blue.withAlpha(33)); + } + + void _drawTextCenter(Canvas canvas,String str) { + var builder = ui.ParagraphBuilder(ui.ParagraphStyle( + textAlign: TextAlign.center, + fontSize: 12, + textDirection: TextDirection.ltr, + maxLines: 1, + )) + ..pushStyle( + ui.TextStyle( + color: Colors.black87, textBaseline: ui.TextBaseline.alphabetic), + ) + ..addText(str); + + canvas.drawParagraph( + builder.build()..layout(ui.ParagraphConstraints(width: 12.0*str.length)), + Offset(0, 0)); + + } + + void _drawTextTextAlignRight(Canvas canvas) { + var builder = ui.ParagraphBuilder(ui.ParagraphStyle( + textAlign: TextAlign.right, + fontSize: 40, + textDirection: TextDirection.ltr, + maxLines: 1, + )) + ..pushStyle( + ui.TextStyle( + color: Colors.black87, textBaseline: ui.TextBaseline.alphabetic), + ) + ..addText("Flutter Unit"); + + canvas.drawParagraph( + builder.build()..layout(ui.ParagraphConstraints(width: 300)), + Offset(0, 100)); + + canvas.drawRect(Rect.fromLTRB(0, 0 + 100.0, 300, 40 + 100.0), + _paint..color = Colors.blue.withAlpha(33)); + } + + void _drawTextPaint(Canvas canvas, String text, + {Offset offset = Offset.zero}) { + TextPainter( + text: TextSpan( + text: text, style: TextStyle(fontSize: 12, color: Colors.black)), + textAlign: TextAlign.left, + textDirection: TextDirection.ltr) + ..layout(maxWidth: 300) + ..paint(canvas, offset); + + canvas.drawRect(Rect.fromLTRB(0, 0, 300, 40), + _paint..color = Colors.blue.withAlpha(33)); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/p05.dart b/assets/draw/p05/p05.dart new file mode 100644 index 0000000..8ee5f6b --- /dev/null +++ b/assets/draw/p05/p05.dart @@ -0,0 +1 @@ +export 'p05_page.dart'; \ No newline at end of file diff --git a/assets/draw/p05/p05_page.dart b/assets/draw/p05/p05_page.dart new file mode 100644 index 0000000..c0d23de --- /dev/null +++ b/assets/draw/p05/p05_page.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; +import 's07.dart' as s7; +import 's08.dart' as s8; +import 's09.dart' as s9; +import 's10.dart' as s10; +import 's11.dart' as s11; + + +class P05Page extends StatelessWidget { + const P05Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p05', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + s7.Paper(), + s8.Paper(), + s9.Paper(), + s10.Paper(), + s11.Paper(), + ], + ); + } +} diff --git a/assets/draw/p05/s01.dart b/assets/draw/p05/s01.dart new file mode 100644 index 0000000..9e5792d --- /dev/null +++ b/assets/draw/p05/s01.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.deepPurpleAccent + ..style = PaintingStyle.fill; + path + ..moveTo(0, 0) //移至(0,0)点 + ..lineTo(60, 80) //从(0,0)画线到(60, 80) 点 + ..lineTo(60, 0) //从(60,80)画线到(60, 0) 点 + ..lineTo(0, -80) //从(60, 0) 画线到(0, -80)点 + ..close(); //闭合路径 + canvas.drawPath(path, paint); + + paint + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + path + ..moveTo(0, 0) + ..lineTo(-60, 80) + ..lineTo(-60, 0) + ..lineTo(0, -80); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s02.dart b/assets/draw/p05/s02.dart new file mode 100644 index 0000000..6e0ceaa --- /dev/null +++ b/assets/draw/p05/s02.dart @@ -0,0 +1,60 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} +class PaperPainter extends CustomPainter { + + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.green + ..style = PaintingStyle.fill; + path + ..relativeMoveTo(0, 0) + ..relativeLineTo(100, 120) + ..relativeLineTo(-10, -60) + ..relativeLineTo( 60,-10,) + ..close(); + canvas.drawPath(path, paint); + + path.reset(); + paint + ..style = PaintingStyle.stroke..color=Colors.green + ..strokeWidth = 2; + path + ..relativeMoveTo(-200, 0) + ..relativeLineTo(100, 120) + ..relativeLineTo(-10, -60) + ..relativeLineTo( 60,-10,)..close(); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s03.dart b/assets/draw/p05/s03.dart new file mode 100644 index 0000000..249946f --- /dev/null +++ b/assets/draw/p05/s03.dart @@ -0,0 +1,54 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + var rect = Rect.fromCenter(center: Offset(0, 0), width: 160, height: 100); + + path.lineTo(30, 30); + path..arcTo(rect, 0, pi * 1.5, true); + canvas.drawPath(path, paint); + + path.reset(); + canvas.translate(200, 0); + path.lineTo(30, 30); + path..arcTo(rect, 0, pi * 1.5, false); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s04.dart b/assets/draw/p05/s04.dart new file mode 100644 index 0000000..c25d1f0 --- /dev/null +++ b/assets/draw/p05/s04.dart @@ -0,0 +1,77 @@ + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + path.lineTo(80, -40); + + //绘制中间 + path + ..arcToPoint( + Offset(40, 40), + radius: Radius.circular(60), + largeArc: false, + ) + ..close(); + canvas.drawPath(path, paint); + + //绘制左侧 + path.reset(); + canvas.translate(-150, 0); + path.lineTo(80, -40); + path + ..arcToPoint(Offset(40, 40), + radius: Radius.circular(60), largeArc: true, clockwise: false) + ..close(); + canvas.drawPath(path, paint); + + //绘制右侧 + path.reset(); + canvas.translate(150 + 150.0, 0); + path.lineTo(80, -40); + path + ..arcToPoint( + Offset(40, 40), + radius: Radius.circular(60), + largeArc: true, + ) + ..close(); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s05.dart b/assets/draw/p05/s05.dart new file mode 100644 index 0000000..c0a6a66 --- /dev/null +++ b/assets/draw/p05/s05.dart @@ -0,0 +1,80 @@ + +import 'dart:ui'; +import 'package:flutter/material.dart'; +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + + final Coordinate coordinate=Coordinate(); + + final Offset p1 = Offset(80, -100); + final Offset p2 = Offset(160, 0); + + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + //抛物线 + path.conicTo(p1.dx, p1.dy, p2.dx, p2.dy, 1); + _drawHelper(canvas); + canvas.drawPath(path, paint); + + //椭圆线 + path.reset(); + canvas.translate(-180, 0); + path.conicTo(p1.dx, p1.dy, p2.dx, p2.dy, 0.5); + canvas.drawPath(path, paint); + _drawHelper(canvas); + + //双曲线 + path.reset(); + canvas.translate(180+180.0, 0); + path.conicTo(p1.dx, p1.dy, p2.dx, p2.dy, 1.5); + canvas.drawPath(path, paint); + _drawHelper(canvas); + } + + void _drawHelper(Canvas canvas) { + canvas.drawPoints( + PointMode.points, + [ + p1, + p2, + ], + Paint() + ..strokeWidth = 6 + ..strokeCap = StrokeCap.round + ..color = Colors.blue); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s06.dart b/assets/draw/p05/s06.dart new file mode 100644 index 0000000..f21f54e --- /dev/null +++ b/assets/draw/p05/s06.dart @@ -0,0 +1,88 @@ + +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + + +class PaperPainter extends CustomPainter { + + final Coordinate coordinate = Coordinate(); + + final Offset p1 = Offset(100, -100); + final Offset p2 = Offset(160, 50); + + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + path.quadraticBezierTo(p1.dx, p1.dy, p2.dx, p2.dy); + _drawHelper(canvas); + + path.relativeQuadraticBezierTo(p1.dx, p1.dy, p2.dx, p2.dy); + canvas.drawPath(path, paint); + + } + + void _drawHelper(Canvas canvas) { + canvas.drawPoints( + PointMode.polygon, + [ + Offset.zero, + p1, + p2, + p1.translate(160, 50), + p2.translate(160, 50), + ], + Paint() + ..strokeWidth = 1 + ..strokeCap = StrokeCap.round + ..color = Colors.blue); + canvas.drawPoints( + PointMode.points, + [ + Offset.zero, + p1, + p2, + p1.translate(160, 50), + p2.translate(160, 50), + ], + Paint() + ..strokeWidth = 6 + ..strokeCap = StrokeCap.round + ..color = Colors.blue); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s07.dart b/assets/draw/p05/s07.dart new file mode 100644 index 0000000..2342730 --- /dev/null +++ b/assets/draw/p05/s07.dart @@ -0,0 +1,91 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + final Offset p1 = Offset(80, -100); + final Offset p2 = Offset(80, 50); + final Offset p3 = Offset(160, 50); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint(); + + paint + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + path.cubicTo(p1.dx, p1.dy, p2.dx, p2.dy, p3.dx, p3.dy); + _drawHelper(canvas); + + path.relativeCubicTo(p1.dx, p1.dy, p2.dx, p2.dy, p3.dx, p3.dy); + canvas.drawPath(path, paint); + + } + + void _drawHelper(Canvas canvas) { + canvas.drawPoints( + PointMode.lines, + [ + Offset.zero, + p1, + p2, + p3, + Offset.zero + p3, + p1 + p3, + p2 + p3, + p3 + p3, + ], + Paint() + ..strokeWidth = 1 + ..strokeCap = StrokeCap.round + ..color = Colors.blue); + canvas.drawPoints( + PointMode.points, + [ + Offset.zero, + p1, + p2, + p3, + Offset.zero + p3, + p1 + p3, + p2 + p3, + p3 + p3, + ], + Paint() + ..strokeWidth = 6 + ..strokeCap = StrokeCap.round + ..color = Colors.blue); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s08.dart b/assets/draw/p05/s08.dart new file mode 100644 index 0000000..05b873d --- /dev/null +++ b/assets/draw/p05/s08.dart @@ -0,0 +1,50 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + Rect rect = Rect.fromPoints(Offset(100, 100), Offset(160, 160)); + path + ..lineTo(100, 100) + ..addRect(rect) + ..relativeLineTo(100, -100) + ..addRRect(RRect.fromRectXY(rect.translate(100, -100), 10, 10)); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s09.dart b/assets/draw/p05/s09.dart new file mode 100644 index 0000000..40faf9a --- /dev/null +++ b/assets/draw/p05/s09.dart @@ -0,0 +1,52 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + Rect rect = Rect.fromPoints(Offset(100, 100), Offset(160, 140)); + path + ..lineTo(100, 100) + ..addOval(rect) + ..relativeLineTo(100, -100) + ..addArc(rect.translate(100 + 60.0, -100), 0, pi); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s10.dart b/assets/draw/p05/s10.dart new file mode 100644 index 0000000..554cb21 --- /dev/null +++ b/assets/draw/p05/s10.dart @@ -0,0 +1,66 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter( + coordinate: Coordinate() + ), + ), + ); + } +} + + +class PaperPainter extends CustomPainter { + + final Coordinate? coordinate; + PaperPainter({this.coordinate}); + + @override + void paint(Canvas canvas, Size size) { + coordinate?.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + var p0 = Offset(100, 100); + path + ..lineTo(100, 100) + ..addPolygon([ + p0, + p0.translate(20, -20), + p0.translate(40, -20), + p0.translate(60, 0), + p0.translate(60, 20), + p0.translate(40, 40), + p0.translate(20, 40), + p0.translate(0, 20), + ], true) + ..addPath( + Path()..relativeQuadraticBezierTo(125, -100, 260, 0), Offset.zero) + ..lineTo(160, 100); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p05/s11.dart b/assets/draw/p05/s11.dart new file mode 100644 index 0000000..739ab41 --- /dev/null +++ b/assets/draw/p05/s11.dart @@ -0,0 +1,39 @@ +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(step: 25); + + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => false; +} diff --git a/assets/draw/p06/p06.dart b/assets/draw/p06/p06.dart new file mode 100644 index 0000000..1edcaaf --- /dev/null +++ b/assets/draw/p06/p06.dart @@ -0,0 +1 @@ +export 'p06_page.dart'; \ No newline at end of file diff --git a/assets/draw/p06/p06_page.dart b/assets/draw/p06/p06_page.dart new file mode 100644 index 0000000..cd2e2c6 --- /dev/null +++ b/assets/draw/p06/p06_page.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; + +class P06Page extends StatelessWidget { + const P06Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p06', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + ], + ); + } +} diff --git a/assets/draw/p06/s01.dart b/assets/draw/p06/s01.dart new file mode 100644 index 0000000..9c03a4c --- /dev/null +++ b/assets/draw/p06/s01.dart @@ -0,0 +1,56 @@ + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + + + final Coordinate coordinate = Coordinate(); + PaperPainter(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + + Paint paint = Paint() + ..color = Colors.purpleAccent + ..strokeWidth = 2 + ..style = PaintingStyle.stroke; + + path + ..lineTo(100, 100) + ..relativeLineTo(0, -50) + ..close(); + + canvas.drawPath(path, paint); + canvas.drawPath(path.shift(Offset(100, 0)), paint); + canvas.drawPath(path.shift(Offset(200, 0)), paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p06/s02.dart b/assets/draw/p06/s02.dart new file mode 100644 index 0000000..736007d --- /dev/null +++ b/assets/draw/p06/s02.dart @@ -0,0 +1,61 @@ + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purple + ..style = PaintingStyle.fill; + + path + ..relativeMoveTo(0, 0) + ..relativeLineTo(-30, 120) + ..relativeLineTo(30, -30) + ..relativeLineTo(30, 30) + ..close(); + + canvas.drawPath(path, paint); + + print(path.contains(Offset(20, 20))); + print(path.contains(Offset(0, 20))); + + Rect bounds = path.getBounds(); + canvas.drawRect( + bounds, + Paint() + ..color = Colors.orange + ..style = PaintingStyle.stroke + ..strokeWidth = 1); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p06/s03.dart b/assets/draw/p06/s03.dart new file mode 100644 index 0000000..13d8cff --- /dev/null +++ b/assets/draw/p06/s03.dart @@ -0,0 +1,56 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + + + final Coordinate coordinate = Coordinate(); + + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint() + ..color = Colors.purple + ..style = PaintingStyle.fill; + path + ..relativeMoveTo(0, 0) + ..relativeLineTo(-30, 120) + ..relativeLineTo(30, -30) + ..relativeLineTo( 30,30) + ..close(); + + for(int i=0;i<8;i++){ + canvas.drawPath(path.transform(Matrix4.rotationZ(i*pi/4).storage), paint); + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p06/s04.dart b/assets/draw/p06/s04.dart new file mode 100644 index 0000000..5d763b8 --- /dev/null +++ b/assets/draw/p06/s04.dart @@ -0,0 +1,68 @@ + + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + + + final Coordinate coordinate= Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Path path = Path(); + Paint paint = Paint(); + paint + ..color = Colors.purple + ..style = PaintingStyle.fill; + path + ..relativeMoveTo(0, 0) + ..relativeLineTo(-30, 120) + ..relativeLineTo(30, -30) + ..relativeLineTo( 30,30) + ..close(); + + + var pathOval =Path()..addOval(Rect.fromCenter(center: Offset(0, 0),width: 60,height: 60)); + canvas.drawPath(Path.combine(PathOperation.difference, path, pathOval), paint); + + canvas.translate(120, 0); + canvas.drawPath(Path.combine(PathOperation.intersect, path, pathOval), paint); + + canvas.translate(120, 0); + canvas.drawPath(Path.combine(PathOperation.union, path, pathOval), paint); + + canvas.translate(-120*3.0, 0); + canvas.drawPath(Path.combine(PathOperation.reverseDifference, path, pathOval), paint); + + canvas.translate(-120, 0); + canvas.drawPath(Path.combine(PathOperation.xor, path, pathOval), paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p06/s05.dart b/assets/draw/p06/s05.dart new file mode 100644 index 0000000..dde4a0a --- /dev/null +++ b/assets/draw/p06/s05.dart @@ -0,0 +1,74 @@ + +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate.dart'; + + + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatelessWidget{ + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } + +} + +class PaperPainter extends CustomPainter { + final Coordinate coordinate = Coordinate(); + + + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Paint paint = Paint() + ..color = Colors.purple + ..strokeWidth = 1 + ..style = PaintingStyle.stroke; + + Path path = Path(); + path + ..relativeMoveTo(0, 0) + ..relativeLineTo(-30, 120) + ..relativeLineTo(30, -30) + ..relativeLineTo(30, 30) + ..close(); + + path.addOval(Rect.fromCenter(center: Offset.zero, width: 50, height: 50)); + + PathMetrics pms = path.computeMetrics(); + pms.forEach((pm) { + print( + "---length:-${pm.length}----contourIndex:-${pm.contourIndex}----contourIndex:-${pm.isClosed}----"); + + Tangent? tangent = pm.getTangentForOffset(pm.length * 0.5); + if(tangent==null) return; + print( + "---position:-${tangent.position}----angle:-${tangent.angle}----vector:-${tangent.vector}----"); + + canvas.drawCircle( + tangent.position, 5, Paint()..color = Colors.deepOrange); + }); + + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p06/s06.dart b/assets/draw/p06/s06.dart new file mode 100644 index 0000000..9973d70 --- /dev/null +++ b/assets/draw/p06/s06.dart @@ -0,0 +1,83 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/5/1 +/// contact me by email 1981462002@qq.com +/// 说明: + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _ctrl; + double progress = 0.0; + + @override + void initState() { + super.initState(); + _ctrl = AnimationController( + duration: Duration(seconds: 3), vsync: this) + ..forward(); + } + + @override + void dispose() { + _ctrl.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(progress: _ctrl), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + final Animation progress; + + PaperPainter({required this.progress}) : super(repaint: progress); + + @override + void paint(Canvas canvas, Size size) { + canvas.translate(size.width / 2, size.height / 2); + + Paint paint = Paint() + ..color = Colors.purple + ..strokeWidth = 1 + ..style = PaintingStyle.stroke; + + Path path = Path(); + path + ..relativeMoveTo(0, 0) + ..relativeLineTo(-30, 120) + ..relativeLineTo(30, -30) + ..relativeLineTo(30, 30) + ..close(); + + path.addOval(Rect.fromCenter(center: Offset.zero, width: 50, height: 50)); + + PathMetrics pms = path.computeMetrics(); + for (PathMetric pm in pms) { + Tangent? tangent = pm.getTangentForOffset(pm.length * progress.value); + if(tangent ==null) continue; + canvas.drawCircle( + tangent.position, 5, Paint()..color = Colors.deepOrange); + } + + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) => + oldDelegate.progress != progress; +} diff --git a/assets/draw/p07/p07.dart b/assets/draw/p07/p07.dart new file mode 100644 index 0000000..6a2965b --- /dev/null +++ b/assets/draw/p07/p07.dart @@ -0,0 +1 @@ +export 'p07_page.dart'; \ No newline at end of file diff --git a/assets/draw/p07/p07_page.dart b/assets/draw/p07/p07_page.dart new file mode 100644 index 0000000..c38d6a5 --- /dev/null +++ b/assets/draw/p07/p07_page.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; + +class P07Page extends StatelessWidget { + const P07Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p07', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + ], + ); + } +} diff --git a/assets/draw/p07/s01.dart b/assets/draw/p07/s01.dart new file mode 100644 index 0000000..3fa49e4 --- /dev/null +++ b/assets/draw/p07/s01.dart @@ -0,0 +1,61 @@ + +import 'package:flutter/material.dart'; + +import '../components/coordinate_pro.dart'; + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + static const double step = 20; // 方格变长 + final Coordinate coordinate = Coordinate(step: step); + + // 颜色列表 256 个元素 + final Color colors = Color(0xffBBE9F7).withRed(0); + // final Color colors = Color(0xff00E9F9); + + @override + void paint(Canvas canvas, Size size) { + Paint paint = Paint(); + + canvas.save(); + canvas.translate(size.width / 2, size.height / 2); + + List values = colors.value.toRadixString(2).split('').toList(); + + // 遍历列表 绘制矩形色块 + canvas.translate(-step * 4.0, -step * 2.0); + values.asMap().forEach((i, v) { + int line = (i % 8); // 行 + int row = i ~/ 8; // 列 + var topLeft = Offset(step * line, step * row); + var rect = Rect.fromPoints(topLeft, topLeft.translate(step, step)); + canvas.drawRect( + rect, paint..color = v == '0' ? Colors.red : Colors.black); + }); + + canvas.restore(); + coordinate.paint(canvas, size); //绘制坐标系 + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p07/s02.dart b/assets/draw/p07/s02.dart new file mode 100644 index 0000000..dece160 --- /dev/null +++ b/assets/draw/p07/s02.dart @@ -0,0 +1,55 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; + +import '../components/coordinate_pro.dart'; +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + static const double step = 15; // 方格变长 + final Coordinate coordinate = Coordinate(step: step); + + // 颜色列表 256 个元素 + final List colors = + List.generate(256, (i) => Color.fromARGB(255 - i, 255, 0, 0)); + + @override + void paint(Canvas canvas, Size size) { + Paint paint = Paint(); + + canvas.save(); + canvas.translate(size.width / 2, size.height / 2); + + // 遍历列表 绘制矩形色块 + canvas.translate(-step * 8.0, -step * 8.0); + colors.asMap().forEach((i, color) { + int line = (i % 16); // 行 + int row = i ~/ 16; // 列 + var topLeft = Offset(step * line, step * row); + var rect = Rect.fromPoints(topLeft, topLeft.translate(step, step)); + canvas.drawRect(rect, paint..color = color); + }); + + canvas.restore(); + coordinate.paint(canvas, size); //绘制坐标系 + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/assets/draw/p07/s03.dart b/assets/draw/p07/s03.dart new file mode 100644 index 0000000..5b1ce84 --- /dev/null +++ b/assets/draw/p07/s03.dart @@ -0,0 +1,112 @@ +import 'dart:async'; +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _image; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _image = + await loadImageFromAssets('assets/images/icon_head.png'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, child: CustomPaint(painter: PaperPainter(_image))); + } + + +} + +class PaperPainter extends CustomPainter { + + final ui.Image? image; + + + PaperPainter(this.image); + + static const double step = 20; // 方格变长 + final Coordinate coordinate = Coordinate(step: step); + + // 颜色列表 256 个元素 + final List colors = + List.generate(256, (i) => Color.fromARGB(255 - i, 255, 0, 0)); + + @override + void paint(Canvas canvas, Size size) { + if(image ==null) return; + + Paint srcPaint = Paint(); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-step * 17, -step * 7); + Paint dstPaint = Paint(); + BlendMode.values.asMap().forEach((i, value) { + int line = i ~/ 10; + int row = i % 10; + canvas.save(); + + canvas.translate(3.7 * step * row, 5.5 * step * line); + canvas.drawImageRect(image!, Rect.fromPoints(Offset.zero, Offset(image!.width*1.0,image!.height*1.0)), + Rect.fromCenter(center:Offset.zero, width: 25*2.0,height: 25*2.0), dstPaint); + + srcPaint + ..color = Color(0xffff0000) + ..blendMode = value; + canvas.drawRect( + Rect.fromPoints(Offset.zero, Offset(20 * 2.0, 20 * 2.0)), srcPaint); + + _simpleDrawText(canvas,value.toString().split(".")[1],offset: Offset(-10, 50)); + canvas.restore(); + }); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; + + void _simpleDrawText(Canvas canvas, String str, + {Offset offset = Offset.zero, Color color = Colors.black}) { + var builder = ui.ParagraphBuilder(ui.ParagraphStyle( + textAlign: TextAlign.left, + fontSize: 11, + textDirection: TextDirection.ltr, + maxLines: 1, + )) + ..pushStyle( + ui.TextStyle(color: color, textBaseline: ui.TextBaseline.alphabetic), + ) + ..addText(str); + + canvas.drawParagraph( + builder.build() + ..layout(ui.ParagraphConstraints(width: 11.0 * str.length)), + offset); + } +} diff --git a/assets/draw/p07/s04.dart b/assets/draw/p07/s04.dart new file mode 100644 index 0000000..fa9e121 --- /dev/null +++ b/assets/draw/p07/s04.dart @@ -0,0 +1,123 @@ +import 'dart:async'; +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate_pro.dart'; + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _srcImage; + ui.Image? _dstImage; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _srcImage = await loadImageFromAssets('assets/images/src.png'); + _dstImage = await loadImageFromAssets('assets/images/dst.png'); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint(painter: PaperPainter(_srcImage, _dstImage))); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + +} + +class PaperPainter extends CustomPainter { + final ui.Image? srcImage; + final ui.Image? dstImage; + + PaperPainter(this.srcImage, this.dstImage); + + static const double step = 20; // 方格变长 + final Coordinate coordinate = Coordinate(step: step); + + + @override + void paint(Canvas canvas, Size size) { + if (dstImage == null || srcImage == null) return; + + Paint srcPaint = Paint(); + Paint dstPaint = Paint(); + + int index = 4; + + BlendMode srcModel = BlendMode.dstOver; + BlendMode dstModel = BlendMode.srcOver; + + srcPaint + ..blendMode = srcModel; + dstPaint + ..blendMode = dstModel; + + _simpleDrawText(canvas, BlendMode.values[index].toString().split(".")[1], + fontSize: 16, + offset: Offset(50, 50)); + + canvas.translate(size.width / 2, size.height / 2); + + canvas.drawImageRect( + dstImage!, + Rect.fromPoints( + Offset.zero, Offset(dstImage!.width * 1.0, dstImage!.height * 1.0)), + Rect.fromCenter( + center: Offset.zero, width: 400, height: 400), + dstPaint); + + canvas.drawImageRect( + srcImage!, + Rect.fromPoints( + Offset.zero, Offset(srcImage!.width * 1.0, srcImage!.height * 1.0)), + Rect.fromCenter( + center: Offset.zero, width: 400, height: 400), + srcPaint); + + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; + + void _simpleDrawText(Canvas canvas, String str, + {double fontSize = 11,Offset offset = Offset.zero, Color color = Colors.black}) { + var builder = ui.ParagraphBuilder(ui.ParagraphStyle( + textAlign: TextAlign.left, + fontSize: fontSize, + textDirection: TextDirection.ltr, + maxLines: 1, + )) + ..pushStyle( + ui.TextStyle(color: color, textBaseline: ui.TextBaseline.alphabetic), + ) + ..addText(str); + + canvas.drawParagraph( + builder.build() + ..layout(ui.ParagraphConstraints(width: fontSize * str.length)), + offset); + } +} diff --git a/assets/draw/p07/s05.dart b/assets/draw/p07/s05.dart new file mode 100644 index 0000000..e5546a2 --- /dev/null +++ b/assets/draw/p07/s05.dart @@ -0,0 +1,81 @@ +import 'dart:async'; +import 'dart:ui' as ui; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:image/image.dart' as image; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + image.Image? _image; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _image = await loadImageFromAssets('assets/images/wy_300x200.jpg'); + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, child: CustomPaint(painter: PaperPainter(_image))); + } + + //读取 assets 中的图片 + Future loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + List bytes = data.buffer.asUint8List(); + return image.decodeImage(Uint8List.fromList(bytes)); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final image.Image? imageSrc; + final Coordinate coordinate = Coordinate(); + + PaperPainter(this.imageSrc) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + _drawImage(canvas); + } + + @override + bool shouldRepaint(PaperPainter oldDelegate) =>true; + + void _drawImage(Canvas canvas) { + if (imageSrc == null) return; + image.Pixel pixel = imageSrc!.getPixel(imageSrc!.width, 0); + var color = Color.fromARGB(pixel.a.toInt(),pixel.r.toInt(),pixel.g.toInt(),pixel.b.toInt()); + canvas.drawCircle(Offset.zero, 10, _paint..color = color); + } +} diff --git a/assets/draw/p07/s06.dart b/assets/draw/p07/s06.dart new file mode 100644 index 0000000..6c289a5 --- /dev/null +++ b/assets/draw/p07/s06.dart @@ -0,0 +1,110 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:image/image.dart' as image; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + image.Image? _image; + List balls = []; + double d = 20; //复刻的像素边长 + + @override + void initState() { + super.initState(); + _initBalls(); + } + + void _initBalls() async { + _image = await loadImageFromAssets('assets/images/icon_head.png'); + if (_image == null) return; + for (int i = 0; i < _image!.width; i++) { + for (int j = 0; j < _image!.height; j++) { + Ball ball = Ball(); + ball.x = i * d + d / 2; + ball.y = j * d + d / 2; + ball.r = d / 2; + image.Pixel pixel = _image!.getPixel(i, j); + var color = Color.fromARGB(pixel.a.toInt(),pixel.r.toInt(),pixel.g.toInt(),pixel.b.toInt()); + ball.color = color; + balls.add(ball); + } + } + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(balls), + )); + } + + //读取 assets 中的图片 + Future loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + List bytes = data.buffer.asUint8List(); + return image.decodeImage(Uint8List.fromList(bytes)); + } +} + +class PaperPainter extends CustomPainter { + late Paint _paint; + + final double strokeWidth = 0.5; + final Color color = Colors.blue; + + final List balls; + final Coordinate coordinate = Coordinate(); + + PaperPainter(this.balls) { + _paint = Paint() + ..style = PaintingStyle.fill + ..strokeWidth = strokeWidth + ..color = color; + } + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(-710, -1000); + _drawImage(canvas); + } + + void _drawImage(Canvas canvas) { + balls.forEach((Ball ball) { + canvas.drawCircle( + Offset(ball.x, ball.y), ball.r, _paint..color = ball.color); + }); + } + + + @override + bool shouldRepaint(PaperPainter oldDelegate) => true; + +} + +class Ball { + double x; //点位X + double y; //点位Y + Color color; //颜色 + double r; // 半径 + + Ball({this.x=0, this.y=0, this.color=Colors.black, this.r=5}); + +} diff --git a/assets/draw/p08/p08.dart b/assets/draw/p08/p08.dart new file mode 100644 index 0000000..dc0b986 --- /dev/null +++ b/assets/draw/p08/p08.dart @@ -0,0 +1 @@ +export 'p08_page.dart'; \ No newline at end of file diff --git a/assets/draw/p08/p08_page.dart b/assets/draw/p08/p08_page.dart new file mode 100644 index 0000000..e5dea57 --- /dev/null +++ b/assets/draw/p08/p08_page.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; +import 's06.dart' as s6; +import 's07.dart' as s7; +import 's08.dart' as s8; +import 's09.dart' as s9; + + +class P08Page extends StatelessWidget { + const P08Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p08', + + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + s6.Paper(), + s7.Paper(), + s8.Paper(), + s9.Paper(), + ], + ); + } +} diff --git a/assets/draw/p08/s01.dart b/assets/draw/p08/s01.dart new file mode 100644 index 0000000..3e4bfdf --- /dev/null +++ b/assets/draw/p08/s01.dart @@ -0,0 +1,113 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + Coordinate coordinate = Coordinate(); + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-100, 0); + + drawShaderLinear(canvas); + } + + void drawShaderLinear(Canvas canvas) { + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + Paint paint = Paint(); + + paint + ..style = PaintingStyle.stroke + ..color = Colors.blue + ..strokeJoin = StrokeJoin.miter + ..strokeWidth = 50; + + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.clamp); + canvas.drawLine( + Offset(0, 0), + Offset(200, 0), + paint, + ); + + canvas.translate(240, 0); + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.repeated); + canvas.drawLine( + Offset(0, 0), + Offset(200, 0), + paint, + ); + + canvas.translate(-240*2.0, 0); + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.mirror); + canvas.drawLine( + Offset(0, 0), + Offset(200, 0), + paint, + ); + + canvas.translate(0, 100); + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.mirror,Matrix4.rotationZ(pi/6).storage); + canvas.drawLine( + Offset(0, 0), + Offset(200, 0), + paint, + ); + + canvas.translate(240, 0); + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.mirror,Matrix4.translationValues(20, 0, 0).storage); + canvas.drawLine( + Offset(0, 0), + Offset(200, 0), + paint, + ); + + canvas.translate(240, 0); + paint.shader = ui.Gradient.linear( + Offset(0, 0), Offset(100, 0), colors, pos, TileMode.mirror,Matrix4.skewX(-pi/6).storage); + canvas.drawLine( + Offset(0, 0), + Offset(200, 0), + paint, + ); + + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s02.dart b/assets/draw/p08/s02.dart new file mode 100644 index 0000000..26636bb --- /dev/null +++ b/assets/draw/p08/s02.dart @@ -0,0 +1,111 @@ + +import 'package:flutter/material.dart'; + +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + Coordinate coordinate = Coordinate(); + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + drawShaderRadial(canvas); + } + + void drawShaderRadial(Canvas canvas) { + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + Paint paint = Paint(); + paint + ..style = PaintingStyle.fill + ..color = Colors.blue; + + paint.shader = ui.Gradient.radial( + Offset(0, 0), 25, colors, pos, TileMode.clamp); + canvas.drawCircle( + Offset(0, 0), + 50, + paint, + ); + + canvas.translate(160, 0); + paint.shader = ui.Gradient.radial( + Offset(0, 0), 25, colors, pos, TileMode.repeated); + canvas.drawCircle( + Offset(0, 0), + 50, + paint, + ); + + canvas.translate(-160*2.0, 0); + paint.shader = ui.Gradient.radial( + Offset(0, 0), 25, colors, pos, TileMode.mirror); + canvas.drawCircle( + Offset(0, 0), + 50, + paint, + ); + + canvas.translate(0, 120); + paint.shader = ui.Gradient.radial(Offset(0, 0), 25, colors, + pos, TileMode.mirror, null, Offset(10, 10), 1); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + + canvas.translate(160, 0); + paint.shader = ui.Gradient.radial(Offset(0, 0), 25, colors, + pos, TileMode.mirror, null, Offset(-10, -10), 3); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + + + canvas.translate(160, 0); + paint.shader = ui.Gradient.radial(Offset(0, 0), 25, colors, + pos, TileMode.mirror, null, Offset(-10, -10), 0); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s03.dart b/assets/draw/p08/s03.dart new file mode 100644 index 0000000..c1b738d --- /dev/null +++ b/assets/draw/p08/s03.dart @@ -0,0 +1,92 @@ +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + drawShaderSweep(canvas); + } + + void drawShaderSweep(Canvas canvas) { + var colors = [ + Color(0xFFF60C0C), + Color(0xFFF3B913), + Color(0xFFE7F716), + Color(0xFF3DF30B), + Color(0xFF0DF6EF), + Color(0xFF0829FB), + Color(0xFFB709F4), + ]; + + var pos = [1.0 / 7, 2.0 / 7, 3.0 / 7, 4.0 / 7, 5.0 / 7, 6.0 / 7, 1.0]; + Paint paint = Paint(); + paint + ..style = PaintingStyle.fill + ..color = Colors.blue; + + paint.shader = + ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.clamp, pi / 2, pi); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + + canvas.translate(160, 0); + paint.shader = + ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.repeated, pi / 2, pi); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + + canvas.translate(-160*2.0, 0); + paint.shader = + ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.mirror, pi / 2, pi); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + + canvas.translate(-160*2.0, 0); + paint.shader = + ui.Gradient.sweep(Offset.zero, colors, pos, TileMode.mirror, pi / 2, pi); + canvas.drawCircle( + Offset.zero, + 50, + paint, + ); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s04.dart b/assets/draw/p08/s04.dart new file mode 100644 index 0000000..324b677 --- /dev/null +++ b/assets/draw/p08/s04.dart @@ -0,0 +1,98 @@ +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'dart:ui' as ui; + +import 'package:flutter/services.dart'; + +import '../components/coordinate_pro.dart'; + + + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: ImageShaderPainter(_img), + ), + ); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } +} + +class ImageShaderPainter extends CustomPainter { + ui.Image? img; + + ImageShaderPainter(this.img); + Coordinate coordinate = Coordinate(); + @override + void paint(Canvas canvas, Size size) { + if(img == null) return; + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + + Paint paint = Paint()..shader = ImageShader( + img!, + TileMode.repeated, + TileMode.repeated, + Float64List.fromList([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + ])); + + canvas.drawCircle(Offset(100, 100), 50, paint); + + canvas.translate(120, 0); + + canvas.drawCircle( + Offset(100, 100), + 50, + paint + ..strokeWidth = 10 + ..style = PaintingStyle.stroke); + + canvas.translate(-120*2.0, 0); + + canvas.drawLine( + Offset(100 , 50), + Offset(100 , 50 + 100.0), + paint + ..strokeWidth = 30 + ..style = PaintingStyle.stroke); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s05.dart b/assets/draw/p08/s05.dart new file mode 100644 index 0000000..cc4f575 --- /dev/null +++ b/assets/draw/p08/s05.dart @@ -0,0 +1,98 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(_img), + )); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + Coordinate coordinate = Coordinate(); + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if (img == null) return; + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-120 * 2.0 - imgW / 4, -imgH / 4); + drawColorFilter(canvas); + } + + double get imgW => img!.width.toDouble(); + + double get imgH => img!.height.toDouble(); + + void drawColorFilter(Canvas canvas) { + var paint = Paint(); + paint.colorFilter = ColorFilter.linearToSrgbGamma(); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.modulate); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.difference); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.blue, BlendMode.plus); + _drawImage(canvas, paint); + + paint.colorFilter = ColorFilter.mode(Colors.blue, BlendMode.lighten); + _drawImage(canvas, paint); + } + + void _drawImage(Canvas canvas, Paint paint) { + canvas.drawImageRect(img!, Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW / 2, imgH / 2), paint); + canvas.translate(120, 0); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s06.dart b/assets/draw/p08/s06.dart new file mode 100644 index 0000000..570fb86 --- /dev/null +++ b/assets/draw/p08/s06.dart @@ -0,0 +1,139 @@ +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(_img), + )); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + Coordinate coordinate = Coordinate(); + + PaperPainter(this.img); + + @override + void paint(Canvas canvas, Size size) { + if (img == null) return; + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-120*2 - imgW / 4, -imgH / 4); + drawColorFilter(canvas); + } + + double get imgW => img!.width.toDouble(); + + double get imgH => img!.height.toDouble(); + + void drawColorFilter(Canvas canvas) { + var paint = Paint(); + + _drawImage(canvas, paint); + + const ColorFilter carveCarve = ColorFilter.matrix([ + -1, 0, 0, 0, 255, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, + ]); + paint.colorFilter = carveCarve; + // _drawImage(canvas, paint); + + const ColorFilter negative = ColorFilter.matrix([ + -1, 0, 0, 0, 255, + 0, -1, 0, 0, 255, + 0, 0, -1,0, 255, + 0, 0, 0, 1, 0 + ]); + paint.colorFilter = negative; + // _drawImage(canvas, paint); + + const ColorFilter sepia = ColorFilter.matrix([ + 0.393, 0.769, 0.189, 0, 0, + 0.349, 0.686, 0.168, 0, 0, + 0.272, 0.534, 0.131, 0 , 0, + 0, 0, 0, 1, 0, + ]); + _drawImage(canvas, paint..colorFilter=sepia); + + const ColorFilter greyscale = ColorFilter.matrix([ + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0, 0, 0, 1, 0, + ]); + _drawImage(canvas, paint..colorFilter=greyscale); + + const n = 90.0; + const ColorFilter light = ColorFilter.matrix([ + 1,0,0,0,n, + 0,1,0,0,n, + 0,0,1,0,n, + 0,0,0,1,0 + ]); + _drawImage(canvas, paint..colorFilter=light); + + const n2 = -126.0; + const ColorFilter darken = ColorFilter.matrix([ + 1,0,0,0,n2, + 0,1,0,0,n2, + 0,0,1,0,n2, + 0,0,0,1,0 + ]); + _drawImage(canvas, paint..colorFilter=darken); + + } + + void _drawImage(Canvas canvas, Paint paint) { + canvas.drawImageRect(img!, Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW / 2, imgH / 2), paint); + canvas.translate(120, 0); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s07.dart b/assets/draw/p08/s07.dart new file mode 100644 index 0000000..bd577d8 --- /dev/null +++ b/assets/draw/p08/s07.dart @@ -0,0 +1,102 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(_img), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + if (img == null) return; + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-120*2.5 - imgW / 4, -imgH / 4); + drawMaskFilter(canvas); + } + + double get imgW => img!.width.toDouble(); + + double get imgH => img!.height.toDouble(); + + void drawMaskFilter(Canvas canvas) { + var paint = Paint(); + _drawImage(canvas, paint); + + paint.maskFilter = MaskFilter.blur(BlurStyle.inner, 20); + _drawImage(canvas, paint); + + paint.maskFilter = MaskFilter.blur(BlurStyle.outer, 3); + _drawImage(canvas, paint); + + paint.maskFilter = MaskFilter.blur(BlurStyle.solid, 3); + _drawImage(canvas, paint); + + paint.maskFilter = MaskFilter.blur(BlurStyle.normal, 3); + _drawImage(canvas, paint); + + paint.maskFilter = MaskFilter.blur(BlurStyle.normal, 5); + _drawImage(canvas, paint); + } + + void _drawImage(Canvas canvas, Paint paint) { + canvas.drawImageRect(img!, Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW / 2, imgH / 2), paint); + canvas.translate(120, 0); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s08.dart b/assets/draw/p08/s08.dart new file mode 100644 index 0000000..d34e004 --- /dev/null +++ b/assets/draw/p08/s08.dart @@ -0,0 +1,100 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(_img), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + if (img == null) return; + coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-120 * 2.0 - imgW / 4, -imgH / 4); + drawImageFilter(canvas); + } + + double get imgW => img!.width.toDouble(); + + double get imgH => img!.height.toDouble(); + + void drawImageFilter(Canvas canvas) { + var paint = Paint(); + _drawImage(canvas, paint); + + paint.imageFilter = ui.ImageFilter.blur(sigmaX: 0.4, sigmaY: 0.4); + _drawImage(canvas, paint); + + paint.imageFilter = ui.ImageFilter.blur(sigmaX: 0.6, sigmaY: 0.6); + _drawImage(canvas, paint); + + paint.imageFilter = ui.ImageFilter.blur(sigmaX: 0.8, sigmaY: 0.8); + _drawImage(canvas, paint); + + paint.imageFilter = ui.ImageFilter.matrix(Matrix4.skew(pi / 8, 0).storage); + _drawImage(canvas, paint); + } + + void _drawImage(Canvas canvas, Paint paint) { + canvas.drawImageRect(img!, Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW / 2, imgH / 2), paint); + canvas.translate(120, 0); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p08/s09.dart b/assets/draw/p08/s09.dart new file mode 100644 index 0000000..0a41a58 --- /dev/null +++ b/assets/draw/p08/s09.dart @@ -0,0 +1,99 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui' as ui; + +import '../components/coordinate_pro.dart'; + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + const Paper({super.key}); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State { + ui.Image? _img; + + bool get hasImage => _img != null; + + @override + void initState() { + super.initState(); + _loadImage(); + } + + void _loadImage() async { + _img = await loadImageFromAssets('assets/images/wy_200x300.jpg'); + setState(() {}); + } + + //读取 assets 中的图片 + Future? loadImageFromAssets(String path) async { + ByteData data = await rootBundle.load(path); + return decodeImageFromList(data.buffer.asUint8List()); + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( + painter: PaperPainter(_img), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + ui.Image? img; + + PaperPainter(this.img); + + Coordinate coordinate = Coordinate(); + + @override + void paint(Canvas canvas, Size size) { + if (img == null) return; + // coordinate.paint(canvas, size); + canvas.translate(size.width / 2, size.height / 2); + canvas.translate(-120 * 1.5 - imgW / 4, -imgH / 4); + drawFilterQuality(canvas); + } + + double get imgW => img!.width.toDouble(); + + double get imgH => img!.height.toDouble(); + + void drawFilterQuality(Canvas canvas) { + var paint = Paint(); + paint.imageFilter = ui.ImageFilter.blur(sigmaX: 0.6, sigmaY: 0.6); + paint.maskFilter = MaskFilter.blur(BlurStyle.inner, 20); + paint.colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.modulate); + paint.filterQuality = FilterQuality.none; + _drawImage(canvas, paint); + paint.filterQuality = FilterQuality.low; + _drawImage(canvas, paint); + paint.filterQuality = FilterQuality.medium; + _drawImage(canvas, paint); + paint.filterQuality = FilterQuality.high; + _drawImage(canvas, paint); + } + + void _drawImage(Canvas canvas, Paint paint) { + canvas.drawImageRect(img!, Rect.fromLTRB(0, 0, imgW, imgH), + Rect.fromLTRB(0, 0, imgW / 2, imgH / 2), paint); + canvas.translate(120, 0); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/assets/draw/p09/p09.dart b/assets/draw/p09/p09.dart new file mode 100644 index 0000000..4b0886a --- /dev/null +++ b/assets/draw/p09/p09.dart @@ -0,0 +1 @@ +export 'p09_page.dart'; \ No newline at end of file diff --git a/assets/draw/p09/p09_page.dart b/assets/draw/p09/p09_page.dart new file mode 100644 index 0000000..baf9442 --- /dev/null +++ b/assets/draw/p09/p09_page.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; + +class P09Page extends StatelessWidget { + const P09Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p09', + + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + ], + ); + } +} diff --git a/assets/draw/p09/s01.dart b/assets/draw/p09/s01.dart new file mode 100644 index 0000000..9044b51 --- /dev/null +++ b/assets/draw/p09/s01.dart @@ -0,0 +1,60 @@ + +import 'package:flutter/material.dart'; + + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Expanded( + child: CustomPaint( + // painter: BgPainter(), // 背景 + foregroundPainter: BgPainter(Colors.blue.withOpacity(0.9)), // 前景 + child: + Text( + "张风捷特烈", + style: TextStyle(color: Colors.black, fontSize: 20), + ), + ), + ), + Expanded( + child: CustomPaint( + painter: BgPainter(Colors.red), // 背景 + // foregroundPainter: BgPainter(), // 前景 + child: + Text( + "张风捷特烈", + style: TextStyle(color: Colors.white, fontSize: 20), + ), + ), + ), + ], + ); + } +} + +class BgPainter extends CustomPainter { + final Color color; + + BgPainter(this.color); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero&size); + canvas.drawPaint(Paint()..color = color); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return false; + } +} diff --git a/assets/draw/p09/s02.dart b/assets/draw/p09/s02.dart new file mode 100644 index 0000000..11561ee --- /dev/null +++ b/assets/draw/p09/s02.dart @@ -0,0 +1,65 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; + +import '../components/coordinate_pro.dart'; +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Center(child: _buildChild()); + } + + Widget _buildChild() { + final Widget just = CustomPaint( + painter: BgPainter(), // 背景 + ); + + final Widget withSize = CustomPaint( + size: Size(100,100), + painter: BgPainter(), // 背景 + ); + + + final Widget withLayoutBuilder = LayoutBuilder( + builder: _builderByLayout, + ); + + + final Widget withChild = CustomPaint( + painter: BgPainter(), + child: Container( + width: 100, + height: 100, + ), // 背景 + ); + + return withChild; + } + + Widget _builderByLayout(BuildContext context, BoxConstraints constraints) { + return CustomPaint( + size: Size(constraints.maxWidth, constraints.maxHeight), + painter: BgPainter(), // 背景 + ); + } +} + +class BgPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero&size); + + canvas.drawRect( + Rect.fromPoints(Offset.zero, Offset(size.width, size.height)), + Paint()..color = Colors.red); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => false; +} + diff --git a/assets/draw/p09/s03.dart b/assets/draw/p09/s03.dart new file mode 100644 index 0000000..244576d --- /dev/null +++ b/assets/draw/p09/s03.dart @@ -0,0 +1,52 @@ +import 'dart:async'; +import 'dart:math'; +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../components/coordinate_pro.dart'; + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatelessWidget{ + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: Size(100,100), + painter: PicMan(), // 背景 + ); + } + +} + +class PicMan extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + canvas.translate(size.width/2, size.height/2); + _drawArcDetail(canvas); + } + + void _drawArcDetail(Canvas canvas) { + var rect = Rect.fromCenter(center: Offset(0, 0), height: 100, width: 100); + Paint _paint = Paint(); + + + var a = pi / 8; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, _paint..color=Colors.yellowAccent); + canvas.translate(40, 0); + + canvas.translate(40, 0); + canvas.drawCircle(Offset(0, 0), 6, _paint); + canvas.translate(25, 0); + canvas.drawCircle(Offset(0, 0), 6, _paint); + + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => false; +} \ No newline at end of file diff --git a/assets/draw/p10/p10.dart b/assets/draw/p10/p10.dart new file mode 100644 index 0000000..4a07e1a --- /dev/null +++ b/assets/draw/p10/p10.dart @@ -0,0 +1 @@ +export 'p10_page.dart'; \ No newline at end of file diff --git a/assets/draw/p10/p10_page.dart b/assets/draw/p10/p10_page.dart new file mode 100644 index 0000000..7cb60bf --- /dev/null +++ b/assets/draw/p10/p10_page.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; +import 's05.dart' as s5; + +class P10Page extends StatelessWidget { + const P10Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p10', + + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + s5.Paper(), + ], + ); + } +} diff --git a/assets/draw/p10/s01.dart b/assets/draw/p10/s01.dart new file mode 100644 index 0000000..14354fe --- /dev/null +++ b/assets/draw/p10/s01.dart @@ -0,0 +1,71 @@ + +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate_pro.dart'; + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 + +class Paper extends StatefulWidget { + final Color color; + final double angle; + const Paper({Key? key, this.color = Colors.lightBlue, this.angle = 30 }) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State{ + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), + painter: PicManPainter(color: widget.color, angle : widget.angle), // 背景 + ), + ); + } +} + +class PicManPainter extends CustomPainter { + final Color color; // 颜色 + final double angle; // 角度(与x轴交角 角度制) + + Paint _paint = Paint(); + + PicManPainter({this.color = Colors.yellowAccent, this.angle = 30}); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + var a = angle / 180 * pi; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, _paint..color = color); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate) => + oldDelegate.color != color || oldDelegate.angle != angle; +} diff --git a/assets/draw/p10/s02.dart b/assets/draw/p10/s02.dart new file mode 100644 index 0000000..4e386a8 --- /dev/null +++ b/assets/draw/p10/s02.dart @@ -0,0 +1,87 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/11/2 +/// contact me by email 1981462002@qq.com +/// 说明: +/// + +class Paper extends StatefulWidget { + final Color color; + + const Paper({Key? key, this.color = Colors.lightBlue}) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + lowerBound: 10, + upperBound: 40, + duration: const Duration(seconds: 1), + vsync: this, + )..repeat(reverse: true); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), + painter: PicManPainter(color: widget.color, angle: _controller), // 背景 + ), + ); + } +} + +class PicManPainter extends CustomPainter { + + final Animation angle; // 角度(与x轴交角 角度制) + final Color color; // 颜色 + Paint _paint = Paint(); + + PicManPainter({this.color = Colors.yellowAccent, required this.angle}) + : super(repaint: angle); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + var a = angle.value / 180 * pi; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, _paint..color = color); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate) { + print('-----shouldRepaint---------'); + return true; + } +} diff --git a/assets/draw/p10/s03.dart b/assets/draw/p10/s03.dart new file mode 100644 index 0000000..a9df87a --- /dev/null +++ b/assets/draw/p10/s03.dart @@ -0,0 +1,94 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/11/2 +/// contact me by email 1981462002@qq.com +/// 说明: +/// + +class Paper extends StatefulWidget { + final Color color; + + const Paper({Key? key, this.color = Colors.lightBlue}) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _colorCtrl; + late Animation _angleCtrl; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(seconds: 1), + vsync: this, + ); + + _angleCtrl = _controller.drive(Tween(begin: 10, end: 40)); + + _colorCtrl = + ColorTween(begin: Colors.blue, end: Colors.red).animate(_controller); + + _controller.repeat(reverse: true); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), + painter: PicManPainter( + color: _colorCtrl, angle: _angleCtrl, repaint: _controller), + ), + ); + } +} + +class PicManPainter extends CustomPainter { + final Animation repaint; + final Animation angle; + final Animation color; + + Paint _paint = Paint(); + + PicManPainter({ required this.repaint,required this.color,required this.angle}) + : super(repaint: repaint); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + var a = angle.value / 180 * pi; + canvas.drawArc( + rect, a, 2 * pi - a.abs() * 2, true, _paint..color = color.value??Colors.black); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate)=> oldDelegate.repaint != repaint; +} diff --git a/assets/draw/p10/s04.dart b/assets/draw/p10/s04.dart new file mode 100644 index 0000000..b3693e7 --- /dev/null +++ b/assets/draw/p10/s04.dart @@ -0,0 +1,82 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/11/2 +/// contact me by email 1981462002@qq.com +/// 说明: +/// + +class Paper extends StatefulWidget { + final Color color; + + const Paper({Key? key, this.color = Colors.lightBlue}) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(seconds: 1), + vsync: this, + ); + + _controller.repeat(reverse: true); + } + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), + painter: PicManPainter(_controller), // 背景 + ), + ); + } +} + +class PicManPainter extends CustomPainter { + final Animation repaint; // 角度(与x轴交角 角度制) + + final ColorTween colorTween = ColorTween(begin: Colors.blue, end: Colors.red); + final Tween angleTween = Tween(begin: 10.0, end: 40.0); + + Paint _paint = Paint(); + + PicManPainter(this.repaint) + : super(repaint: repaint); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + double a = angleTween.evaluate(repaint) / 180 * pi; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, + _paint..color = colorTween.evaluate(repaint)??Colors.black); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate) => + oldDelegate.repaint != repaint; +} diff --git a/assets/draw/p10/s05.dart b/assets/draw/p10/s05.dart new file mode 100644 index 0000000..fbb99f9 --- /dev/null +++ b/assets/draw/p10/s05.dart @@ -0,0 +1,100 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/11/2 +/// contact me by email 1981462002@qq.com +/// 说明: +/// + +class Paper extends StatefulWidget { + final Color color; + + const Paper({Key? key, this.color = Colors.lightBlue}) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(seconds: 1), + vsync: this, + ); + + _controller.repeat(reverse: true); + } + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), painter: PicManPainter(_controller), // 背景 + ), + ); + } +} + +class PicManPainter extends CustomPainter { + final Animation repaint; + + // 创建 Tween + final ColorDoubleTween tween = ColorDoubleTween( + begin: ColorDouble(color: Colors.blue, value: 10), + end: ColorDouble(color: Colors.red, value: 10)); + + Paint _paint = Paint(); + + PicManPainter(this.repaint) : super(repaint: repaint); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + var a = tween.evaluate(repaint).value / 180 * pi; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, + _paint..color = tween.evaluate(repaint).color ?? Colors.black); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate) => + oldDelegate.repaint != repaint; +} + +class ColorDouble { + final Color? color; + final double value; + + ColorDouble({this.color = Colors.blue, this.value = 0}); +} + +class ColorDoubleTween extends Tween { + ColorDoubleTween({required ColorDouble begin, required ColorDouble end}) + : super(begin: begin, end: end); + + @override + ColorDouble lerp(double t) => ColorDouble( + color: Color.lerp(begin?.color, end?.color, t), + value: (begin!.value + (end!.value - begin!.value) * t), + ); +} diff --git a/assets/draw/p11/p11.dart b/assets/draw/p11/p11.dart new file mode 100644 index 0000000..4f616e1 --- /dev/null +++ b/assets/draw/p11/p11.dart @@ -0,0 +1 @@ +export 'p11_page.dart'; \ No newline at end of file diff --git a/assets/draw/p11/p11_page.dart b/assets/draw/p11/p11_page.dart new file mode 100644 index 0000000..c2ed3dd --- /dev/null +++ b/assets/draw/p11/p11_page.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +import 'package:idraw/components/demo_shower.dart'; +import 's01.dart' as s1; +import 's02.dart' as s2; +import 's03.dart' as s3; +import 's04.dart' as s4; + +class P11Page extends StatelessWidget { + const P11Page({super.key}); + + @override + Widget build(BuildContext context) { + return const DemoShower( + srcCodeDir: 'draw/p11', + demos: [ + s1.Paper(), + s2.Paper(), + s3.Paper(), + s4.Paper(), + ], + ); + } +} diff --git a/assets/draw/p11/s01.dart b/assets/draw/p11/s01.dart new file mode 100644 index 0000000..c81496a --- /dev/null +++ b/assets/draw/p11/s01.dart @@ -0,0 +1,121 @@ + +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate_pro.dart'; + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Center( + child: CurveBox(curve: const Cubic(1, -0.06, 0.1, 1.2),), + ); + } +} + + +class CurveBox extends StatefulWidget { + final Color color; + final Curve curve; + + CurveBox({Key? key, this.color = Colors.lightBlue, this.curve = Curves.linear}) + : super(key: key); + + @override + _CurveBoxState createState() => _CurveBoxState(); +} + +class _CurveBoxState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _angleAnimation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(seconds: 3), + vsync: this, + ); + _angleAnimation = CurveTween(curve: widget.curve).animate(_controller); + _controller.repeat(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: Size(100, 100), + painter: CurveBoxPainter(_controller, _angleAnimation), // 背景 + ); + } +} + +class CurveBoxPainter extends CustomPainter { + final Animation repaint; // + Animation angleAnimation; + + Paint _paint = Paint(); + + CurveBoxPainter(this.repaint, this.angleAnimation) : super(repaint: repaint) {} + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); + canvas.translate(size.width / 2, size.height / 2); + _drawRing(canvas, size); + _drawRedCircle(canvas, size); + _drawGreenCircle(canvas, size); + } + + //绘制环 + void _drawRing(Canvas canvas, Size size) { + final double strokeWidth = 5; + _paint + ..color = Colors.blue + ..style = PaintingStyle.stroke + ..strokeWidth = strokeWidth; + canvas.drawCircle(Offset.zero, size.width / 2 - strokeWidth, _paint); + } + + // 绘制红球 + void _drawRedCircle(Canvas canvas, Size size) { + canvas.save(); + canvas.rotate(angleAnimation.value * 2 * pi); + _paint + ..color = Colors.red + ..style = PaintingStyle.fill; + canvas.drawCircle( + Offset.zero.translate(0, -(size.width / 2 - 5)), 5, _paint); + canvas.restore(); + } + + // 绘制绿球 + void _drawGreenCircle(Canvas canvas, Size size) { + canvas.save(); + canvas.translate(0,angleAnimation.value * (size.height-10)); + _paint + ..color = Colors.green + ..style = PaintingStyle.fill; + canvas.drawCircle( + Offset.zero.translate(0, -(size.width / 2 - 5)), 5, _paint); + canvas.restore(); + } + + @override + bool shouldRepaint(covariant CurveBoxPainter oldDelegate) => + oldDelegate.repaint != repaint; +} diff --git a/assets/draw/p11/s02.dart b/assets/draw/p11/s02.dart new file mode 100644 index 0000000..54113ed --- /dev/null +++ b/assets/draw/p11/s02.dart @@ -0,0 +1,175 @@ + +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import '../components/coordinate_pro.dart'; + + + +/// create by 张风捷特烈 on 2020-03-19 +/// contact me by email 1981462002@qq.com +/// 说明: 纸 +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + final curvesMap = { + "linear": Curves.linear, + "decelerate": Curves.decelerate, + "fastLinearToSlowEaseIn": Curves.fastLinearToSlowEaseIn, + "ease": Curves.ease, + "easeIn": Curves.easeIn, + "easeInToLinear": Curves.easeInToLinear, + "easeInSine": Curves.easeInSine, + "easeInQuad": Curves.easeInCubic, + "easeInCubic": Curves.easeInCubic, + "easeInQuart": Curves.easeInQuart, + "easeInQuint": Curves.easeInQuint, + "easeInExpo": Curves.easeInExpo, + "easeInCirc": Curves.easeInCirc, + "easeInBack": Curves.easeInBack, + "easeOut": Curves.easeOut, + "linearToEaseOut": Curves.linearToEaseOut, + "easeOutSine": Curves.easeOutSine, + "easeOutQuad": Curves.easeOutQuad, + "easeOutCubic": Curves.easeOutCubic, + "easeOutQuart": Curves.easeOutQuart, + "easeOutQuint": Curves.easeOutQuint, + + // "easeOutExpo": Curves.easeOutExpo, + // "easeOutCirc": Curves.easeOutCirc, + // "easeOutBack": Curves.easeOutBack, + // "easeInOut": Curves.easeInOut, + // "easeInOutSine": Curves.easeInOutSine, + // "easeInOutQuad": Curves.easeInOutQuad, + // "easeInOutCubic": Curves.easeInOutCubic, + // "easeInOutQuart": Curves.easeInOutQuart, + // "easeInOutQuint": Curves.easeInOutQuint, + // "easeInOutExpo": Curves.easeInOutExpo, + // "easeInOutCirc": Curves.easeInOutCirc, + // "easeInOutBack": Curves.easeInOutBack, + // "fastOutSlowIn": Curves.fastOutSlowIn, + // "slowMiddle": Curves.slowMiddle, + // "bounceIn": Curves.bounceIn, + // "bounceOut": Curves.bounceOut, + // "bounceInOut": Curves.bounceInOut, + // "elasticIn": Curves.elasticIn, + // "elasticInOut": Curves.elasticInOut, + // "elasticOut": Curves.elasticOut, + }; + return Center( + child: + Wrap( + runSpacing: 20, + children: curvesMap.keys.map((e) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + CurveBox(curve: curvesMap[e]!,), + SizedBox(height: 3,), + Text(e,style: TextStyle(fontSize: 10),) + ], + )).toList(), + ), + ); + } +} + +class CurveBox extends StatefulWidget { + final Color color; + final Curve curve; + + const CurveBox({Key? key, this.color = Colors.lightBlue, this.curve = Curves.linear}) + : super(key: key); + + @override + _CurveBoxState createState() => _CurveBoxState(); +} + +class _CurveBoxState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _angleAnimation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(seconds: 3), + vsync: this, + ); + _angleAnimation = CurveTween(curve: widget.curve).animate(_controller); + _controller.repeat(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: Size(100, 100), + painter: CurveBoxPainter(_controller, _angleAnimation), // 背景 + ); + } +} + +class CurveBoxPainter extends CustomPainter { + final Animation repaint; // + Animation angleAnimation; + + Paint _paint = Paint(); + + CurveBoxPainter(this.repaint, this.angleAnimation) : super(repaint: repaint) {} + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); + canvas.translate(size.width / 2, size.height / 2); + _drawRing(canvas, size); + _drawRedCircle(canvas, size); + _drawGreenCircle(canvas, size); + } + + //绘制环 + void _drawRing(Canvas canvas, Size size) { + final double strokeWidth = 5; + _paint + ..color = Colors.blue + ..style = PaintingStyle.stroke + ..strokeWidth = strokeWidth; + canvas.drawCircle(Offset.zero, size.width / 2 - strokeWidth, _paint); + } + + // 绘制红球 + void _drawRedCircle(Canvas canvas, Size size) { + canvas.save(); + canvas.rotate(angleAnimation.value * 2 * pi); + _paint + ..color = Colors.red + ..style = PaintingStyle.fill; + canvas.drawCircle( + Offset.zero.translate(0, -(size.width / 2 - 5)), 5, _paint); + canvas.restore(); + } + + // 绘制绿球 + void _drawGreenCircle(Canvas canvas, Size size) { + canvas.save(); + canvas.translate(0,angleAnimation.value * (size.height-10)); + _paint + ..color = Colors.green + ..style = PaintingStyle.fill; + canvas.drawCircle( + Offset.zero.translate(0, -(size.width / 2 - 5)), 5, _paint); + canvas.restore(); + } + + @override + bool shouldRepaint(covariant CurveBoxPainter oldDelegate) => + oldDelegate.repaint != repaint; +} diff --git a/assets/draw/p11/s03.dart b/assets/draw/p11/s03.dart new file mode 100644 index 0000000..31c8125 --- /dev/null +++ b/assets/draw/p11/s03.dart @@ -0,0 +1,87 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/11/2 +/// contact me by email 1981462002@qq.com +/// 说明: +/// + +class Paper extends StatefulWidget { + final Color color; + + const Paper({Key? key, this.color = Colors.lightBlue}) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + lowerBound: 10, + upperBound: 40, + duration: const Duration(seconds: 1), + vsync: this, + ); + + // _controller.forward(); + // _controller.reverse(from: 40); + // _controller.repeat(); + // _controller.repeat(reverse: true); + _controller.fling(); + } + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), + painter: PicManPainter(color: widget.color, angle: _controller), // 背景 + ), + ); + } +} + +class PicManPainter extends CustomPainter { + + final Animation angle; // 角度(与x轴交角 角度制) + final Color color; // 颜色 + Paint _paint = Paint(); + + PicManPainter({this.color = Colors.yellowAccent,required this.angle}) + : super(repaint: angle); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + var a = angle.value / 180 * pi; + canvas.drawArc(rect, a, 2 * pi - a.abs() * 2, true, _paint..color = color); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate) { + print('-----shouldRepaint---------'); + return true; + } +} diff --git a/assets/draw/p11/s04.dart b/assets/draw/p11/s04.dart new file mode 100644 index 0000000..96aae54 --- /dev/null +++ b/assets/draw/p11/s04.dart @@ -0,0 +1,111 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/11/2 +/// contact me by email 1981462002@qq.com +/// 说明: +/// + +class Paper extends StatefulWidget { + final Color color; + + const Paper({Key? key, this.color = Colors.lightBlue}) : super(key: key); + + @override + _PaperState createState() => _PaperState(); +} + +class _PaperState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + final ValueNotifier _color = ValueNotifier(Colors.blue); + + @override + void initState() { + super.initState(); + _controller = AnimationController( + lowerBound: 10, + upperBound: 40, + duration: const Duration(seconds: 1), + vsync: this, + ); + _controller.addStatusListener(_statusListen); + _controller.forward(); + // _controller.repeat(reverse: true); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Center( + child: CustomPaint( + size: Size(100, 100), + painter: PicManPainter( + color: _color, + angle: _controller, + repaint: Listenable.merge([_controller, _color])), // 背景 + ), + ); + } + + void _statusListen(AnimationStatus status) { + switch (status) { + case AnimationStatus.dismissed: + _color.value = Colors.black; + break; + case AnimationStatus.forward: + _color.value = Colors.blue; + break; + case AnimationStatus.reverse: + _color.value = Colors.red; + break; + case AnimationStatus.completed: + _color.value = Colors.green; + break; + } + } +} + +class PicManPainter extends CustomPainter { + final Animation angle; + final Listenable repaint; + final ValueNotifier color; + + PicManPainter({required this.color,required this.angle, required this.repaint}) + : super(repaint: repaint); + + Paint _paint = Paint(); + + @override + void paint(Canvas canvas, Size size) { + canvas.clipRect(Offset.zero & size); //剪切画布 + final double radius = size.width / 2; + canvas.translate(radius, size.height / 2); + _drawHead(canvas, size); + _drawEye(canvas, radius); + } + + //绘制头 + void _drawHead(Canvas canvas, Size size) { + var rect = Rect.fromCenter( + center: Offset(0, 0), height: size.width, width: size.height); + var a = angle.value / 180 * pi; + canvas.drawArc( + rect, a, 2 * pi - a.abs() * 2, true, _paint..color = color.value); + } + + //绘制眼睛 + void _drawEye(Canvas canvas, double radius) { + canvas.drawCircle(Offset(radius * 0.15, -radius * 0.6), radius * 0.12, + _paint..color = Colors.white); + } + + @override + bool shouldRepaint(covariant PicManPainter oldDelegate) => + oldDelegate.repaint != repaint; +} diff --git a/lib/components/components.dart b/lib/components/components.dart deleted file mode 100644 index 21dae69..0000000 --- a/lib/components/components.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'toly_ui/toly_ui.dart'; -export 'windows/window_buttons.dart'; -export 'windows/drag_to_move_area.dart'; \ No newline at end of file diff --git a/lib/components/project/colors_panel.dart b/lib/components/project/colors_panel.dart deleted file mode 100644 index d8852cf..0000000 --- a/lib/components/project/colors_panel.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorsPanel extends StatelessWidget { - final List colors; - final ValueChanged onSelect; - const ColorsPanel({super.key, required this.colors, required this.onSelect}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Wrap( - spacing: 8, - runSpacing: 8, - children: colors - .asMap() - .keys - .map((int index) => GestureDetector( - onTap: () => onSelect(colors[index]), - child: Container( - alignment: Alignment.center, - width: 60, - height: 60, - decoration: BoxDecoration( - color: colors[index], - borderRadius: BorderRadius.circular(8)), - child: Text( - '$index', - style: TextStyle(color: Colors.white), - ), - ), - )) - .toList(), - ), - ); - } -} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 76cfee1..6847905 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,8 +5,11 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:window_manager/window_manager.dart'; -import 'navigation/app_navigation.dart'; -import 'v12/app.dart'; +import 'navigation/router/menus/menu_scope/menu_scope.dart'; +import 'navigation/router/routers/app.dart'; +import 'navigation/transition/fade_page_transitions_builder.dart'; +import 'navigation/views/app_navigation.dart'; + void main() { WidgetsFlutterBinding.ensureInitialized(); @@ -16,6 +19,46 @@ void main() { } +class TolyBooksApp extends StatelessWidget { + final GoRouter _router = GoRouter( + initialLocation: '/dashboard/view', + routes: [appRoute], + onException: (BuildContext ctx, GoRouterState state, GoRouter router) { + router.go('/404', extra: state.uri.toString()); + }, + ); + + late final MenuStore menuStore = MenuStore( + activeMenu: '/dashboard/view', + expandMenus: ['/dashboard'], + goRouter: _router, + ); + + @override + Widget build(BuildContext context) { + return MenuScope( + notifier: menuStore, + child: MaterialApp.router( + routerConfig: _router, + debugShowCheckedModeBanner: false, + title: 'Flutter Demo', + theme: ThemeData( + scaffoldBackgroundColor: Colors.white, + fontFamily: "宋体", + primarySwatch: Colors.blue, + pageTransitionsTheme: const PageTransitionsTheme(builders: { + TargetPlatform.android: ZoomPageTransitionsBuilder(), + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + TargetPlatform.macOS: FadePageTransitionsBuilder(), + TargetPlatform.windows: FadePageTransitionsBuilder(), + TargetPlatform.linux: FadePageTransitionsBuilder(), + }), + ), + ), + ); + } +} + void setSize() async{ if(kIsWeb||Platform.isAndroid||Platform.isIOS) return; await windowManager.ensureInitialized(); diff --git a/lib/navigation/app_navigation.dart b/lib/navigation/app_navigation.dart deleted file mode 100644 index a28da76..0000000 --- a/lib/navigation/app_navigation.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; -import 'package:toly_menu/src/menu.dart'; -import 'package:toly_menu/src/model/menu_state.dart'; -import 'package:toly_menu/toly_menu.dart'; - -import '../v12/app/navigation/transition/fade_page_transitions_builder.dart'; -import 'router/menus/menu_tree.dart'; -import 'views/top_logo.dart'; -import 'views/top_bar.dart'; -import 'package:iroute/navigation/router/routers/app.dart'; - -class TolyBooksApp extends StatelessWidget { - final GoRouter _router = GoRouter( - initialLocation: '/dashboard/view', - routes: [appRoute], - onException: (BuildContext ctx, GoRouterState state, GoRouter router) { - router.go('/404', extra: state.uri.toString()); - }, - // redirect: _authRedirect - ); - - @override - Widget build(BuildContext context) { - return MaterialApp.router( - routerConfig: _router, - debugShowCheckedModeBanner: false, - title: 'Flutter Demo', - theme: ThemeData( - fontFamily: "宋体", - primarySwatch: Colors.blue, - pageTransitionsTheme: const PageTransitionsTheme(builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - }), - ), - ); - } -} - -class BookAppNavigation extends StatefulWidget { - final Widget content; - const BookAppNavigation({super.key, required this.content}); - - @override - State createState() => _BookAppNavigationState(); -} - -class _BookAppNavigationState extends State { - MenuState state = MenuState( - expandMenus: ['/dashboard'], - activeMenu: '/dashboard/view', - items: rootMenu.children); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [ - DragToMoveWrap( - child: Container( - color: const Color(0xff001529), - width: 210, - child: Column( - children: [ - TopLogo(), - Expanded(child: TolyMenu(state: state, onSelect: _onSelect)), - ], - ), - ), - ), - Expanded( - child: Column( - children: [AppTopBar(), Expanded(child: widget.content)], - ), - ) - ], - ), - ); - } - - void _onSelect(MenuNode menu) { - if (menu.isLeaf) { - state = state.copyWith(activeMenu: menu.path); - print(menu.path); - // print(; - context.go(menu.path); - } else { - List menus = []; - String path = menu.path.substring(1); - List parts = path.split('/'); - - if (parts.isNotEmpty) { - String path = ''; - for (String part in parts) { - path += '/$part'; - menus.add(path); - } - } - - if (state.expandMenus.contains(menu.path)) { - menus.remove(menu.path); - } - - state = state.copyWith(expandMenus: menus); - } - setState(() {}); - } -} diff --git a/lib/navigation/router/menus/anima.dart b/lib/navigation/router/menus/anima.dart index ed1105b..01e3115 100644 --- a/lib/navigation/router/menus/anima.dart +++ b/lib/navigation/router/menus/anima.dart @@ -1,6 +1,9 @@ +import '../../../app/res/fx_icon.dart'; + Map animaMenus = { 'path' : '/anima', 'label' : '动画-流光幻影', + 'icon': FxIcon.icon_anima, 'children': [ { 'path' : '/chapter1', diff --git a/lib/navigation/router/menus/dashboard.dart b/lib/navigation/router/menus/dashboard.dart new file mode 100644 index 0000000..11fb5c7 --- /dev/null +++ b/lib/navigation/router/menus/dashboard.dart @@ -0,0 +1,32 @@ + +import '../../../app/res/fx_icon.dart'; + +Map dashboard = { + 'path': '/dashboard', + 'label': '面板总览', + 'icon': FxIcon.dashboard, + 'children': [ + { + 'path': '/view', + 'label': '小册全集', + }, + { + 'path': '/chat', + 'label': '读者交流', + 'children': [ + { + 'path': '/a', + 'label': '第一交流区', + }, + { + 'path': '/b', + 'label': '第二交流区', + }, + { + 'path': '/c', + 'label': '第三交流区', + }, + ] + }, + ], +}; \ No newline at end of file diff --git a/lib/navigation/router/menus/draw.dart b/lib/navigation/router/menus/draw.dart index 72b0270..39b1a97 100644 --- a/lib/navigation/router/menus/draw.dart +++ b/lib/navigation/router/menus/draw.dart @@ -1,5 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:iroute/app/res/fx_icon.dart'; + Map drawMenus = { 'path': '/draw', + 'icon': FxIcon.icon_paint, 'label': '绘制-妙笔生花', 'children': [ { diff --git a/lib/navigation/router/menus/dream.dart b/lib/navigation/router/menus/dream.dart index ec4e69b..5140db5 100644 --- a/lib/navigation/router/menus/dream.dart +++ b/lib/navigation/router/menus/dream.dart @@ -1,6 +1,9 @@ +import '../../../app/res/fx_icon.dart'; + Map dreamMenus = { 'path' : '/dream', 'label' : '基础-梦始之地', + 'icon': FxIcon.icon_dream, 'children': [ { 'path' : '/chapter1', diff --git a/lib/navigation/router/menus/layout.dart b/lib/navigation/router/menus/layout.dart index 1806d7f..8d0ed4d 100644 --- a/lib/navigation/router/menus/layout.dart +++ b/lib/navigation/router/menus/layout.dart @@ -1,6 +1,10 @@ +import '../../../app/res/fx_icon.dart'; + Map layoutMenus = { 'path' : '/layout', 'label' : '布局-薪火相传', + 'icon': FxIcon.icon_layout, + 'children': [ { 'path' : '/chapter1', diff --git a/lib/navigation/router/menus/menu_scope/menu_history.dart b/lib/navigation/router/menus/menu_scope/menu_history.dart new file mode 100644 index 0000000..41fbb0d --- /dev/null +++ b/lib/navigation/router/menus/menu_scope/menu_history.dart @@ -0,0 +1,9 @@ +class MenuHistory { + final String menuLabel; + final String menuPath; + + MenuHistory({ + required this.menuLabel, + required this.menuPath, + }); +} diff --git a/lib/navigation/router/menus/menu_scope/menu_scope.dart b/lib/navigation/router/menus/menu_scope/menu_scope.dart new file mode 100644 index 0000000..ab94fcd --- /dev/null +++ b/lib/navigation/router/menus/menu_scope/menu_scope.dart @@ -0,0 +1,200 @@ +import 'package:flutter/cupertino.dart'; +import 'package:go_router/go_router.dart'; +import 'package:toly_menu/toly_menu.dart'; + +import '../menu_tree.dart'; +import 'menu_history.dart'; + +class MenuScope extends InheritedNotifier { + const MenuScope({super.key, required super.child, super.notifier}); + + static MenuStore of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType()!.notifier!; + } + + static MenuStore read(BuildContext context) { + return context.getInheritedWidgetOfExactType()!.notifier!; + } +} + +class MenuStore with ChangeNotifier { + late MenuState _state; + MenuState get state => _state; + final GoRouter goRouter; + final List _history = []; + List get history => _history; + + MenuStore({ + List expandMenus = const [], + required this.goRouter, + required String activeMenu, + }) { + _state = MenuState( + expandMenus: expandMenus, + activeMenu: activeMenu, + items: rootMenu.children, + ); + + _history.add(MenuHistory( + menuLabel: pathName(activeMenu) ?? activeMenu, + menuPath: activeMenu, + )); + goRouter.routerDelegate.addListener(_onRouterChange); + } + + MenuNode? get currentNode => queryMenuNodeByPath( + MenuNode( + path: '', + label: '', + deep: -1, + children: _state.items, + ), + _state.activeMenu); + + String? pathName(String path) => queryMenuNodeByPath( + MenuNode( + path: '', + label: '', + deep: -1, + children: _state.items, + ), + path) + ?.label; + + void selectMenuPath(String path) { + print("======================selectMenuPath:$path======${_shouldAddHistory}=============="); + MenuNode root = MenuNode( + path: '', + label: '', + deep: -1, + children: _state.items, + ); + List result = findNodes(root, Uri.parse(path), 0, '/', []); + if (result.isNotEmpty) { + List expandMenus = []; + if (result.length > 1) { + expandMenus.addAll( + result.sublist(0, result.length - 1).map((e) => e.path).toList()); + } + if(_shouldAddHistory){ + _history.add(MenuHistory( + menuLabel: result.last.label, + menuPath: result.last.path, + )); + }else{ + _shouldAddHistory = true; + } + + _state = state.copyWith( + activeMenu: result.last.path, expandMenus: expandMenus); + } + } + + bool _shouldAddHistory = true; + void selectHistory(String path) { + _shouldAddHistory = false; + goRouter.go(path); + } + + void closeHistory(MenuHistory history) { + int index = _history.indexOf(history); + if(_history.length==1){ + return; + } + if(state.activeMenu!=history.menuPath){ + _history.remove(history); + notifyListeners(); + return; + } + MenuHistory nextActiveHistory; + if(index==_history.length-1){ + /// + nextActiveHistory = _history[_history.length-2]; + }else{ + nextActiveHistory = _history[index+1]; + } + _history.remove(history); + selectHistory(nextActiveHistory.menuPath); + } + + List findNodes( + MenuNode node, + Uri uri, + int deep, + String prefix, + List result, + ) { + List parts = uri.pathSegments; + if (deep > parts.length - 1) { + return result; + } + String target = parts[deep]; + if (node.children.isNotEmpty) { + target = prefix + target; + List nodes = + node.children.where((e) => e.path == target).toList(); + bool match = nodes.isNotEmpty; + if (match) { + MenuNode matched = nodes.first; + result.add(matched); + String nextPrefix = '${matched.path}/'; + findNodes(matched, uri, ++deep, nextPrefix, result); + } + } + return result; + } + + MenuNode? queryMenuNodeByPath(MenuNode node, String path) { + if (node.path == path) { + return node; + } + if (node.children.isNotEmpty) { + for (int i = 0; i < node.children.length; i++) { + MenuNode? result = queryMenuNodeByPath(node.children[i], path); + if (result != null) { + return result; + } + } + } + return null; + } + + void select(MenuNode menu) { + if (menu.isLeaf) { + _state = state.copyWith(activeMenu: menu.path); + goRouter.go(menu.path); + _history.add(MenuHistory( + menuLabel: menu.label, + menuPath: menu.path, + )); + // notifyListeners(); + } else { + List menus = []; + String path = menu.path.substring(1); + List parts = path.split('/'); + + if (parts.isNotEmpty) { + String path = ''; + for (String part in parts) { + path += '/$part'; + menus.add(path); + } + } + if (state.expandMenus.contains(menu.path)) { + menus.remove(menu.path); + } + + _state = state.copyWith(expandMenus: menus); + notifyListeners(); + } + } + + void _onRouterChange() { + String path = + goRouter.routerDelegate.currentConfiguration.last.matchedLocation; + if (path != state.activeMenu) { + selectMenuPath(path); + } + } + +} diff --git a/lib/navigation/router/menus/menu_tree.dart b/lib/navigation/router/menus/menu_tree.dart index 9b6b7d0..8e42469 100644 --- a/lib/navigation/router/menus/menu_tree.dart +++ b/lib/navigation/router/menus/menu_tree.dart @@ -1,6 +1,8 @@ +import 'package:flutter/cupertino.dart'; import 'package:toly_menu/toly_menu.dart'; import 'anima.dart'; +import 'dashboard.dart'; import 'draw.dart'; import 'dream.dart'; import 'layout.dart'; @@ -23,40 +25,13 @@ Map root = { ] }; -Map dashboard = { - 'path': '/dashboard', - 'label': '面板总览', - 'children': [ - { - 'path': '/view', - 'label': '小册全集', - }, - { - 'path': '/chat', - 'label': '读者交流', - 'children': [ - { - 'path': '/a', - 'label': '第一交流区', - }, - { - 'path': '/b', - 'label': '第二交流区', - }, - { - 'path': '/c', - 'label': '第三交流区', - }, - ] - }, - ], -}; MenuNode get rootMenu => parser(root, -1, ''); MenuNode parser(Map data, int deep, String prefix) { String path = data['path']; String label = data['label']; + IconData? icon = data['icon']; List>? childrenMap = data['children']; List children = []; if (childrenMap != null && childrenMap.isNotEmpty) { @@ -66,6 +41,7 @@ MenuNode parser(Map data, int deep, String prefix) { } } return MenuNode( + icon: icon, path: prefix + path, label: label, deep: deep, diff --git a/lib/navigation/router/menus/render.dart b/lib/navigation/router/menus/render.dart index 900ac88..35fa528 100644 --- a/lib/navigation/router/menus/render.dart +++ b/lib/navigation/router/menus/render.dart @@ -1,6 +1,10 @@ +import '../../../app/res/fx_icon.dart'; + Map renderMenus = { 'path' : '/render', 'label' : '渲染-聚沙成塔', + 'icon': FxIcon.icon_sun, + 'children': [ { 'path' : '/chapter1', diff --git a/lib/navigation/router/menus/scroll.dart b/lib/navigation/router/menus/scroll.dart index 6cab03b..06f6fa3 100644 --- a/lib/navigation/router/menus/scroll.dart +++ b/lib/navigation/router/menus/scroll.dart @@ -1,6 +1,10 @@ +import '../../../app/res/fx_icon.dart'; + Map scrollMenus = { 'path' : '/scroll', 'label' : '滑动-珠联璧合', + 'icon': FxIcon.icon_scroll, + 'children': [ { 'path' : '/chapter1', diff --git a/lib/navigation/router/menus/touch.dart b/lib/navigation/router/menus/touch.dart index 2920847..a56c314 100644 --- a/lib/navigation/router/menus/touch.dart +++ b/lib/navigation/router/menus/touch.dart @@ -1,6 +1,9 @@ +import '../../../app/res/fx_icon.dart'; + Map touchMenus = { 'path' : '/touch', 'label' : '手势-执掌天下', + 'icon': FxIcon.fill_shoushi, 'children': [ { 'path' : '/chapter1', diff --git a/lib/navigation/router/routers/anima.dart b/lib/navigation/router/routers/anima.dart new file mode 100644 index 0000000..259d758 --- /dev/null +++ b/lib/navigation/router/routers/anima.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:idraw/idraw.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; + +final RouteBase animaRouters = GoRoute( + path: '/anima/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': + return const P01Page(); + case '2': + return const P01Page(); + case '3': + return const P03Page(); + case '4': + return const P04Page(); + case '5': + return const P05Page(); + case '6': + return const P06Page(); + case '7': + return const P07Page(); + case '8': + return const P08Page(); + case '9': + return const P09Page(); + case '10': + return const P10Page(); + case '11': + return const P11Page(); + } + return const EmptyPanel(msg: '暂未实现'); + }, +); diff --git a/lib/navigation/router/routers/app.dart b/lib/navigation/router/routers/app.dart index 3a56731..25db920 100644 --- a/lib/navigation/router/routers/app.dart +++ b/lib/navigation/router/routers/app.dart @@ -1,37 +1,39 @@ +import 'package:components/components.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:iroute/v12/pages/empty/empty_panel.dart'; +import 'package:iroute/navigation/router/routers/anima.dart'; +import 'package:iroute/navigation/router/routers/dream.dart'; +import 'package:iroute/navigation/router/routers/render.dart'; +import 'package:iroute/navigation/router/routers/scroll.dart'; +import 'package:iroute/navigation/router/routers/touch.dart'; -import '../../../navigation/app_navigation.dart'; +import '../../views/app_navigation.dart'; +import '../../../pages/empty/empty_panel.dart'; import 'dashboard.dart'; import 'draw.dart'; +import 'layout.dart'; final RouteBase appRoute = ShellRoute( builder: (BuildContext context, GoRouterState state, Widget child) { - return BookAppNavigation(content: child); + return TolyBookNavigation(content: child); }, routes: [ dashboardRouters, drawRouters, - // GoRoute( - // path: 'counter', - // builder: (BuildContext context, GoRouterState state) { - // return const CounterPage(); - // }), - // sortRouters, - // GoRoute( - // path: 'user', - // builder: (BuildContext context, GoRouterState state) { - // return const UserPage(); - // }, - // ), - // GoRoute( - // path: 'settings', - // builder: (BuildContext context, GoRouterState state) { - // return const SettingPage(); - // }, - // ), + touchRouters, + dreamRouters, + scrollRouters, + renderRouters, + layoutRouters, + animaRouters, + GoRoute( + path: '/code', + builder: (BuildContext context, GoRouterState state) { + String? path = state.uri.queryParameters['path']; + return CodeView(path: path??'',); + }, + ), GoRoute( path: '/404', builder: (BuildContext context, GoRouterState state) { diff --git a/lib/navigation/router/routers/draw.dart b/lib/navigation/router/routers/draw.dart index 7cac861..2b3c2ef 100644 --- a/lib/navigation/router/routers/draw.dart +++ b/lib/navigation/router/routers/draw.dart @@ -1,82 +1,36 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:idraw/idraw.dart'; -import 'package:iroute/pages/dashboard/chat_room.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; final RouteBase drawRouters = GoRoute( - path: '/draw', - redirect: (_, state) { - if (state.fullPath == '/draw') { - return '/draw/chapter1'; - } - return null; - }, - routes: [ - GoRoute( - path: 'chapter1', - builder: (BuildContext context, GoRouterState state) { + path: '/draw/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': return const P01Page(); - }, - ), - GoRoute( - path: 'chapter2', - builder: (BuildContext context, GoRouterState state) { + case '2': return const P02Page(); - }, - ), - GoRoute( - path: 'chapter3', - builder: (BuildContext context, GoRouterState state) { + case '3': return const P03Page(); - }, - ), - GoRoute( - path: 'chapter4', - builder: (BuildContext context, GoRouterState state) { + case '4': return const P04Page(); - }, - ), - GoRoute( - path: 'chapter5', - builder: (BuildContext context, GoRouterState state) { + case '5': return const P05Page(); - }, - ), - GoRoute( - path: 'chapter6', - builder: (BuildContext context, GoRouterState state) { + case '6': return const P06Page(); - }, - ), - GoRoute( - path: 'chapter7', - builder: (BuildContext context, GoRouterState state) { + case '7': return const P07Page(); - }, - ), - GoRoute( - path: 'chapter8', - builder: (BuildContext context, GoRouterState state) { + case '8': return const P08Page(); - }, - ), - GoRoute( - path: 'chapter9', - builder: (BuildContext context, GoRouterState state) { + case '9': return const P09Page(); - }, - ), - GoRoute( - path: 'chapter10', - builder: (BuildContext context, GoRouterState state) { + case '10': return const P10Page(); - }, - ), - GoRoute( - path: 'chapter11', - builder: (BuildContext context, GoRouterState state) { + case '11': return const P11Page(); - }, - ), - ], + } + return const EmptyPanel(msg: '暂未实现'); + }, ); diff --git a/lib/navigation/router/routers/dream.dart b/lib/navigation/router/routers/dream.dart new file mode 100644 index 0000000..3a8fbab --- /dev/null +++ b/lib/navigation/router/routers/dream.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:idraw/idraw.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; + +final RouteBase dreamRouters = GoRoute( + path: '/dream/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': + return const P01Page(); + case '2': + return const P01Page(); + case '3': + return const P03Page(); + case '4': + return const P04Page(); + case '5': + return const P05Page(); + case '6': + return const P06Page(); + case '7': + return const P07Page(); + case '8': + return const P08Page(); + case '9': + return const P09Page(); + case '10': + return const P10Page(); + case '11': + return const P11Page(); + } + return const EmptyPanel(msg: '暂未实现'); + }, +); diff --git a/lib/navigation/router/routers/layout.dart b/lib/navigation/router/routers/layout.dart new file mode 100644 index 0000000..5b37bb1 --- /dev/null +++ b/lib/navigation/router/routers/layout.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:idraw/idraw.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; + +final RouteBase layoutRouters = GoRoute( + path: '/layout/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': + return const P01Page(); + case '2': + return const P01Page(); + case '3': + return const P03Page(); + case '4': + return const P04Page(); + case '5': + return const P05Page(); + case '6': + return const P06Page(); + case '7': + return const P07Page(); + case '8': + return const P08Page(); + case '9': + return const P09Page(); + case '10': + return const P10Page(); + case '11': + return const P11Page(); + } + return const EmptyPanel(msg: '暂未实现'); + }, +); diff --git a/lib/navigation/router/routers/render.dart b/lib/navigation/router/routers/render.dart new file mode 100644 index 0000000..0123b94 --- /dev/null +++ b/lib/navigation/router/routers/render.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:idraw/idraw.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; + +final RouteBase renderRouters = GoRoute( + path: '/render/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': + return const P01Page(); + case '2': + return const P01Page(); + case '3': + return const P03Page(); + case '4': + return const P04Page(); + case '5': + return const P05Page(); + case '6': + return const P06Page(); + case '7': + return const P07Page(); + case '8': + return const P08Page(); + case '9': + return const P09Page(); + case '10': + return const P10Page(); + case '11': + return const P11Page(); + } + return const EmptyPanel(msg: '暂未实现'); + }, +); diff --git a/lib/navigation/router/routers/scroll.dart b/lib/navigation/router/routers/scroll.dart new file mode 100644 index 0000000..256e39e --- /dev/null +++ b/lib/navigation/router/routers/scroll.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:idraw/idraw.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; + +final RouteBase scrollRouters = GoRoute( + path: '/scroll/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': + return const P01Page(); + case '2': + return const P01Page(); + case '3': + return const P03Page(); + case '4': + return const P04Page(); + case '5': + return const P05Page(); + case '6': + return const P06Page(); + case '7': + return const P07Page(); + case '8': + return const P08Page(); + case '9': + return const P09Page(); + case '10': + return const P10Page(); + case '11': + return const P11Page(); + } + return const EmptyPanel(msg: '暂未实现'); + }, +); diff --git a/lib/navigation/router/routers/touch.dart b/lib/navigation/router/routers/touch.dart new file mode 100644 index 0000000..3d72a8d --- /dev/null +++ b/lib/navigation/router/routers/touch.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:idraw/idraw.dart'; +import 'package:iroute/pages/empty/empty_panel.dart'; + +final RouteBase touchRouters = GoRoute( + path: '/touch/chapter:index', + builder: (BuildContext context, GoRouterState state) { + String? index = state.pathParameters['index']; + switch(index){ + case '1': + return const P01Page(); + case '2': + return const P01Page(); + case '3': + return const P03Page(); + case '4': + return const P04Page(); + case '5': + return const P05Page(); + case '6': + return const P06Page(); + case '7': + return const P07Page(); + case '8': + return const P08Page(); + case '9': + return const P09Page(); + case '10': + return const P10Page(); + case '11': + return const P11Page(); + } + return const EmptyPanel(msg: '暂未实现'); + }, +); diff --git a/lib/v10/app/navigation/transition/fade_page_transitions_builder.dart b/lib/navigation/transition/fade_page_transitions_builder.dart similarity index 100% rename from lib/v10/app/navigation/transition/fade_page_transitions_builder.dart rename to lib/navigation/transition/fade_page_transitions_builder.dart diff --git a/lib/navigation/views/app_navigation.dart b/lib/navigation/views/app_navigation.dart new file mode 100644 index 0000000..c13994d --- /dev/null +++ b/lib/navigation/views/app_navigation.dart @@ -0,0 +1,53 @@ +import 'package:components/components.dart'; +import 'package:flutter/material.dart'; +import 'package:toly_menu/src/menu.dart'; +import 'package:toly_menu/toly_menu.dart'; +import '../router/menus/menu_scope/menu_scope.dart'; +import 'menu_record.dart'; +import 'top_logo.dart'; +import 'top_bar.dart'; + +class TolyBookNavigation extends StatelessWidget { + final Widget content; + const TolyBookNavigation({super.key, required this.content}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Row( + children: [ + DragToMoveWrap( + child: Container( + color: const Color(0xff001529), + width: 210, + child: Column( + children: [ + TopLogo(), + Expanded(child: MenuTreeView()), + ], + ), + ), + ), + Expanded( + child: Column( + children: [ + ColoredBox( + color: const Color(0xffF2F2F2), + child: AppTopBar()), + MenuRecord() , + Expanded(child: content)], + ), + ) + ], + ), + ); + } +} + +class MenuTreeView extends StatelessWidget { + @override + Widget build(BuildContext context) { + MenuStore store = MenuScope.of(context); + return TolyMenu(state: store.state, onSelect: store.select); + } +} diff --git a/lib/navigation/views/menu_record.dart b/lib/navigation/views/menu_record.dart new file mode 100644 index 0000000..d94bdd4 --- /dev/null +++ b/lib/navigation/views/menu_record.dart @@ -0,0 +1,131 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/gestures/events.dart'; +import 'package:iroute/navigation/router/menus/menu_scope/menu_history.dart'; +import 'package:iroute/navigation/router/menus/menu_scope/menu_scope.dart'; + +class MenuRecord extends StatelessWidget { + const MenuRecord({super.key}); + + @override + Widget build(BuildContext context) { + MenuStore store = MenuScope.of(context); + List history = MenuScope.of(context).history; + const BorderSide side = BorderSide(color: Color(0xffE8E8E8), width: 1); + Color themeColor = Theme.of(context).primaryColor; + return Container( + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + color: const Color(0xffF2F2F2), + border: Border(top: side, bottom: side)), + height: 28, + child: ListView( + scrollDirection: Axis.horizontal, + children: history + .map((e) => RecordTab( + canClose: history.length > 1, + onCloseHistory: store.closeHistory, + onTapHistory: store.selectHistory, + active: store.state.activeMenu == e.menuPath, + history: e, + )) + .toList()), + ); + } +} + +class RecordTab extends StatelessWidget { + final bool active; + final bool canClose; + final MenuHistory history; + final ValueChanged onCloseHistory; + final ValueChanged onTapHistory; + const RecordTab({ + super.key, + this.active = false, + required this.canClose, + required this.history, + required this.onCloseHistory, + required this.onTapHistory, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: ()=>onTapHistory(history.menuPath), + child: ColoredBox( + color: active ? Colors.white : Colors.transparent, + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Text( + history.menuLabel, + style: TextStyle( + fontSize: 12, + ), + ), + const SizedBox( + width: 2, + ), + if(canClose) + CloseHoverButton( + onPressed: ()=>onCloseHistory(history) + ) + ], + ), + ), + ), + ), + ); + } +} + +class CloseHoverButton extends StatefulWidget { + final VoidCallback onPressed; + const CloseHoverButton({super.key, required this.onPressed}); + + @override + State createState() => _CloseHoverButtonState(); +} + +class _CloseHoverButtonState extends State { + bool _isHover = false; + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: widget.onPressed, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onExit: _onExit, + onEnter: _onEnter, + child: Container( + padding: EdgeInsets.all(3), + decoration: BoxDecoration( + color: _isHover ? Color(0xffBFC5C8) : Colors.transparent, + borderRadius: BorderRadius.circular(10)), + child: Icon( + CupertinoIcons.clear_thick, + size: 10, + color: _isHover ? Colors.white : Colors.grey, + )), + ), + ); + } + + void _onExit(PointerExitEvent event) { + setState(() { + _isHover = false; + }); + } + + void _onEnter(PointerEnterEvent event) { + setState(() { + _isHover = true; + }); + } +} diff --git a/lib/navigation/views/top_bar.dart b/lib/navigation/views/top_bar.dart index 4bb5919..131a111 100644 --- a/lib/navigation/views/top_bar.dart +++ b/lib/navigation/views/top_bar.dart @@ -1,25 +1,162 @@ +import 'package:components/components.dart'; import 'package:flutter/material.dart'; - -import '../../components/components.dart'; +import 'package:go_router/go_router.dart'; +import 'package:iroute/navigation/router/menus/menu_scope/menu_scope.dart'; class AppTopBar extends StatelessWidget { const AppTopBar({super.key}); @override Widget build(BuildContext context) { - + // String? lable = MenuScope.of(context).currentNode?.label; return DragToMoveWrap( - child: const Row( - children: [ - SizedBox(width: 20,), - // Text( - // '404 界面丢失', - // style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - // ), - Spacer(), - WindowButtons() - ], + child: Stack( + alignment: Alignment.centerRight, + children: [Row( + children: [ + SizedBox(width: 20,), + RouteBackIndicator(), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10.0), + child: RouterIndicator(), + ), + // Text( + // '$lable', + // style: TextStyle(fontSize: 14), + // ), + Spacer(), + ], + ),WindowButtons()] ), ); } } +class RouteBackIndicator extends StatefulWidget { + const RouteBackIndicator({super.key}); + + @override + State createState() => _RouteBackIndicatorState(); +} + +class _RouteBackIndicatorState extends State { + + late GoRouterDelegate _delegate ; + + @override + void initState() { + super.initState(); + _delegate = GoRouter.of(context).routerDelegate; + _delegate.addListener(_onChange); + } + + @override + void dispose() { + _delegate.removeListener(_onChange); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + bool hasPush = _delegate.currentConfiguration.matches + .whereType().isNotEmpty; + if(hasPush){ + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: context.pop, + child: Container( + width: 20, + height: 20, + margin: EdgeInsets.only(right: 8), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Color(0xffE3E5E7), + borderRadius: BorderRadius.circular(6) + ), + child: Icon(Icons.arrow_back_ios_new,size: 14,)), + ), + ); + } + return SizedBox(); + } + + void _onChange() { + setState(() { + + }); + } +} +class RouterIndicator extends StatefulWidget { + const RouterIndicator({super.key}); + + @override + State createState() => _RouterIndicatorState(); +} + +class _RouterIndicatorState extends State { + late GoRouterDelegate _delegate; + @override + void initState() { + super.initState(); + _delegate = GoRouter.of(context).routerDelegate; + _delegate.addListener(_onRouterChange); + } + + @override + void dispose() { + _delegate.removeListener(_onRouterChange); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + List matches = _delegate.currentConfiguration.matches; + if(matches.isEmpty) return const SizedBox(); + RouteMatch match = _delegate.currentConfiguration.matches.last; + + print( + "=========_RouterIndicatorState:build==${match.matchedLocation}========"); + + return TolyBreadcrumb( + fontSize: 12, + items: pathToBreadcrumbItems(context, match.matchedLocation), + onTapItem: (item) { + if (item.to != null) { + GoRouter.of(context).go(item.to!); + } + }, + ); + } + + void _onRouterChange() { + setState(() {}); + } + + List pathToBreadcrumbItems( + BuildContext context, String path) { + Uri uri = Uri.parse(path); + List result = []; + String to = ''; + + String distPath = ''; + for (String segment in uri.pathSegments) { + distPath += '/$segment'; + } + + for (String segment in uri.pathSegments) { + to += '/$segment'; + String? label; + if(to=='/code'){ + label = '代码详情'; + }else{ + label = MenuScope.read(context).pathName(to); + } + + if (label!=null&&label.isNotEmpty) { + result + .add(BreadcrumbItem(to: to, label: label, active: to == distPath)); + } + } + return result; + } +} diff --git a/lib/pages/dashboard/view_book/book_cell.dart b/lib/pages/dashboard/view_book/book_cell.dart index 362f910..b3c1e3f 100644 --- a/lib/pages/dashboard/view_book/book_cell.dart +++ b/lib/pages/dashboard/view_book/book_cell.dart @@ -5,7 +5,8 @@ import '../view_books.dart'; class BookCell extends StatefulWidget { final BookInfo bookInfo; - const BookCell({super.key, required this.bookInfo}); + final ValueChanged onSelect; + const BookCell({super.key, required this.bookInfo, required this.onSelect}); @override State createState() => _BookCellState(); @@ -14,31 +15,34 @@ class BookCell extends StatefulWidget { class _BookCellState extends State { @override Widget build(BuildContext context) { - return MouseRegion( - onEnter: _onEnter, - cursor: SystemMouseCursors.click, - child: Center( - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10, vertical: 6), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Center(child: ClipRRect( - child: Image.asset(widget.bookInfo.cover), - borderRadius:BorderRadius.circular(8) - ))), - const SizedBox(height: 8), + return GestureDetector( + onTap: ()=> widget.onSelect(widget.bookInfo), + child: MouseRegion( + onEnter: _onEnter, + cursor: SystemMouseCursors.click, + child: Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Center(child: ClipRRect( + child: Image.asset(widget.bookInfo.cover), + borderRadius:BorderRadius.circular(8) + ))), + const SizedBox(height: 8), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text( - '${widget.bookInfo.info}', - style: - TextStyle(fontSize: 12, color: Color(0xff515767)), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Text( + '${widget.bookInfo.info}', + style: + TextStyle(fontSize: 12, color: Color(0xff515767)), + ), ), - ), - ], + ], + ), ), ), ), diff --git a/lib/pages/dashboard/view_book/title_group.dart b/lib/pages/dashboard/view_book/title_group.dart index 7dd632c..9b42b91 100644 --- a/lib/pages/dashboard/view_book/title_group.dart +++ b/lib/pages/dashboard/view_book/title_group.dart @@ -1,7 +1,6 @@ +import 'package:components/toly_ui/decoration/title.dart'; import 'package:flutter/material.dart'; -import '../../../components/toly_ui/decoration/title.dart'; - class TitleGroup extends StatelessWidget { final String title; final Color? color; diff --git a/lib/pages/dashboard/view_books.dart b/lib/pages/dashboard/view_books.dart index 318c84c..fc43787 100644 --- a/lib/pages/dashboard/view_books.dart +++ b/lib/pages/dashboard/view_books.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:iroute/navigation/router/menus/menu_scope/menu_scope.dart'; import 'view_book/book_cell.dart'; import 'view_book/title_group.dart'; @@ -121,14 +123,14 @@ class ViewBooks extends StatelessWidget { lineColor: const Color(0xff6EAFF9), ), ), - _buildSliverSliverGrid(kBooks,gridDelegate), + _buildSliverSliverGrid(context,kBooks,gridDelegate), SliverToBoxAdapter( child: TitleGroup( title: 'Flutter 实战探索', lineColor: const Color(0xffFD983A), ), ), - _buildSliverSliverGrid(projectBooks,gridDelegate), + _buildSliverSliverGrid(context,projectBooks,gridDelegate), SliverToBoxAdapter( @@ -137,18 +139,22 @@ class ViewBooks extends StatelessWidget { lineColor: const Color(0xff7864E1), ), ), - _buildSliverSliverGrid(freeBooks,gridDelegate), + _buildSliverSliverGrid(context,freeBooks,gridDelegate), ], ); } - Widget _buildSliverSliverGrid( + Widget _buildSliverSliverGrid(BuildContext context, List books, SliverGridDelegate gridDelegate) { return SliverPadding( padding: const EdgeInsets.symmetric(horizontal: 10), sliver: SliverGrid( delegate: SliverChildBuilderDelegate( - (_, i) => BookCell(bookInfo: books[i]), + (_, i) => BookCell(bookInfo: books[i],onSelect: (b){ + if(b.path == 'draw'){ + context.go('/draw/chapter1'); + } + },), childCount: books.length, ), gridDelegate: gridDelegate), diff --git a/lib/v12/pages/empty/empty_panel.dart b/lib/pages/empty/empty_panel.dart similarity index 89% rename from lib/v12/pages/empty/empty_panel.dart rename to lib/pages/empty/empty_panel.dart index 6aadee2..307e72e 100644 --- a/lib/v12/pages/empty/empty_panel.dart +++ b/lib/pages/empty/empty_panel.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; class EmptyPanel extends StatelessWidget { final String msg; @@ -21,12 +20,11 @@ class EmptyPanel extends StatelessWidget { style: TextStyle(fontSize: 24, color: Colors.grey), ), ElevatedButton(onPressed: (){ - context.go('/'); + context.go('/dashboard/view'); }, child: Text('返回首页')) ], ), ), ); } -} - +} \ No newline at end of file diff --git a/lib/v1/app.dart b/lib/v1/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v1/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v1/app/navigation/app_router_delegate.dart b/lib/v1/app/navigation/app_router_delegate.dart deleted file mode 100644 index 6600a0d..0000000 --- a/lib/v1/app/navigation/app_router_delegate.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:flutter/material.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/user/user_page.dart'; -import '../../transition/fade_transition_page.dart'; -import '../../transition/no_transition_page.dart'; - -const List kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - String _path = '/color'; - - String get path => _path; - - set path(String value) { - if (_path == value) return; - _path = value; - notifyListeners(); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPageByPath(path), - ); - } - - List _buildPageByPath(String path) { - Widget? child; - if (path == kDestinationsPaths[0]) { - child = const ColorPage(); - } - if (path == kDestinationsPaths[1]) { - child = const CounterPage(); - } - if (path == kDestinationsPaths[2]) { - child = const UserPage(); - } - if (path == kDestinationsPaths[3]) { - child = const SettingPage(); - } - return [ - FadeTransitionPage( - key: ValueKey(path), - child: child ?? const EmptyPage(), - ) - ]; - } - - @override - Future popRoute() async { - print('=======popRoute========='); - return true; - } - - bool _onPopPage(Route route, result) { - return route.didPop(result); - } - - @override - Future setNewRoutePath(configuration) async {} -} - -// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { -// -// List _value = ['/']; -// -// -// List get value => _value; -// -// set value(List value){ -// _value = value; -// notifyListeners(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Navigator( -// onPopPage: _onPopPage, -// pages: _value.map((e) => _pageMap[e]!).toList(), -// ); -// } -// -// final Map _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? navigatorKey = GlobalKey(); -// -// @override -// Future setNewRoutePath(String configuration) async{ -// } -// } diff --git a/lib/v1/app/navigation/views/app_navigation_rail.dart b/lib/v1/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 71e22b7..0000000 --- a/lib/v1/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import '../app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List 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(); - } - - int _index = 0 ; - - @override - Widget build(BuildContext context) { - return NavigationRail( - labelType: NavigationRailLabelType.all, - onDestinationSelected: _onDestinationSelected, - destinations: destinations, - selectedIndex: _index, - ); - } - - void _onDestinationSelected(int index) { - router.path = kDestinationsPaths[index]; - } - - void _onRouterChange() { - _index = kDestinationsPaths.indexOf(router.path); - setState(() { - - }); - } -} \ No newline at end of file diff --git a/lib/v1/app/unit_app.dart b/lib/v1/app/unit_app.dart deleted file mode 100644 index 5332b5d..0000000 --- a/lib/v1/app/unit_app.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/app_router_delegate.dart'; -import 'navigation/views/app_navigation_rail.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - )); - } -} - - diff --git a/lib/v1/pages/color/color_page.dart b/lib/v1/pages/color/color_page.dart deleted file mode 100644 index b807f6f..0000000 --- a/lib/v1/pages/color/color_page.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - } - - void _toAddPage() async { - } -} \ No newline at end of file diff --git a/lib/v1/pages/counter/counter_page.dart b/lib/v1/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v1/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v1/pages/empty/empty_page.dart b/lib/v1/pages/empty/empty_page.dart deleted file mode 100644 index e9064a8..0000000 --- a/lib/v1/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('界面走丢了'), - ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v1/pages/settings/settings_page.dart b/lib/v1/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v1/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v1/pages/user/user_page.dart b/lib/v1/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v1/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v1/transition/fade_transition_page.dart b/lib/v1/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v1/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v1/transition/no_transition_page.dart b/lib/v1/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v1/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v10/app.dart b/lib/v10/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v10/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v10/app/navigation/router/app_router_delegate.dart b/lib/v10/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index cdc38e0..0000000 --- a/lib/v10/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,184 +0,0 @@ -import 'dart:async'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'views/navigator_scope.dart'; -import 'iroute.dart'; -import 'iroute_config.dart'; -import 'route_history_manager.dart'; -import 'routes.dart'; -import 'views/not_find_view.dart'; - -AppRouterDelegate router = AppRouterDelegate(node: rootRoute); - -class AppRouterDelegate extends RouterDelegate - with ChangeNotifier { - /// 核心数据,路由配置数据列表 - final List _configs = []; - - String get path => current.uri.path; - - IRouteConfig get current => _configs.last; - - final IRoutePageBuilder? notFindPageBuilder; - - final IRouteNode node; - - @override - IRouteConfig? get currentConfiguration { - if(_configs.isEmpty) return null; - return current; - } - - AppRouterDelegate({ - this.notFindPageBuilder, - required this.node, - }); - - Page _defaultNotFindPageBuilder(_, __) => const MaterialPage( - child: Material(child: NotFindPage()), - ); - - final RouteHistoryManager _historyManager = RouteHistoryManager(); - - RouteHistoryManager get historyManager => _historyManager; - - /// 历史回退操作 - /// 详见: [RouteHistoryManager.back] - void back() => _historyManager.back(changeRoute); - - /// 撤销回退操作 - /// 详见: [RouteHistoryManager.revocation] - void revocation() => _historyManager.revocation(changeRoute); - - void closeHistory(int index) { - _historyManager.close(index); - notifyListeners(); - } - - void clearHistory() { - _historyManager.clear(); - notifyListeners(); - } - - // final List _pathStack = []; - - bool get canPop => _configs.where((e) => e.routeStyle == RouteStyle.push).isNotEmpty; - - final Map> _completerMap = {}; - - FutureOr changeRoute(IRouteConfig config) { - String value = config.uri.path; - if (current == config) null; - _handleChangeStyle(config); - - if (config.forResult) { - _completerMap[value] = Completer(); - } - - if (config.recordHistory) { - _historyManager.recode(config); - } - - notifyListeners(); - - if (config.forResult) { - return _completerMap[value]!.future; - } - } - - void _handleChangeStyle(IRouteConfig config) { - switch (config.routeStyle) { - case RouteStyle.push: - if (_configs.contains(config)) { - _configs.remove(config); - } - _configs.add(config); - break; - case RouteStyle.replace: - List liveRoutes = - _configs.where((e) => e.keepAlive && e != config).toList(); - _configs.clear(); - _configs.addAll([...liveRoutes, config]); - break; - } - } - - FutureOr changePath( - String value, { - bool forResult = false, - Object? extra, - bool keepAlive = false, - bool recordHistory = false, - RouteStyle style = RouteStyle.replace, - }) { - return changeRoute(IRouteConfig( - uri: Uri.parse(value), - forResult: forResult, - extra: extra, - routeStyle: style, - keepAlive: keepAlive, - recordHistory: recordHistory, - )); - } - - @override - Widget build(BuildContext context) { - return NavigatorScope( - node: node, - onPopPage: _onPopPage, - configs: _configs, - notFindPageBuilder: (notFindPageBuilder ?? _defaultNotFindPageBuilder), - ); - } - - @override - Future popRoute() async { - print('=======popRoute========='); - return true; - } - - void backStack() { - if (_configs.isNotEmpty) { - _configs.removeLast(); - if (_configs.isNotEmpty) { - changeRoute(_configs.last); - } else { - changeRoute(current); - } - } - } - - bool _onPopPage(Route route, result) { - if (_completerMap.containsKey(path)) { - _completerMap[path]?.complete(result); - _completerMap.remove(path); - } - - if (canPop) { - _configs.removeLast(); - notifyListeners(); - } else { - changePath(backPath(path), recordHistory: false); - } - return route.didPop(result); - } - - String backPath(String path) { - Uri uri = Uri.parse(path); - if (uri.pathSegments.length == 1) return path; - List parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(IRouteConfig configuration) async{ - changeRoute(configuration); - } - - @override - Future setInitialRoutePath(IRouteConfig configuration) { - _configs.add(configuration); - _historyManager.recode(configuration); - return super.setInitialRoutePath(configuration); - } -} diff --git a/lib/v10/app/navigation/router/app_router_parser.dart b/lib/v10/app/navigation/router/app_router_parser.dart deleted file mode 100644 index a2f11db..0000000 --- a/lib/v10/app/navigation/router/app_router_parser.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -import 'iroute_config.dart'; - -class AppRouterParser extends RouteInformationParser { - @override - RouteInformation restoreRouteInformation(IRouteConfig configuration) { - return RouteInformation(uri: configuration.uri); - } - - @override - Future parseRouteInformationWithDependencies( - RouteInformation routeInformation, - BuildContext context, - ) { - return SynchronousFuture(IRouteConfig(uri: routeInformation.uri)); - } -} diff --git a/lib/v10/app/navigation/router/iroute.dart b/lib/v10/app/navigation/router/iroute.dart deleted file mode 100644 index 8b13ea1..0000000 --- a/lib/v10/app/navigation/router/iroute.dart +++ /dev/null @@ -1,155 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/v9/app/navigation/router/views/navigator_scope.dart'; - -import 'iroute_config.dart'; - -typedef IRoutePageBuilder = Page? Function( - BuildContext context, - IRouteConfig data, -); - - - -typedef IRouteWidgetBuilder = Widget? Function( - BuildContext context, - IRouteConfig data, -); - -abstract class IRouteNode { - final String path; - final List children; - - const IRouteNode({ - required this.path, - required this.children, - }); - - Page? createPage(BuildContext context, IRouteConfig config); - - List find( - String input, - ) { - String prefix = '/'; - if (this is CellIRoute) { - input = input.replaceFirst(path, ''); - if (path != '/') { - prefix = path + "/"; - } - } - - return findNodes(this, Uri.parse(input), 0, prefix, []); - } - - List findNodes( - IRouteNode node, - Uri uri, - int deep, - String prefix, - List result, - ) { - List parts = uri.pathSegments; - if (deep > parts.length - 1) { - return result; - } - String target = parts[deep]; - if (node.children.isNotEmpty) { - target = prefix + target; - - List nodes = node.children.where((e) => e.path == target).toList(); - bool match = nodes.isNotEmpty; - if (match) { - IRouteNode matched = nodes.first; - result.add(matched); - String nextPrefix = '${matched.path}/'; - findNodes(matched, uri, ++deep, nextPrefix, result); - } else { - result.add(NotFindNode(path: target)); - return result; - } - } - return result; - } -} - -/// 优先调用 [pageBuilder] 构建 Page -/// 没有 [pageBuilder] 时, 使用 [widgetBuilder] 构建组件 -/// 没有 [pageBuilder] 和 [widgetBuilder] 时, 使用 [widget] 构建组件 -class IRoute extends IRouteNode { - final IRoutePageBuilder? pageBuilder; - final IRouteWidgetBuilder? widgetBuilder; - final Widget? widget; - - const IRoute({ - required super.path, - super.children = const [], - this.widget, - this.pageBuilder, - this.widgetBuilder, - }); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - if (pageBuilder != null) { - return pageBuilder!(context, config); - } - Widget? child; - if (widgetBuilder != null) { - child = widgetBuilder!(context, config); - } - child ??= widget; - if (child != null) { - return MaterialPage(child: child, key: config.pageKey); - } - return null; - } -} - -/// 未知路由 -class NotFindNode extends IRouteNode { - NotFindNode({required super.path, super.children = const []}); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - return null; - } -} - -typedef CellBuilder = Widget Function( - BuildContext context, - IRouteConfig config, - Widget navigator, -); - -typedef CellIRoutePageBuilder = Page? Function( - BuildContext context, - IRouteConfig data, - Widget child, - ); - -class CellIRoute extends IRouteNode { - final CellBuilder cellBuilder; - final CellIRoutePageBuilder? pageBuilder; - - const CellIRoute({ - required this.cellBuilder, - this.pageBuilder, - required super.path, - required super.children, - }); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - return null; - } - - Page? createCellPage(BuildContext context, IRouteConfig config, - Widget child) { - if (pageBuilder != null) { - return pageBuilder!(context, config, child); - } - return MaterialPage( - child: child, - key: config.pageKey, - ); - } -} \ No newline at end of file diff --git a/lib/v10/app/navigation/router/iroute_config.dart b/lib/v10/app/navigation/router/iroute_config.dart deleted file mode 100644 index f526e71..0000000 --- a/lib/v10/app/navigation/router/iroute_config.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:flutter/material.dart'; - -enum RouteStyle{ - push, - replace, -} - - -class IRouteConfig { - final Object? extra; - final bool forResult; - final Uri uri; - final bool keepAlive; - final RouteStyle routeStyle; - final bool recordHistory; - - const IRouteConfig({ - this.extra, - required this.uri, - this.forResult = false, - this.keepAlive = false, - this.routeStyle = RouteStyle.replace, - this.recordHistory = false, - }); - - String get path => uri.path; - - IRouteConfig copyWith({ - Object? extra, - bool? forResult, - bool? keepAlive, - bool? recordHistory, - String? path, - }) => - IRouteConfig( - extra: extra ?? this.extra, - forResult: forResult ?? this.forResult, - keepAlive: keepAlive ?? this.keepAlive, - recordHistory: recordHistory ?? this.recordHistory, - uri: path!=null?Uri.parse(path):uri, - ); - - ValueKey get pageKey => ValueKey(hashCode); - - - @override - String toString() { - return 'IRouteConfig{extra: $extra, forResult: $forResult, uri: $uri, keepAlive: $keepAlive, routeStyle: $routeStyle, recordHistory: $recordHistory}'; - } - - @override - bool operator ==(Object other) => - identical(this, other) || - other is IRouteConfig && - runtimeType == other.runtimeType && - extra == other.extra && - forResult == other.forResult && - uri == other.uri && - keepAlive == other.keepAlive && - routeStyle == other.routeStyle && - recordHistory == other.recordHistory; - - @override - int get hashCode => - extra.hashCode ^ - forResult.hashCode ^ - uri.hashCode ^ - keepAlive.hashCode ^ - routeStyle.hashCode ^ - recordHistory.hashCode; -} diff --git a/lib/v10/app/navigation/router/route_history_manager.dart b/lib/v10/app/navigation/router/route_history_manager.dart deleted file mode 100644 index 8844898..0000000 --- a/lib/v10/app/navigation/router/route_history_manager.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'iroute_config.dart'; - -typedef OnRouteChange = void Function(IRouteConfig config); - -class RouteHistoryManager{ - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories.reversed.toList(); - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 将 [config] 加入历史记录 - void recode(IRouteConfig config){ - if (_histories.isNotEmpty && config.path == _histories.last.path) return; - _histories.add(config); - } - - /// 历史回退操作 - /// 将当前顶层移除,并加入 [_backHistories] 撤销列表 - /// 并转到前一路径 [_histories.last] - void back(OnRouteChange callback) { - if (!hasHistory) return; - IRouteConfig top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - callback(_histories.last); - } - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation(OnRouteChange callback) { - IRouteConfig target = _backHistories.removeLast(); - callback(target); - } - - void close(int index) { - _histories.removeAt(index); - } - - void clear() { - _histories.clear(); - } -} \ No newline at end of file diff --git a/lib/v10/app/navigation/router/routes.dart b/lib/v10/app/navigation/router/routes.dart deleted file mode 100644 index 356f8b2..0000000 --- a/lib/v10/app/navigation/router/routes.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../../pages/login/login.dart'; -import '../transition/no_transition_page.dart'; -import '../../../pages/sort/views/player/sort_player.dart'; -import 'iroute_config.dart'; -import '../views/app_navigation.dart'; -import 'iroute.dart'; -import '../../../pages/color/color_add_page.dart'; -import '../../../pages/color/color_detail_page.dart'; -import '../../../pages/color/color_page.dart'; -import '../../../pages/counter/counter_page.dart'; -import '../../../pages/user/user_page.dart'; -import '../../../pages/settings/settings_page.dart'; -import '../../../pages/sort/views/sort_page/sort_page.dart'; -import '../../../pages/sort/views/settings/sort_setting.dart'; - -CellIRoute appRoute = CellIRoute( - cellBuilder: (_, __, navigator) => AppNavigation( - navigator: navigator, - ), - path: '/app', - children: [ - IRoute( - path: '/app/color', - widget: ColorPage(), - children: [ - IRoute(path: '/app/color/detail', widgetBuilder: _buildColorDetail), - IRoute(path: '/app/color/add', widget: ColorAddPage()), - ], - ), - const IRoute(path: '/app/counter', widget: CounterPage()), - CellIRoute( - cellBuilder: (_, __, navigator) => SortNavigation(navigator: navigator), - // pageBuilder: (_,config,child)=> NoTransitionPage( - // child: child, - // key: config.pageKey - // ), - path: '/app/sort', - children: [ - const IRoute( - path: '/app/sort/settings', - widget: SortSettings(), - ), - const IRoute( - path: '/app/sort/player', - widget: SortPlayer(), - ), - ], - ), - const IRoute(path: '/app/user', widget: UserPage()), - const IRoute(path: '/app/settings', widget: SettingPage()), - ], -); - -IRoute rootRoute = IRoute(path: '/', children: [ - appRoute, - const IRoute( - path: '/login', - widget: LoginPage() - ) -]); - -Widget? _buildColorDetail(BuildContext context, IRouteConfig data) { - final Map queryParams = data.uri.queryParameters; - String? selectedColor = queryParams['color']; - Color color = Colors.black; - if (selectedColor != null) { - color = Color(int.parse(selectedColor, radix: 16)); - } else if (data.extra is Color) { - color = data.extra as Color; - } - return ColorDetailPage(color: color); -} - -Map kRouteLabelMap = { - '/app': '', - '/app/color': '颜色板', - '/app/color/add': '添加颜色', - '/app/color/detail': '颜色详情', - '/app/counter': '计数器', - '/app/sort': '排序算法', - '/app/sort/player': '演示', - '/app/sort/settings': '排序配置', - '/app/user': '我的', - '/app/settings': '系统设置', -}; - -const List deskNavBarMenus = [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined, path: '/app/color'), - MenuMeta(label: '计数器', icon: Icons.add_chart, path: '/app/counter'), - MenuMeta(label: '排序', icon: Icons.sort, path: '/app/sort/player'), - MenuMeta(label: '我的', icon: Icons.person, path: '/app/user'), - MenuMeta(label: '设置', icon: Icons.settings, path: '/app/settings'), -]; diff --git a/lib/v10/app/navigation/router/views/navigator_scope.dart b/lib/v10/app/navigation/router/views/navigator_scope.dart deleted file mode 100644 index be7b1d8..0000000 --- a/lib/v10/app/navigation/router/views/navigator_scope.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:flutter/material.dart'; -import '../iroute.dart'; - -import '../iroute_config.dart'; - -class NavigatorScope extends StatefulWidget { - final IRouteNode node; - final PopPageCallback onPopPage; - final List configs; - final IRoutePageBuilder notFindPageBuilder; - - const NavigatorScope({ - super.key, - required this.node, - required this.onPopPage, - required this.configs, - required this.notFindPageBuilder, - }); - - @override - State createState() => _NavigatorScopeState(); -} - -class _NavigatorScopeState extends State { - @override - Widget build(BuildContext context) { - Widget content = Navigator( - onPopPage: widget.onPopPage, - pages: _buildPages(context, widget.configs), - ); - - if(widget.node is CellIRoute){ - content = (widget.node as CellIRoute).cellBuilder(context,widget.configs.last,content); - } - return HeroControllerScope( - controller: MaterialApp.createMaterialHeroController(), - child: content, - ); - } - - List _buildPages(BuildContext context, List configs) { - IRouteConfig top = configs.last; - List bottoms = - configs.sublist(0, configs.length - 1).toList(); - List pages = []; - List topPages = _buildPageByPathFromTree(context, top); - pages = _buildLivePageByPathList(context, bottoms, top, topPages); - pages.addAll(topPages); - return pages; - } - - List _buildLivePageByPathList( - BuildContext context, - List paths, - IRouteConfig curConfig, - List curPages, - ) { - List pages = []; - if (paths.isNotEmpty) { - for (IRouteConfig path in paths) { - if (path != curConfig) { - pages.addAll(_buildPageByPathFromTree(context, path)); - } - } - /// 去除和 curPages 中重复的界面 - pages.removeWhere((page) => curPages.map((e) => e.key).contains(page.key)); - } - return pages; - } - - List _buildPageByPathFromTree( - BuildContext context, IRouteConfig config) { - List result = []; - List iRoutes = widget.node.find(config.path); - - if (iRoutes.isNotEmpty) { - for (int i = 0; i < iRoutes.length; i++) { - IRouteNode iroute = iRoutes[i]; - IRouteConfig fixConfig = config; - - if(iroute.path!=config.uri.path){ - fixConfig = IRouteConfig(uri: Uri.parse(iroute.path)); - } - - Page? page; - if (iroute is NotFindNode) { - page = widget.notFindPageBuilder(context, config); - } else if (iroute is CellIRoute) { - Widget scope = NavigatorScope( - node: iroute, - onPopPage: widget.onPopPage, - configs: widget.configs, - notFindPageBuilder: widget.notFindPageBuilder, - ); - page = iroute.createCellPage(context, fixConfig, scope); - } else { - page = iroute.createPage(context, fixConfig); - } - if (page != null) { - result.add(page); - } - if (iroute is CellIRoute) { - break; - } - } - } - return result; - } -} diff --git a/lib/v10/app/navigation/router/views/not_find_view.dart b/lib/v10/app/navigation/router/views/not_find_view.dart deleted file mode 100644 index ccefa16..0000000 --- a/lib/v10/app/navigation/router/views/not_find_view.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotFindPage extends StatelessWidget { - const NotFindPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Material( - child: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - '404 Page Not Find', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ); - } -} diff --git a/lib/v10/app/navigation/router/views/route_back_indicator.dart b/lib/v10/app/navigation/router/views/route_back_indicator.dart deleted file mode 100644 index 5be781a..0000000 --- a/lib/v10/app/navigation/router/views/route_back_indicator.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import '../app_router_delegate.dart'; -class RouteBackIndicator extends StatefulWidget { - const RouteBackIndicator({super.key}); - - @override - State createState() => _RouteBackIndicatorState(); -} - -class _RouteBackIndicatorState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if(router.canPop){ - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: router.backStack, - child: Container( - width: 26, - height: 26, - margin: EdgeInsets.only(right: 8), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Color(0xffE3E5E7), - borderRadius: BorderRadius.circular(6) - ), - child: Icon(Icons.arrow_back_ios_new,size: 14,)), - ), - ); - } - return SizedBox(); - } - - void _onChange() { - setState(() { - - }); - } -} diff --git a/lib/v10/app/navigation/transition/fade_transition_page.dart b/lib/v10/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index fc4e6e6..0000000 --- a/lib/v10/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v10/app/navigation/transition/no_transition_page.dart b/lib/v10/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v10/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v10/app/navigation/views/app_navigation.dart b/lib/v10/app/navigation/views/app_navigation.dart deleted file mode 100644 index 9360abf..0000000 --- a/lib/v10/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatefulWidget { - final Widget navigator; - - const AppNavigation({super.key,required this.navigator}); - - @override - State createState() => _AppNavigationState(); -} - -class _AppNavigationState extends State { - - @override - void initState() { - print('======_AppNavigationState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_AppNavigationState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: widget.navigator, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v10/app/navigation/views/app_navigation_rail.dart b/lib/v10/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 29eec05..0000000 --- a/lib/v10/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; -import '../router/iroute_config.dart'; -import '../router/routes.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text( - 'V0.0.10', - style: TextStyle(color: Colors.white, fontSize: 12), - ), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: activeIndex, - ), - ); - } - - RegExp _segReg = RegExp(r'/app/\w+'); - - int? get activeIndex { - String path = router.path; - RegExpMatch? match = _segReg.firstMatch(path); - if (match == null) return null; - String? target = match.group(0); - int index = deskNavBarMenus.indexWhere((menu) => menu.path!.contains(target??'')); - if (index == -1) return null; - return index; - } - - void _onDestinationSelected(int index) { - String path = deskNavBarMenus[index].path!; - if (index == 1) { - router.changePath(path, keepAlive: true,recordHistory: true); - return; - } - if (index == 4) { - router.changePath(path, style: RouteStyle.push,recordHistory: true); - return; - } else { - router.changePath(path,recordHistory: true); - } - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v10/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v10/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index 40516a7..0000000 --- a/lib/v10/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v10/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v10/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index 150ac6b..0000000 --- a/lib/v10/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/routes.dart'; -import '../../router/views/route_back_indicator.dart'; -import 'app_router_editor.dart'; -import 'history_view_icon.dart'; -import 'route_history_button.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouteBackIndicator(), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - RouteHistoryButton(), - const SizedBox(width: 12,), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.changePath(path), - )), - const SizedBox(width: 12,), - HistoryViewIcon(), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.changePath(item.to!); - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - if(label.isNotEmpty){ - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - } - return result; - } -} diff --git a/lib/v10/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v10/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index e2ad492..0000000 --- a/lib/v10/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/routes.dart'; -import '../../router/iroute_config.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar() { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: router.clearHistory, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final IRouteConfig history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(widget.history.path), - const SizedBox( - height: 2, - ), - Text(kRouteLabelMap[widget.history.path]??'未知路由'), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List histories = router.historyManager.histories; - if(histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - int fixIndex = histories.length - 1 - index; - router.closeHistory(fixIndex); - }, - onPressed: (){ - router.changeRoute(histories[index].copyWith(recordHistory: false)); - Navigator.of(context).pop(); - }, - history: histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v10/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v10/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index 3ee6513..0000000 --- a/lib/v10/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = router.historyManager.hasHistory; - bool hasBackHistory = router.historyManager.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?router.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?router.revocation:null, - ), - ], - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v10/app/unit_app.dart b/lib/v10/app/unit_app.dart deleted file mode 100644 index 7e4acb0..0000000 --- a/lib/v10/app/unit_app.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/router/app_router_parser.dart'; -import 'navigation/router/app_router_delegate.dart'; -import '../pages/sort/provider/state.dart'; -import 'navigation/transition/fade_page_transitions_builder.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - return SortStateScope( - notifier: SortState(), - child: MaterialApp.router( - routerDelegate: router, - routeInformationParser: AppRouterParser(), - routeInformationProvider: PlatformRouteInformationProvider( - initialRouteInformation: RouteInformation(uri: Uri.parse('/app/color')), - ), - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - pageTransitionsTheme: const PageTransitionsTheme(builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - }), - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - // home: AppNavigation() - ), - ); - } -} diff --git a/lib/v10/pages/color/color_add_page.dart b/lib/v10/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v10/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v10/pages/color/color_detail_page.dart b/lib/v10/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v10/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v10/pages/color/color_page.dart b/lib/v10/pages/color/color_page.dart deleted file mode 100644 index 644005e..0000000 --- a/lib/v10/pages/color/color_page.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - void initState() { - print('======_ColorPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_ColorPageState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.changePath('/app/color/detail',extra: color); - - } - - void _toAddPage() async { - Color? color = await router.changePath('/app/color/add',forResult: true,recordHistory: false); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v10/pages/counter/counter_page.dart b/lib/v10/pages/counter/counter_page.dart deleted file mode 100644 index b74a199..0000000 --- a/lib/v10/pages/counter/counter_page.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - @override - void initState() { - print('======_CounterPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_CounterPageState#dispose=============='); - super.dispose(); - } - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v10/pages/empty/empty_page.dart b/lib/v10/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v10/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v10/pages/login/login.dart b/lib/v10/pages/login/login.dart deleted file mode 100644 index af1568a..0000000 --- a/lib/v10/pages/login/login.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class LoginPage extends StatelessWidget { - const LoginPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Login Page',style: TextStyle(fontSize: 24),), - const SizedBox(height: 20,), - ElevatedButton(onPressed: (){ - router.changePath('/app/color'); - }, child: Text('点击进入')) - ], - ), - ), - ); - } -} diff --git a/lib/v10/pages/settings/settings_page.dart b/lib/v10/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v10/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v10/pages/sort/functions.dart b/lib/v10/pages/sort/functions.dart deleted file mode 100644 index 6ae1176..0000000 --- a/lib/v10/pages/sort/functions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'functions/bubble.dart'; -import 'functions/cocktail.dart'; -import 'functions/comb.dart'; -import 'functions/cycle.dart'; -import 'functions/gnome.dart'; -import 'functions/heap.dart'; -import 'functions/insertion.dart'; -import 'functions/merage.dart'; -import 'functions/pigeonHole.dart'; -import 'functions/quick.dart'; -import 'functions/selection.dart'; -import 'functions/shell.dart'; - -typedef SortFunction = Future Function(List src, SortCallback callback); -typedef SortCallback = Future Function(List dist); - -Map sortFunctionMap = { - 'insertion': insertionSort, - 'bubble': bubbleSort, - 'cocktail': cocktailSort, - 'comb': combSort, - 'pigeonHole': pigeonHoleSort, - 'shell': shellSort, - 'selection': selectionSort, - 'gnome': gnomeSort, - 'cycle': cycleSort, - 'heap': heapSort, - 'quick': quickSort, - 'mergeSort': mergeSort, -}; - -Map sortNameMap = { - 'insertion': '插入排序', - 'bubble': '冒泡排序', - 'cocktail': '鸡尾酒排序(双向冒泡排序)', - 'comb': '梳排序', - 'pigeonHole': '鸽巢排序', - 'shell': '希尔排序', - 'selection': '选择排序', - 'gnome': '侏儒排序', - 'cycle': '循环排序', - 'heap': '堆排序', - 'quick': '快速排序', - 'mergeSort': '归并排序', -}; - diff --git a/lib/v10/pages/sort/functions/bubble.dart b/lib/v10/pages/sort/functions/bubble.dart deleted file mode 100644 index 3cf3c99..0000000 --- a/lib/v10/pages/sort/functions/bubble.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///冒泡排序 -Future bubbleSort(List src, SortCallback callback ) async{ - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < src.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < src.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (src[j] > src[j + 1]) { - int temp = src[j]; - src[j] = src[j + 1]; - src[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/cocktail.dart b/lib/v10/pages/sort/functions/cocktail.dart deleted file mode 100644 index 8c2d18c..0000000 --- a/lib/v10/pages/sort/functions/cocktail.dart +++ /dev/null @@ -1,52 +0,0 @@ -import '../functions.dart'; - -///鸡尾酒排序(双向冒泡排序) -Future cocktailSort(List src, SortCallback callback ) async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = src.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/comb.dart b/lib/v10/pages/sort/functions/comb.dart deleted file mode 100644 index 821f4a9..0000000 --- a/lib/v10/pages/sort/functions/comb.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '../functions.dart'; - -///梳排序(Comb Sort) -Future combSort(List src, SortCallback callback) async{ - int gap = src.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < src.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (src[i] > src[i + gap]) { - int temp = src[i]; - src[i] = src[i + gap]; - src[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await callback(src); - } - } -} - -int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/cycle.dart b/lib/v10/pages/sort/functions/cycle.dart deleted file mode 100644 index 4bef6eb..0000000 --- a/lib/v10/pages/sort/functions/cycle.dart +++ /dev/null @@ -1,54 +0,0 @@ -import '../functions.dart'; - -///循环排序 -Future cycleSort(List src, SortCallback callback) async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) { - int item = src[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (item != src[pos]) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/gnome.dart b/lib/v10/pages/sort/functions/gnome.dart deleted file mode 100644 index 5e08fc3..0000000 --- a/lib/v10/pages/sort/functions/gnome.dart +++ /dev/null @@ -1,22 +0,0 @@ -import '../functions.dart'; - -///地精排序 (侏儒排序) -Future gnomeSort(List src, SortCallback callback) async { - int index = 0; - while (index < src.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (src[index] >= src[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = src[index]; - src[index] = src[index - 1]; - src[index - 1] = temp; - index--; - } - await callback(src); - } - return; -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/heap.dart b/lib/v10/pages/sort/functions/heap.dart deleted file mode 100644 index 9f5410b..0000000 --- a/lib/v10/pages/sort/functions/heap.dart +++ /dev/null @@ -1,38 +0,0 @@ -import '../functions.dart'; - -///堆排序 -Future heapSort(List src, SortCallback callback) async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = src.length ~/ 2; i >= 0; i--) { - await heapify(src,callback, src.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = src.length - 1; i >= 0; i--) { - int temp = src[0]; - src[0] = src[i]; - src[i] = temp; - await heapify(src, callback,i, 0); - } -} - -Future heapify(List src, SortCallback callback, int n, int i) async{ - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && src[l] > src[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && src[r] > src[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = src[i]; - src[i] = src[largest]; - src[largest] = temp; - heapify(src,callback, n, largest); - } - await callback(src); -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/insertion.dart b/lib/v10/pages/sort/functions/insertion.dart deleted file mode 100644 index b1c7814..0000000 --- a/lib/v10/pages/sort/functions/insertion.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///插入排序 -Future insertionSort(List src, SortCallback callback) async { - for (int i = 1; i < src.length; i++) { - int temp = src[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < src[j]) { - src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - // 更新排序结果回调 - await callback(src); - } - src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await callback(src); - } -} diff --git a/lib/v10/pages/sort/functions/merage.dart b/lib/v10/pages/sort/functions/merage.dart deleted file mode 100644 index 12135b4..0000000 --- a/lib/v10/pages/sort/functions/merage.dart +++ /dev/null @@ -1,79 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future mergeSort(List src, SortCallback callback) async { - await _mergeSort(src,callback,0,src.length-1); -} - -///归并排序 -Future _mergeSort(List src, SortCallback callback,int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = src[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = src[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - src[k] = leftList[i]; - i++; - } else { - src[k] = rightList[j]; - j++; - } - - await callback(src); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - src[k] = leftList[i]; - i++; - k++; - - await callback(src); - } - - while (j < rightSize) { - src[k] = rightList[j]; - j++; - k++; - - await callback(src); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await _mergeSort(src,callback,leftIndex, middleIndex); - await _mergeSort(src,callback,middleIndex + 1, rightIndex); - - await callback(src); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/oddEven.dart b/lib/v10/pages/sort/functions/oddEven.dart deleted file mode 100644 index bd6f548..0000000 --- a/lib/v10/pages/sort/functions/oddEven.dart +++ /dev/null @@ -1,37 +0,0 @@ -import '../functions.dart'; - -///奇偶排序(Odd-Even Sort) -Future oddEvenSort(List src, SortCallback callback) async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= src.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await callback(src); - } - } - - for (int i = 0; i <= src.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; - await callback(src); - } - } - } - - return; -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/pigeonHole.dart b/lib/v10/pages/sort/functions/pigeonHole.dart deleted file mode 100644 index 83bbce1..0000000 --- a/lib/v10/pages/sort/functions/pigeonHole.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../functions.dart'; - -///鸽巢排序 -Future pigeonHoleSort(List src, SortCallback callback ) async{ - int min = src[0]; - int max = src[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < src.length; a++) { - if (src[a] > max) max = src[a]; - if (src[a] < min) min = src[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < src.length; i++) { - p[src[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - src[index++] = j + min; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/quick.dart b/lib/v10/pages/sort/functions/quick.dart deleted file mode 100644 index 25b9685..0000000 --- a/lib/v10/pages/sort/functions/quick.dart +++ /dev/null @@ -1,65 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future quickSort(List src, SortCallback callback) async { - await _quickSort(src,callback,0,src.length-1); -} - -///快速排序 -Future _quickSort(List src, SortCallback callback,int leftIndex,int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = src[p]; - src[p] = src[right]; - src[right] = temp; - await callback(src); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(src[i], src[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = src[i]; - src[i] = src[cursor]; - src[cursor] = temp; - cursor++; - await callback(src); - } - } - - // 将基准元素放置在游标位置 - temp = src[right]; - src[right] = src[cursor]; - src[cursor] = temp; - - await callback(src); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } -} - -// 比较函数,用于判断两个元素的大小关系 -cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/selection.dart b/lib/v10/pages/sort/functions/selection.dart deleted file mode 100644 index 185dae2..0000000 --- a/lib/v10/pages/sort/functions/selection.dart +++ /dev/null @@ -1,18 +0,0 @@ -import '../functions.dart'; - -///选择排序 -Future selectionSort(List src, SortCallback callback ) async { - for (int i = 0; i < src.length; i++) { - for (int j = i + 1; j < src.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (src[i] > src[j]) { - // 判断当前元素是否比后续元素小 - int temp = src[j]; - // 交换当前元素和后续较小的元素 - src[j] = src[i]; - src[i] = temp; - } - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/functions/shell.dart b/lib/v10/pages/sort/functions/shell.dart deleted file mode 100644 index 232f872..0000000 --- a/lib/v10/pages/sort/functions/shell.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../functions.dart'; - -///希尔排序 -Future shellSort(List src, SortCallback callback) async{ - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < src.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = src[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && src[j - gap] > temp; j -= gap) { - src[j] = src[j - gap]; - } - src[j] = temp; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v10/pages/sort/provider/sort_config.dart b/lib/v10/pages/sort/provider/sort_config.dart deleted file mode 100644 index 1fc3790..0000000 --- a/lib/v10/pages/sort/provider/sort_config.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -class SortConfig { - final int count; - 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, - }) => - SortConfig( - count:count??this.count, - seed:seed??this.seed, - duration:duration??this.duration, - name:name??this.name, - colorIndex:colorIndex??this.colorIndex, - ); -} - diff --git a/lib/v10/pages/sort/provider/state.dart b/lib/v10/pages/sort/provider/state.dart deleted file mode 100644 index 1e79b05..0000000 --- a/lib/v10/pages/sort/provider/state.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -import '../functions.dart'; -import 'sort_config.dart'; - -enum SortStatus{ - none, // 未操作 - sorting, // 排序中 - sorted, // 排序完成 -} - -List 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(){ - reset(); - } - - SortStatus status = SortStatus.none; - - List data = []; - List stepData = []; - - SortConfig _config = SortConfig(); - SortConfig get config => _config; - Random random = Random(); - - set config(SortConfig config){ - _config = config; - reset(); - notifyListeners(); - } - - void selectName(String name){ - if(name==config.name) return; - 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; - notifyListeners(); - int count = config.count; - if(config.seed!=-1){ - random = Random(config.seed); - } - for (int i = 0; i < count; i++) { - //随机往数组中填值 - data.add(random.nextInt(1000)); - } - } - - void sort() async{ - status = SortStatus.sorting; - notifyListeners(); - Stopwatch stopwatch = Stopwatch()..start(); - SortFunction? sortFunction = sortFunctionMap[config.name]; - if(sortFunction!=null){ - await sortFunction(data,(arr) async { - await Future.delayed(config.duration); - notifyListeners(); - }); - } - status = SortStatus.sorted; - notifyListeners(); - stopwatch.stop(); - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - } -} - -/// Provides the current [SortState] to descendant widgets in the tree. -class SortStateScope extends InheritedNotifier { - const SortStateScope({ - required super.notifier, - required super.child, - super.key, - }); - - static SortState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; -} \ No newline at end of file diff --git a/lib/v10/pages/sort/views/code_page/code_page.dart b/lib/v10/pages/sort/views/code_page/code_page.dart deleted file mode 100644 index 7d8d4c9..0000000 --- a/lib/v10/pages/sort/views/code_page/code_page.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class CodePage extends StatelessWidget { - const CodePage({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - leading: BackButton(), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - centerTitle: true, - title: Text(sortNameMap[state.config.name]!+'代码实现'), - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text('代码'*1000), - )); - } -} diff --git a/lib/v10/pages/sort/views/player/data_painter.dart b/lib/v10/pages/sort/views/player/data_painter.dart deleted file mode 100644 index 392a9e8..0000000 --- a/lib/v10/pages/sort/views/player/data_painter.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; - - - -class DataPainter extends CustomPainter{ - - final List data; - final MaterialColor color; - - DataPainter( {required this.data,required this.color,}); - - @override - void paint(Canvas canvas, Size size) { - double itemWidth = size.width/data.length; - double height = size.height; - - Paint paint = Paint(); - paint.strokeWidth = itemWidth; - paint.strokeCap = StrokeCap.round; - - - for(int i=0;i 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()), - ), - ); - } -} diff --git a/lib/v10/pages/sort/views/settings/color_picker.dart b/lib/v10/pages/sort/views/settings/color_picker.dart deleted file mode 100644 index b0bb469..0000000 --- a/lib/v10/pages/sort/views/settings/color_picker.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorPicker extends StatelessWidget { - final List colors; - final ValueChanged 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(), - ); - } -} diff --git a/lib/v10/pages/sort/views/settings/sort_setting.dart b/lib/v10/pages/sort/views/settings/sort_setting.dart deleted file mode 100644 index 84f5f52..0000000 --- a/lib/v10/pages/sort/views/settings/sort_setting.dart +++ /dev/null @@ -1,170 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../provider/state.dart'; -import 'color_picker.dart'; -class SortSettings extends StatefulWidget { - - const SortSettings({super.key,}); - - @override - State createState() => _SortSettingsState(); -} - -class _SortSettingsState extends State { - 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, - automaticallyImplyLeading: false, - // 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('确定设置')) - ], - ), - ), - ); - } -} diff --git a/lib/v10/pages/sort/views/sort_page/sort_button.dart b/lib/v10/pages/sort/views/sort_page/sort_button.dart deleted file mode 100644 index 93df9d9..0000000 --- a/lib/v10/pages/sort/views/sort_page/sort_button.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../provider/state.dart'; - -class SortButton extends StatelessWidget { - const SortButton({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - VoidCallback? action; - IconData icon; - String text = ''; - Color color; - switch (state.status) { - case SortStatus.none: - icon = Icons.not_started_outlined; - color = Colors.green; - action = state.sort; - text = '点击启动'; - break; - case SortStatus.sorting: - icon = Icons.stop_circle_outlined; - color = Colors.grey; - action = null; - text = '排序中...'; - break; - case SortStatus.sorted: - icon = CupertinoIcons.repeat; - color = Colors.black; - action = state.reset; - text = '点击重置'; - break; - } - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: action, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon( - icon, - color: color, - size: 18, - ), - const SizedBox(width: 4,), - Text(text,style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold,color: color),), - ], - ), - ), - ); - } -} diff --git a/lib/v10/pages/sort/views/sort_page/sort_page.dart b/lib/v10/pages/sort/views/sort_page/sort_page.dart deleted file mode 100644 index f865e77..0000000 --- a/lib/v10/pages/sort/views/sort_page/sort_page.dart +++ /dev/null @@ -1,166 +0,0 @@ - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import '../../../../app/navigation/router/iroute_config.dart'; -import '../../../../app/navigation/router/app_router_delegate.dart'; -import 'sort_button.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class SortNavigation extends StatelessWidget { - final Widget navigator; - const SortNavigation({super.key, required this.navigator}); - - @override - Widget build(BuildContext context) { - return Material( - child: Row( - children: [ - SizedBox( - width: 220, - child: SortRailPanel(), - ), - VerticalDivider( - width: 1, - ), - Expanded( - child: navigator, - ) - ], - ), - ); - } -} - -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('/app/sort/settings',style: RouteStyle.push); - }, - 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('/app/sort/player'); - }, - ), - ), - ], - ); - } -} - -class SortSelectorPanel extends StatelessWidget { - final String active; - final ValueChanged onSelected; - final List 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 createState() => _SortItemTileState(); -} - -class _SortItemTileState extends State { - @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), - ), - ), - ), - ), - ); - } -} diff --git a/lib/v10/pages/user/user_page.dart b/lib/v10/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v10/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v11/app.dart b/lib/v11/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v11/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v11/app/navigation/helper/function.dart b/lib/v11/app/navigation/helper/function.dart deleted file mode 100644 index 526be07..0000000 --- a/lib/v11/app/navigation/helper/function.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -Map kRouteLabelMap = { - '': '', - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/sort': '排序算法', - '/sort/player': '', - '/sort/settings': '排序配置', - '/user': '我的', - '/settings': '系统设置', -}; - - -String calcRouteName(BuildContext context,String path){ - String? result = kRouteLabelMap[path]; - if(result !=null) return result; - if(path.startsWith('/sort/player/')){ - return path.split('/sort/player/')[1]; - } - - return '未知路由'; -} \ No newline at end of file diff --git a/lib/v11/app/navigation/helper/router_history.dart b/lib/v11/app/navigation/helper/router_history.dart deleted file mode 100644 index 19deda0..0000000 --- a/lib/v11/app/navigation/helper/router_history.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -class RouterHistoryScope extends InheritedNotifier { - const RouterHistoryScope({super.key, required super.child, super.notifier}); - - static RouterHistory of(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType()! - .notifier!; - } - - static RouterHistory read(BuildContext context) { - return context - .getInheritedWidgetOfExactType()! - .notifier!; - } -} - -class RouterHistory with ChangeNotifier { - final List exclusives; - - final GoRouterDelegate delegate; - - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories; - - RouterHistory(this.delegate, {this.exclusives = const []}) { - delegate.addListener(_onRouteChange); - } - - /// 用于记录当前历史记录 - /// 清空历史之后,切换时,先记录 _current - RouteMatchList? _current; - - void _onRouteChange() { - /// 当没有历史,且 _current 非空 - if (_histories.isEmpty && _current != null) { - _histories.add(_current!); - } - - RouteMatchList matchList = delegate.currentConfiguration; - if (_histories.isNotEmpty && matchList == _histories.last - || matchList.isEmpty - ) return; - - - - String uri = matchList.last.matchedLocation; - if (exclusives.contains(uri)) { - return; - } - _recode(matchList); - } - - /// 将 [history] 加入历史记录 - void _recode(RouteMatchList history) { - _current = history; - _histories.add(history); - if (hasHistory) { - notifyListeners(); - } - } - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 历史回退操作 - /// 将当前顶层移除,并加入 [_backHistories] 撤销列表 - /// 并转到前一路径 [_histories.last] - void back() { - if (!hasHistory) { - return; - } - RouteMatchList top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - delegate.setNewRoutePath(_histories.last); - notifyListeners(); - } - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation() { - RouteMatchList target = _backHistories.removeLast(); - delegate.setNewRoutePath(target); - notifyListeners(); - } - - void close(RouteMatchList history) { - _histories.remove(history); - notifyListeners(); - } - - void clear() { - _histories.clear(); - notifyListeners(); - } - - void select(RouteMatchList history) { - _histories.remove(history); - delegate.setNewRoutePath(history); - } -} diff --git a/lib/v11/app/navigation/router/app.dart b/lib/v11/app/navigation/router/app.dart deleted file mode 100644 index c9719e7..0000000 --- a/lib/v11/app/navigation/router/app.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/counter/counter_page.dart'; -import '../../../pages/user/user_page.dart'; -import '../../../pages/settings/settings_page.dart'; -import '../../../pages/empty/empty_panel.dart'; -import '../views/app_navigation.dart'; -import 'color.dart'; -import 'sort.dart'; - - -final RouteBase appRoute = ShellRoute( - builder: (BuildContext context, GoRouterState state, Widget child) { - return AppNavigation(navigator: child); - }, - routes: [ - colorRouters, - GoRoute( - path: 'counter', - builder: (BuildContext context, GoRouterState state) { - return const CounterPage(); - }), - sortRouters, - GoRoute( - path: 'user', - builder: (BuildContext context, GoRouterState state) { - return const UserPage(); - }, - ), - GoRoute( - path: 'settings', - builder: (BuildContext context, GoRouterState state) { - return const SettingPage(); - }, - ), - GoRoute( - path: '404', - builder: (BuildContext context, GoRouterState state) { - String msg = '无法访问: ${state.extra}'; - return EmptyPanel(msg: msg); - }, - ) - ], -); diff --git a/lib/v11/app/navigation/router/color.dart b/lib/v11/app/navigation/router/color.dart deleted file mode 100644 index 6a2052a..0000000 --- a/lib/v11/app/navigation/router/color.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/color/color_add_page.dart'; -import '../../../pages/color/color_detail_page.dart'; -import '../../../pages/color/color_page.dart'; - - - -final RouteBase colorRouters = GoRoute( - path: 'color', - builder: (BuildContext context, GoRouterState state) { - return const ColorPage(); - }, - routes: [ - GoRoute( - path: 'detail', - name: 'colorDetail', - builder: (BuildContext context, GoRouterState state) { - String? selectedColor = state.uri.queryParameters['color']; - Color color = Colors.black; - if (selectedColor != null) { - color = Color(int.parse(selectedColor, radix: 16)); - } - return ColorDetailPage(color: color); - }, - ), - GoRoute( - path: 'add', - builder: (BuildContext context, GoRouterState state) { - return const ColorAddPage(); - }, - ), - ], -); - diff --git a/lib/v11/app/navigation/router/root.dart b/lib/v11/app/navigation/router/root.dart deleted file mode 100644 index 9eea0a3..0000000 --- a/lib/v11/app/navigation/router/root.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/login/login.dart'; -import 'app.dart'; - -final RouteBase rootRoute = GoRoute( - path: '/', - redirect: _redirect, - routes: [ - appRoute, - GoRoute( - path: 'login', - builder: (BuildContext context, GoRouterState state) { - return const LoginPage(); - }, - ), - ], -); - -FutureOr _redirect(BuildContext context, GoRouterState state) { - if(state.fullPath=='/'){ - return '/color'; - } - return null; -} diff --git a/lib/v11/app/navigation/router/sort.dart b/lib/v11/app/navigation/router/sort.dart deleted file mode 100644 index e6d6a84..0000000 --- a/lib/v11/app/navigation/router/sort.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/sort/provider/state.dart'; - -import '../../../pages/sort/views/player/sort_player.dart'; -import '../../../pages/sort/views/settings/sort_setting.dart'; -import '../../../pages/sort/views/sort_page/sort_page.dart'; - -final RouteBase sortRouters = ShellRoute( - builder: (BuildContext context, GoRouterState state, Widget child) { - return SortNavigation(navigator: child); - }, - routes: [ - GoRoute( - path: 'sort', - redirect: _redirectSort, - routes: [ - GoRoute( - path: 'player/:name', - builder: (BuildContext context, GoRouterState state) { - print(state.pathParameters);// 获取路径参数 - return const SortPlayer(); - }, - ), - GoRoute( - path: 'settings', - builder: (BuildContext context, GoRouterState state) { - return const SortSettings(); - }, - ), - ], - ), - ], -); - -FutureOr _redirectSort(BuildContext context, GoRouterState state) { - if (state.fullPath == '/sort') { - String name = SortStateScope.read(context).config.name; - return '/sort/player/$name'; - } - return null; -} diff --git a/lib/v11/app/navigation/transition/fade_page_transitions_builder.dart b/lib/v11/app/navigation/transition/fade_page_transitions_builder.dart deleted file mode 100644 index 0587ecc..0000000 --- a/lib/v11/app/navigation/transition/fade_page_transitions_builder.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class FadePageTransitionsBuilder extends PageTransitionsBuilder { - - const FadePageTransitionsBuilder(); - - @override - Widget buildTransitions( - PageRoute? route, - BuildContext? context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return _FadePagePageTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - child: child, - ); - } -} - -class _FadePagePageTransition extends StatelessWidget { - - const _FadePagePageTransition({ - required this.animation, - required this.secondaryAnimation, - required this.child, - }); - - final Animation animation; - final Animation secondaryAnimation; - final Widget child; - - @override - Widget build(BuildContext context) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: child, - ); - } -} \ No newline at end of file diff --git a/lib/v11/app/navigation/transition/fade_transition_page.dart b/lib/v11/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index fc4e6e6..0000000 --- a/lib/v11/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v11/app/navigation/transition/no_transition_page.dart b/lib/v11/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v11/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v11/app/navigation/views/app_navigation.dart b/lib/v11/app/navigation/views/app_navigation.dart deleted file mode 100644 index bcad815..0000000 --- a/lib/v11/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatefulWidget { - final Widget navigator; - - const AppNavigation({super.key,required this.navigator}); - - @override - State createState() => _AppNavigationState(); -} - -class _AppNavigationState extends State { - - @override - void initState() { - print('======_AppNavigationState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_AppNavigationState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: widget.navigator, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v11/app/navigation/views/app_navigation_rail.dart b/lib/v11/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 654650c..0000000 --- a/lib/v11/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined, path: '/color'), - MenuMeta(label: '计数器', icon: Icons.add_chart, path: '/counter'), - MenuMeta(label: '排序', icon: Icons.sort, path: '/sort'), - MenuMeta(label: '我的', icon: Icons.person, path: '/user'), - MenuMeta(label: '设置', icon: Icons.settings, path: '/settings'), - ]; - - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text( - 'V0.1.1', - style: TextStyle(color: Colors.white, fontSize: 12), - ), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: activeIndex, - ), - ); - } - - final RegExp _segReg = RegExp(r'/\w+'); - - int? get activeIndex { - final String path = GoRouterState.of(context).uri.toString(); - RegExpMatch? match = _segReg.firstMatch(path); - if (match == null) return null; - String? target = match.group(0); - int index = deskNavBarMenus.indexWhere((menu) => menu.path!.contains(target??'')); - if (index == -1) return null; - return index; - } - - void _onDestinationSelected(int index) { - String path = deskNavBarMenus[index].path!; - if(index==4){ - GoRouter.of(context).push(path); - }else{ - GoRouter.of(context).go(path); - } - } -} diff --git a/lib/v11/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v11/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index ea7c2da..0000000 --- a/lib/v11/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -// import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - late GoRouterDelegate _delegate ; - - - @override - void initState() { - super.initState(); - _delegate = GoRouter.of(context).routerDelegate; - - _onRouteChange(); - _delegate.addListener(_onRouteChange); - } - - void _onRouteChange() { - - List matches = _delegate.currentConfiguration.matches; - if(matches.isEmpty) return; - RouteMatch match = matches.last; - if(match is ImperativeRouteMatch){ - _controller.text = match.matches.uri.toString(); - }else{ - _controller.text = match.matchedLocation; - } - } - - @override - void dispose() { - _controller.dispose(); - _delegate.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v11/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v11/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index c43932a..0000000 --- a/lib/v11/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,137 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; -import '../../helper/function.dart'; -import '../route_back_indicator.dart'; -import 'app_router_editor.dart'; -import 'route_history_button.dart'; -import 'history_view_icon.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - // alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouteBackIndicator(), - const RouterIndicator(), - // Spacer(), - Expanded( - child: Row(textDirection: TextDirection.rtl, children: [ - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ), - HistoryViewIcon(), - const SizedBox( - width: 12, - ), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) { - GoRouter.of(context).go(path); - // => router.changePath(path) - }, - )), - const SizedBox( - width: 12, - ), - RouteHistoryButton(), - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -class _RouterIndicatorState extends State { - late GoRouterDelegate _delegate; - @override - void initState() { - super.initState(); - _delegate = GoRouter.of(context).routerDelegate; - _delegate.addListener(_onRouterChange); - } - - @override - void dispose() { - _delegate.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List matches = _delegate.currentConfiguration.matches; - if(matches.isEmpty) return const SizedBox(); - RouteMatch match = _delegate.currentConfiguration.matches.last; - - print( - "=========_RouterIndicatorState:build==${match.matchedLocation}========"); - - return TolyBreadcrumb( - items: pathToBreadcrumbItems(context, match.matchedLocation), - onTapItem: (item) { - if (item.to != null) { - GoRouter.of(context).go(item.to!); - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems( - BuildContext context, String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = calcRouteName(context, to); - if (label.isNotEmpty) { - result - .add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - } - return result; - } -} - -Map kRouteLabelMap = { - '': '', - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/sort': '排序算法', - '/sort/player': '演示', - '/sort/settings': '排序配置', - '/user': '我的', - '/settings': '系统设置', -}; diff --git a/lib/v11/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v11/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index 1bb6749..0000000 --- a/lib/v11/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,156 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; -import 'package:iroute/v11/app/navigation/helper/function.dart'; -import '../../helper/router_history.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - RouterHistory routerHistory = RouterHistoryScope.read(context); - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(routerHistory), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar( RouterHistory routerHistory) { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: routerHistory.clear, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final RouteMatchList history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - String path = widget.history.matches.last.matchedLocation; - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(path), - const SizedBox( - height: 2, - ), - Text(calcRouteName(context, path)), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - late RouterHistory _history ; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _history = RouterHistoryScope.of(context); - } - - - @override - Widget build(BuildContext context) { - List histories = _history.histories.reversed.toList(); - if(histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - _history.close(histories[index]); - }, - onPressed: ()async { - Navigator.of(context).pop(); - _history.select(histories[index]); - // router.changeRoute(histories[index].copyWith(recordHistory: false)); - }, - history: histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v11/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v11/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index d94a2ef..0000000 --- a/lib/v11/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; - -import '../../helper/router_history.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - - late RouterHistory _history ; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _history = RouterHistoryScope.of(context); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = _history.hasHistory; - bool hasBackHistory = _history.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?_history.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?_history.revocation:null, - ), - ], - ); - } -} diff --git a/lib/v11/app/navigation/views/not_find_view.dart b/lib/v11/app/navigation/views/not_find_view.dart deleted file mode 100644 index ccefa16..0000000 --- a/lib/v11/app/navigation/views/not_find_view.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotFindPage extends StatelessWidget { - const NotFindPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Material( - child: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - '404 Page Not Find', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ); - } -} diff --git a/lib/v11/app/navigation/views/route_back_indicator.dart b/lib/v11/app/navigation/views/route_back_indicator.dart deleted file mode 100644 index 2142daa..0000000 --- a/lib/v11/app/navigation/views/route_back_indicator.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -class RouteBackIndicator extends StatefulWidget { - const RouteBackIndicator({super.key}); - - @override - State createState() => _RouteBackIndicatorState(); -} - -class _RouteBackIndicatorState extends State { - - late GoRouterDelegate _delegate ; - - @override - void initState() { - super.initState(); - _delegate = GoRouter.of(context).routerDelegate; - _delegate.addListener(_onChange); - } - - @override - void dispose() { - _delegate.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasPush = _delegate.currentConfiguration.matches - .whereType().isNotEmpty; - if(hasPush){ - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: context.pop, - child: Container( - width: 26, - height: 26, - margin: EdgeInsets.only(right: 8), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Color(0xffE3E5E7), - borderRadius: BorderRadius.circular(6) - ), - child: Icon(Icons.arrow_back_ios_new,size: 14,)), - ), - ); - } - return SizedBox(); - } - - void _onChange() { - setState(() { - - }); - } -} diff --git a/lib/v11/app/unit_app.dart b/lib/v11/app/unit_app.dart deleted file mode 100644 index d17c59c..0000000 --- a/lib/v11/app/unit_app.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../pages/empty/empty_page.dart'; -import 'navigation/router/root.dart'; -import '../pages/sort/provider/state.dart'; -import 'navigation/helper/router_history.dart'; -import 'navigation/transition/fade_page_transitions_builder.dart'; - -class UnitApp extends StatelessWidget { - UnitApp({super.key}); - - final GoRouter _router = GoRouter( - routes: [rootRoute], - onException: (BuildContext ctx,GoRouterState state, GoRouter router){ - router.go('/404', extra: state.uri.toString()); - }, - // errorBuilder: (_,state) { - // return EmptyPage(msg: '无法访问: ${state.matchedLocation}',); - // } - ); - - @override - Widget build(BuildContext context) { - return SortStateScope( - notifier: SortState(), - child: RouterHistoryScope( - notifier: RouterHistory(_router.routerDelegate, exclusives: ['/login']), - child: MaterialApp.router( - routerConfig: _router, - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - pageTransitionsTheme: const PageTransitionsTheme(builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - }), - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - // home: AppNavigation() - ), - ), - ); - } -} diff --git a/lib/v11/pages/color/color_add_page.dart b/lib/v11/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v11/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v11/pages/color/color_detail_page.dart b/lib/v11/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v11/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v11/pages/color/color_page.dart b/lib/v11/pages/color/color_page.dart deleted file mode 100644 index 4081e78..0000000 --- a/lib/v11/pages/color/color_page.dart +++ /dev/null @@ -1,84 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/project/colors_panel.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, - Colors.black, - Colors.blue, - Colors.green, - Colors.orange, - Colors.pink, - Colors.purple, - Colors.indigo, - Colors.amber, - Colors.cyan, - Colors.redAccent, - Colors.grey, - Colors.blueAccent, - Colors.greenAccent, - Colors.orangeAccent, - Colors.pinkAccent, - Colors.purpleAccent, - Colors.indigoAccent, - Colors.amberAccent, - Colors.cyanAccent, - ]; - - @override - void initState() { - print('======_ColorPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_ColorPageState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color) { - String value = color.value.toRadixString(16); - context.push('/color/detail?color=$value'); - // context.pushNamed( - // 'colorDetail', - // queryParameters: {'color': value}, - // ); - } - - void _toAddPage() async { - Color? color = await context.push('/color/add'); - - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/v11/pages/counter/counter_page.dart b/lib/v11/pages/counter/counter_page.dart deleted file mode 100644 index b74a199..0000000 --- a/lib/v11/pages/counter/counter_page.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - @override - void initState() { - print('======_CounterPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_CounterPageState#dispose=============='); - super.dispose(); - } - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v11/pages/empty/empty_page.dart b/lib/v11/pages/empty/empty_page.dart deleted file mode 100644 index 008d529..0000000 --- a/lib/v11/pages/empty/empty_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; - -class EmptyPage extends StatelessWidget { - final String msg; - const EmptyPage({super.key, required this.msg}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Scaffold( - appBar: PreferredSize( - preferredSize: Size.fromHeight(46), - child: Row( - children: [ - const SizedBox(width: 20,), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - ), - Spacer(), - const WindowButtons() - ], - ), - ), - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - msg, - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ElevatedButton(onPressed: (){ - context.go('/'); - }, child: Text('返回首页')) - ], - ), - ), - ), - ); - } -} - diff --git a/lib/v11/pages/empty/empty_panel.dart b/lib/v11/pages/empty/empty_panel.dart deleted file mode 100644 index 1e99155..0000000 --- a/lib/v11/pages/empty/empty_panel.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; - -class EmptyPanel extends StatelessWidget { - final String msg; - const EmptyPanel({super.key, required this.msg}); - - @override - Widget build(BuildContext context) { - return Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - msg, - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ElevatedButton(onPressed: (){ - context.go('/'); - }, child: Text('返回首页')) - ], - ), - ); - } -} - diff --git a/lib/v11/pages/login/login.dart b/lib/v11/pages/login/login.dart deleted file mode 100644 index 3177a76..0000000 --- a/lib/v11/pages/login/login.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - - -class LoginPage extends StatelessWidget { - const LoginPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Login Page',style: TextStyle(fontSize: 24),), - const SizedBox(height: 20,), - ElevatedButton(onPressed: (){ - GoRouter.of(context).go('/color'); - // router.changePath('/app/color'); - }, child: Text('点击进入')) - ], - ), - ), - ); - } -} diff --git a/lib/v11/pages/settings/settings_page.dart b/lib/v11/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v11/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v11/pages/sort/functions.dart b/lib/v11/pages/sort/functions.dart deleted file mode 100644 index 6ae1176..0000000 --- a/lib/v11/pages/sort/functions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'functions/bubble.dart'; -import 'functions/cocktail.dart'; -import 'functions/comb.dart'; -import 'functions/cycle.dart'; -import 'functions/gnome.dart'; -import 'functions/heap.dart'; -import 'functions/insertion.dart'; -import 'functions/merage.dart'; -import 'functions/pigeonHole.dart'; -import 'functions/quick.dart'; -import 'functions/selection.dart'; -import 'functions/shell.dart'; - -typedef SortFunction = Future Function(List src, SortCallback callback); -typedef SortCallback = Future Function(List dist); - -Map sortFunctionMap = { - 'insertion': insertionSort, - 'bubble': bubbleSort, - 'cocktail': cocktailSort, - 'comb': combSort, - 'pigeonHole': pigeonHoleSort, - 'shell': shellSort, - 'selection': selectionSort, - 'gnome': gnomeSort, - 'cycle': cycleSort, - 'heap': heapSort, - 'quick': quickSort, - 'mergeSort': mergeSort, -}; - -Map sortNameMap = { - 'insertion': '插入排序', - 'bubble': '冒泡排序', - 'cocktail': '鸡尾酒排序(双向冒泡排序)', - 'comb': '梳排序', - 'pigeonHole': '鸽巢排序', - 'shell': '希尔排序', - 'selection': '选择排序', - 'gnome': '侏儒排序', - 'cycle': '循环排序', - 'heap': '堆排序', - 'quick': '快速排序', - 'mergeSort': '归并排序', -}; - diff --git a/lib/v11/pages/sort/functions/bubble.dart b/lib/v11/pages/sort/functions/bubble.dart deleted file mode 100644 index 3cf3c99..0000000 --- a/lib/v11/pages/sort/functions/bubble.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///冒泡排序 -Future bubbleSort(List src, SortCallback callback ) async{ - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < src.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < src.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (src[j] > src[j + 1]) { - int temp = src[j]; - src[j] = src[j + 1]; - src[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/cocktail.dart b/lib/v11/pages/sort/functions/cocktail.dart deleted file mode 100644 index 8c2d18c..0000000 --- a/lib/v11/pages/sort/functions/cocktail.dart +++ /dev/null @@ -1,52 +0,0 @@ -import '../functions.dart'; - -///鸡尾酒排序(双向冒泡排序) -Future cocktailSort(List src, SortCallback callback ) async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = src.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/comb.dart b/lib/v11/pages/sort/functions/comb.dart deleted file mode 100644 index 821f4a9..0000000 --- a/lib/v11/pages/sort/functions/comb.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '../functions.dart'; - -///梳排序(Comb Sort) -Future combSort(List src, SortCallback callback) async{ - int gap = src.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < src.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (src[i] > src[i + gap]) { - int temp = src[i]; - src[i] = src[i + gap]; - src[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await callback(src); - } - } -} - -int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/cycle.dart b/lib/v11/pages/sort/functions/cycle.dart deleted file mode 100644 index 4bef6eb..0000000 --- a/lib/v11/pages/sort/functions/cycle.dart +++ /dev/null @@ -1,54 +0,0 @@ -import '../functions.dart'; - -///循环排序 -Future cycleSort(List src, SortCallback callback) async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) { - int item = src[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (item != src[pos]) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/gnome.dart b/lib/v11/pages/sort/functions/gnome.dart deleted file mode 100644 index 5e08fc3..0000000 --- a/lib/v11/pages/sort/functions/gnome.dart +++ /dev/null @@ -1,22 +0,0 @@ -import '../functions.dart'; - -///地精排序 (侏儒排序) -Future gnomeSort(List src, SortCallback callback) async { - int index = 0; - while (index < src.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (src[index] >= src[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = src[index]; - src[index] = src[index - 1]; - src[index - 1] = temp; - index--; - } - await callback(src); - } - return; -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/heap.dart b/lib/v11/pages/sort/functions/heap.dart deleted file mode 100644 index 9f5410b..0000000 --- a/lib/v11/pages/sort/functions/heap.dart +++ /dev/null @@ -1,38 +0,0 @@ -import '../functions.dart'; - -///堆排序 -Future heapSort(List src, SortCallback callback) async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = src.length ~/ 2; i >= 0; i--) { - await heapify(src,callback, src.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = src.length - 1; i >= 0; i--) { - int temp = src[0]; - src[0] = src[i]; - src[i] = temp; - await heapify(src, callback,i, 0); - } -} - -Future heapify(List src, SortCallback callback, int n, int i) async{ - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && src[l] > src[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && src[r] > src[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = src[i]; - src[i] = src[largest]; - src[largest] = temp; - heapify(src,callback, n, largest); - } - await callback(src); -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/insertion.dart b/lib/v11/pages/sort/functions/insertion.dart deleted file mode 100644 index b1c7814..0000000 --- a/lib/v11/pages/sort/functions/insertion.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///插入排序 -Future insertionSort(List src, SortCallback callback) async { - for (int i = 1; i < src.length; i++) { - int temp = src[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < src[j]) { - src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - // 更新排序结果回调 - await callback(src); - } - src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await callback(src); - } -} diff --git a/lib/v11/pages/sort/functions/merage.dart b/lib/v11/pages/sort/functions/merage.dart deleted file mode 100644 index 12135b4..0000000 --- a/lib/v11/pages/sort/functions/merage.dart +++ /dev/null @@ -1,79 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future mergeSort(List src, SortCallback callback) async { - await _mergeSort(src,callback,0,src.length-1); -} - -///归并排序 -Future _mergeSort(List src, SortCallback callback,int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = src[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = src[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - src[k] = leftList[i]; - i++; - } else { - src[k] = rightList[j]; - j++; - } - - await callback(src); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - src[k] = leftList[i]; - i++; - k++; - - await callback(src); - } - - while (j < rightSize) { - src[k] = rightList[j]; - j++; - k++; - - await callback(src); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await _mergeSort(src,callback,leftIndex, middleIndex); - await _mergeSort(src,callback,middleIndex + 1, rightIndex); - - await callback(src); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/oddEven.dart b/lib/v11/pages/sort/functions/oddEven.dart deleted file mode 100644 index bd6f548..0000000 --- a/lib/v11/pages/sort/functions/oddEven.dart +++ /dev/null @@ -1,37 +0,0 @@ -import '../functions.dart'; - -///奇偶排序(Odd-Even Sort) -Future oddEvenSort(List src, SortCallback callback) async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= src.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await callback(src); - } - } - - for (int i = 0; i <= src.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; - await callback(src); - } - } - } - - return; -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/pigeonHole.dart b/lib/v11/pages/sort/functions/pigeonHole.dart deleted file mode 100644 index 83bbce1..0000000 --- a/lib/v11/pages/sort/functions/pigeonHole.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../functions.dart'; - -///鸽巢排序 -Future pigeonHoleSort(List src, SortCallback callback ) async{ - int min = src[0]; - int max = src[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < src.length; a++) { - if (src[a] > max) max = src[a]; - if (src[a] < min) min = src[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < src.length; i++) { - p[src[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - src[index++] = j + min; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/quick.dart b/lib/v11/pages/sort/functions/quick.dart deleted file mode 100644 index 25b9685..0000000 --- a/lib/v11/pages/sort/functions/quick.dart +++ /dev/null @@ -1,65 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future quickSort(List src, SortCallback callback) async { - await _quickSort(src,callback,0,src.length-1); -} - -///快速排序 -Future _quickSort(List src, SortCallback callback,int leftIndex,int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = src[p]; - src[p] = src[right]; - src[right] = temp; - await callback(src); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(src[i], src[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = src[i]; - src[i] = src[cursor]; - src[cursor] = temp; - cursor++; - await callback(src); - } - } - - // 将基准元素放置在游标位置 - temp = src[right]; - src[right] = src[cursor]; - src[cursor] = temp; - - await callback(src); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } -} - -// 比较函数,用于判断两个元素的大小关系 -cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/selection.dart b/lib/v11/pages/sort/functions/selection.dart deleted file mode 100644 index 185dae2..0000000 --- a/lib/v11/pages/sort/functions/selection.dart +++ /dev/null @@ -1,18 +0,0 @@ -import '../functions.dart'; - -///选择排序 -Future selectionSort(List src, SortCallback callback ) async { - for (int i = 0; i < src.length; i++) { - for (int j = i + 1; j < src.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (src[i] > src[j]) { - // 判断当前元素是否比后续元素小 - int temp = src[j]; - // 交换当前元素和后续较小的元素 - src[j] = src[i]; - src[i] = temp; - } - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/functions/shell.dart b/lib/v11/pages/sort/functions/shell.dart deleted file mode 100644 index 232f872..0000000 --- a/lib/v11/pages/sort/functions/shell.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../functions.dart'; - -///希尔排序 -Future shellSort(List src, SortCallback callback) async{ - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < src.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = src[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && src[j - gap] > temp; j -= gap) { - src[j] = src[j - gap]; - } - src[j] = temp; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/provider/sort_config.dart b/lib/v11/pages/sort/provider/sort_config.dart deleted file mode 100644 index 1fc3790..0000000 --- a/lib/v11/pages/sort/provider/sort_config.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -class SortConfig { - final int count; - 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, - }) => - SortConfig( - count:count??this.count, - seed:seed??this.seed, - duration:duration??this.duration, - name:name??this.name, - colorIndex:colorIndex??this.colorIndex, - ); -} - diff --git a/lib/v11/pages/sort/provider/state.dart b/lib/v11/pages/sort/provider/state.dart deleted file mode 100644 index b594b1e..0000000 --- a/lib/v11/pages/sort/provider/state.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -import '../functions.dart'; -import 'sort_config.dart'; - -enum SortStatus{ - none, // 未操作 - sorting, // 排序中 - sorted, // 排序完成 -} - -List 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(){ - reset(); - } - - SortStatus status = SortStatus.none; - - List data = []; - List stepData = []; - - SortConfig _config = SortConfig(); - SortConfig get config => _config; - Random random = Random(); - - set config(SortConfig config){ - _config = config; - reset(); - notifyListeners(); - } - - void selectName(String name){ - if(name==config.name) return; - 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; - notifyListeners(); - int count = config.count; - if(config.seed!=-1){ - random = Random(config.seed); - } - for (int i = 0; i < count; i++) { - //随机往数组中填值 - data.add(random.nextInt(1000)); - } - } - - void sort() async{ - status = SortStatus.sorting; - notifyListeners(); - Stopwatch stopwatch = Stopwatch()..start(); - SortFunction? sortFunction = sortFunctionMap[config.name]; - if(sortFunction!=null){ - await sortFunction(data,(arr) async { - await Future.delayed(config.duration); - notifyListeners(); - }); - } - status = SortStatus.sorted; - notifyListeners(); - stopwatch.stop(); - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - } -} - -/// Provides the current [SortState] to descendant widgets in the tree. -class SortStateScope extends InheritedNotifier { - const SortStateScope({ - required super.notifier, - required super.child, - super.key, - }); - - static SortState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; - - static SortState read(BuildContext context) { - return context.getInheritedWidgetOfExactType()!.notifier!; - } -} \ No newline at end of file diff --git a/lib/v11/pages/sort/views/code_page/code_page.dart b/lib/v11/pages/sort/views/code_page/code_page.dart deleted file mode 100644 index 7d8d4c9..0000000 --- a/lib/v11/pages/sort/views/code_page/code_page.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class CodePage extends StatelessWidget { - const CodePage({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - leading: BackButton(), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - centerTitle: true, - title: Text(sortNameMap[state.config.name]!+'代码实现'), - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text('代码'*1000), - )); - } -} diff --git a/lib/v11/pages/sort/views/player/data_painter.dart b/lib/v11/pages/sort/views/player/data_painter.dart deleted file mode 100644 index 392a9e8..0000000 --- a/lib/v11/pages/sort/views/player/data_painter.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; - - - -class DataPainter extends CustomPainter{ - - final List data; - final MaterialColor color; - - DataPainter( {required this.data,required this.color,}); - - @override - void paint(Canvas canvas, Size size) { - double itemWidth = size.width/data.length; - double height = size.height; - - Paint paint = Paint(); - paint.strokeWidth = itemWidth; - paint.strokeCap = StrokeCap.round; - - - for(int i=0;i 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()), - ), - ); - } -} diff --git a/lib/v11/pages/sort/views/settings/color_picker.dart b/lib/v11/pages/sort/views/settings/color_picker.dart deleted file mode 100644 index b0bb469..0000000 --- a/lib/v11/pages/sort/views/settings/color_picker.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorPicker extends StatelessWidget { - final List colors; - final ValueChanged 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(), - ); - } -} diff --git a/lib/v11/pages/sort/views/settings/sort_setting.dart b/lib/v11/pages/sort/views/settings/sort_setting.dart deleted file mode 100644 index fe86289..0000000 --- a/lib/v11/pages/sort/views/settings/sort_setting.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../provider/state.dart'; -import 'color_picker.dart'; -class SortSettings extends StatefulWidget { - - const SortSettings({super.key,}); - - @override - State createState() => _SortSettingsState(); -} - -class _SortSettingsState extends State { - 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, - automaticallyImplyLeading: false, - // 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.read(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 - ); - GoRouter.of(context).pop(); - // 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('确定设置')) - ], - ), - ), - ); - } -} diff --git a/lib/v11/pages/sort/views/sort_page/sort_button.dart b/lib/v11/pages/sort/views/sort_page/sort_button.dart deleted file mode 100644 index 93df9d9..0000000 --- a/lib/v11/pages/sort/views/sort_page/sort_button.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../provider/state.dart'; - -class SortButton extends StatelessWidget { - const SortButton({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - VoidCallback? action; - IconData icon; - String text = ''; - Color color; - switch (state.status) { - case SortStatus.none: - icon = Icons.not_started_outlined; - color = Colors.green; - action = state.sort; - text = '点击启动'; - break; - case SortStatus.sorting: - icon = Icons.stop_circle_outlined; - color = Colors.grey; - action = null; - text = '排序中...'; - break; - case SortStatus.sorted: - icon = CupertinoIcons.repeat; - color = Colors.black; - action = state.reset; - text = '点击重置'; - break; - } - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: action, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon( - icon, - color: color, - size: 18, - ), - const SizedBox(width: 4,), - Text(text,style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold,color: color),), - ], - ), - ), - ); - } -} diff --git a/lib/v11/pages/sort/views/sort_page/sort_page.dart b/lib/v11/pages/sort/views/sort_page/sort_page.dart deleted file mode 100644 index 6631bff..0000000 --- a/lib/v11/pages/sort/views/sort_page/sort_page.dart +++ /dev/null @@ -1,166 +0,0 @@ - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'sort_button.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class SortNavigation extends StatelessWidget { - final Widget navigator; - const SortNavigation({super.key, required this.navigator}); - - @override - Widget build(BuildContext context) { - return Material( - child: Row( - children: [ - SizedBox( - width: 220, - child: SortRailPanel(), - ), - VerticalDivider( - width: 1, - ), - Expanded( - child: navigator, - ) - ], - ), - ); - } -} - -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: () { - GoRouter.of(context).push('/sort/settings'); - // router.changePath('/app/sort/settings',style: RouteStyle.push); - }, - 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); - GoRouter.of(context).go('/sort/player/$name'); - }, - ), - ), - ], - ); - } -} - -class SortSelectorPanel extends StatelessWidget { - final String active; - final ValueChanged onSelected; - final List 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 createState() => _SortItemTileState(); -} - -class _SortItemTileState extends State { - @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), - ), - ), - ), - ), - ); - } -} diff --git a/lib/v11/pages/user/user_page.dart b/lib/v11/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v11/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v12/app.dart b/lib/v12/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v12/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v12/app/authentication/auth_scope.dart b/lib/v12/app/authentication/auth_scope.dart deleted file mode 100644 index a9f37e0..0000000 --- a/lib/v12/app/authentication/auth_scope.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'package:flutter/material.dart'; - -const Map _kTestUserMap = { - 'toly': '123456', - '张风捷特烈': '111111', - 'test1': '111111', -}; - -class AuthScope extends InheritedNotifier { - const AuthScope({super.key, required super.child, super.notifier}); - - static AuthResult of(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType()! - .notifier!; - } - - static AuthResult read(BuildContext context) { - return context - .getInheritedWidgetOfExactType()! - .notifier!; - } -} - -enum AuthStatus{ - none, - success, - failed, - waitingLogin, - waitingLoginOut, -} - -class AuthResult with ChangeNotifier { - String? name; - int coin = 0; - String? token; - AuthStatus status = AuthStatus.none; - - AuthResult(); - - Future<(bool,String)> login(String username,String pwd) async{ - /// 模拟校验 与 模拟延时 - bool allow = _kTestUserMap[username] == pwd; - status = AuthStatus.waitingLogin; - notifyListeners(); - await Future.delayed(const Duration(seconds: 1)); - if(allow){ - name = username; - coin = 1994328; - token = 'testToken======'; - status = AuthStatus.success; - notifyListeners(); - return (true,'登陆成功!'); - }else{ - /// 可以返回一写其他错误信息 - status = AuthStatus.failed; - notifyListeners(); - return (false,'登陆失败!'); - } - } - - Future logout() async{ - status = AuthStatus.waitingLoginOut; - notifyListeners(); - /// 模拟退出登录请求耗时 - await Future.delayed(const Duration(seconds: 1)); - name = null; - coin = 0; - token = null; - status = AuthStatus.none; - notifyListeners(); - return true; - } -} - diff --git a/lib/v12/app/navigation/helper/function.dart b/lib/v12/app/navigation/helper/function.dart deleted file mode 100644 index 526be07..0000000 --- a/lib/v12/app/navigation/helper/function.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -Map kRouteLabelMap = { - '': '', - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/sort': '排序算法', - '/sort/player': '', - '/sort/settings': '排序配置', - '/user': '我的', - '/settings': '系统设置', -}; - - -String calcRouteName(BuildContext context,String path){ - String? result = kRouteLabelMap[path]; - if(result !=null) return result; - if(path.startsWith('/sort/player/')){ - return path.split('/sort/player/')[1]; - } - - return '未知路由'; -} \ No newline at end of file diff --git a/lib/v12/app/navigation/helper/router_history.dart b/lib/v12/app/navigation/helper/router_history.dart deleted file mode 100644 index 19deda0..0000000 --- a/lib/v12/app/navigation/helper/router_history.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -class RouterHistoryScope extends InheritedNotifier { - const RouterHistoryScope({super.key, required super.child, super.notifier}); - - static RouterHistory of(BuildContext context) { - return context - .dependOnInheritedWidgetOfExactType()! - .notifier!; - } - - static RouterHistory read(BuildContext context) { - return context - .getInheritedWidgetOfExactType()! - .notifier!; - } -} - -class RouterHistory with ChangeNotifier { - final List exclusives; - - final GoRouterDelegate delegate; - - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories; - - RouterHistory(this.delegate, {this.exclusives = const []}) { - delegate.addListener(_onRouteChange); - } - - /// 用于记录当前历史记录 - /// 清空历史之后,切换时,先记录 _current - RouteMatchList? _current; - - void _onRouteChange() { - /// 当没有历史,且 _current 非空 - if (_histories.isEmpty && _current != null) { - _histories.add(_current!); - } - - RouteMatchList matchList = delegate.currentConfiguration; - if (_histories.isNotEmpty && matchList == _histories.last - || matchList.isEmpty - ) return; - - - - String uri = matchList.last.matchedLocation; - if (exclusives.contains(uri)) { - return; - } - _recode(matchList); - } - - /// 将 [history] 加入历史记录 - void _recode(RouteMatchList history) { - _current = history; - _histories.add(history); - if (hasHistory) { - notifyListeners(); - } - } - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 历史回退操作 - /// 将当前顶层移除,并加入 [_backHistories] 撤销列表 - /// 并转到前一路径 [_histories.last] - void back() { - if (!hasHistory) { - return; - } - RouteMatchList top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - delegate.setNewRoutePath(_histories.last); - notifyListeners(); - } - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation() { - RouteMatchList target = _backHistories.removeLast(); - delegate.setNewRoutePath(target); - notifyListeners(); - } - - void close(RouteMatchList history) { - _histories.remove(history); - notifyListeners(); - } - - void clear() { - _histories.clear(); - notifyListeners(); - } - - void select(RouteMatchList history) { - _histories.remove(history); - delegate.setNewRoutePath(history); - } -} diff --git a/lib/v12/app/navigation/router/app.dart b/lib/v12/app/navigation/router/app.dart deleted file mode 100644 index c9719e7..0000000 --- a/lib/v12/app/navigation/router/app.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/counter/counter_page.dart'; -import '../../../pages/user/user_page.dart'; -import '../../../pages/settings/settings_page.dart'; -import '../../../pages/empty/empty_panel.dart'; -import '../views/app_navigation.dart'; -import 'color.dart'; -import 'sort.dart'; - - -final RouteBase appRoute = ShellRoute( - builder: (BuildContext context, GoRouterState state, Widget child) { - return AppNavigation(navigator: child); - }, - routes: [ - colorRouters, - GoRoute( - path: 'counter', - builder: (BuildContext context, GoRouterState state) { - return const CounterPage(); - }), - sortRouters, - GoRoute( - path: 'user', - builder: (BuildContext context, GoRouterState state) { - return const UserPage(); - }, - ), - GoRoute( - path: 'settings', - builder: (BuildContext context, GoRouterState state) { - return const SettingPage(); - }, - ), - GoRoute( - path: '404', - builder: (BuildContext context, GoRouterState state) { - String msg = '无法访问: ${state.extra}'; - return EmptyPanel(msg: msg); - }, - ) - ], -); diff --git a/lib/v12/app/navigation/router/color.dart b/lib/v12/app/navigation/router/color.dart deleted file mode 100644 index 6a2052a..0000000 --- a/lib/v12/app/navigation/router/color.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/color/color_add_page.dart'; -import '../../../pages/color/color_detail_page.dart'; -import '../../../pages/color/color_page.dart'; - - - -final RouteBase colorRouters = GoRoute( - path: 'color', - builder: (BuildContext context, GoRouterState state) { - return const ColorPage(); - }, - routes: [ - GoRoute( - path: 'detail', - name: 'colorDetail', - builder: (BuildContext context, GoRouterState state) { - String? selectedColor = state.uri.queryParameters['color']; - Color color = Colors.black; - if (selectedColor != null) { - color = Color(int.parse(selectedColor, radix: 16)); - } - return ColorDetailPage(color: color); - }, - ), - GoRoute( - path: 'add', - builder: (BuildContext context, GoRouterState state) { - return const ColorAddPage(); - }, - ), - ], -); - diff --git a/lib/v12/app/navigation/router/root.dart b/lib/v12/app/navigation/router/root.dart deleted file mode 100644 index 9eea0a3..0000000 --- a/lib/v12/app/navigation/router/root.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/login/login.dart'; -import 'app.dart'; - -final RouteBase rootRoute = GoRoute( - path: '/', - redirect: _redirect, - routes: [ - appRoute, - GoRoute( - path: 'login', - builder: (BuildContext context, GoRouterState state) { - return const LoginPage(); - }, - ), - ], -); - -FutureOr _redirect(BuildContext context, GoRouterState state) { - if(state.fullPath=='/'){ - return '/color'; - } - return null; -} diff --git a/lib/v12/app/navigation/router/sort.dart b/lib/v12/app/navigation/router/sort.dart deleted file mode 100644 index e6d6a84..0000000 --- a/lib/v12/app/navigation/router/sort.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../../pages/sort/provider/state.dart'; - -import '../../../pages/sort/views/player/sort_player.dart'; -import '../../../pages/sort/views/settings/sort_setting.dart'; -import '../../../pages/sort/views/sort_page/sort_page.dart'; - -final RouteBase sortRouters = ShellRoute( - builder: (BuildContext context, GoRouterState state, Widget child) { - return SortNavigation(navigator: child); - }, - routes: [ - GoRoute( - path: 'sort', - redirect: _redirectSort, - routes: [ - GoRoute( - path: 'player/:name', - builder: (BuildContext context, GoRouterState state) { - print(state.pathParameters);// 获取路径参数 - return const SortPlayer(); - }, - ), - GoRoute( - path: 'settings', - builder: (BuildContext context, GoRouterState state) { - return const SortSettings(); - }, - ), - ], - ), - ], -); - -FutureOr _redirectSort(BuildContext context, GoRouterState state) { - if (state.fullPath == '/sort') { - String name = SortStateScope.read(context).config.name; - return '/sort/player/$name'; - } - return null; -} diff --git a/lib/v12/app/navigation/transition/fade_page_transitions_builder.dart b/lib/v12/app/navigation/transition/fade_page_transitions_builder.dart deleted file mode 100644 index 0587ecc..0000000 --- a/lib/v12/app/navigation/transition/fade_page_transitions_builder.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class FadePageTransitionsBuilder extends PageTransitionsBuilder { - - const FadePageTransitionsBuilder(); - - @override - Widget buildTransitions( - PageRoute? route, - BuildContext? context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return _FadePagePageTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - child: child, - ); - } -} - -class _FadePagePageTransition extends StatelessWidget { - - const _FadePagePageTransition({ - required this.animation, - required this.secondaryAnimation, - required this.child, - }); - - final Animation animation; - final Animation secondaryAnimation; - final Widget child; - - @override - Widget build(BuildContext context) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: child, - ); - } -} \ No newline at end of file diff --git a/lib/v12/app/navigation/transition/fade_transition_page.dart b/lib/v12/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index fc4e6e6..0000000 --- a/lib/v12/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v12/app/navigation/transition/no_transition_page.dart b/lib/v12/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v12/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v12/app/navigation/views/app_navigation.dart b/lib/v12/app/navigation/views/app_navigation.dart deleted file mode 100644 index bcad815..0000000 --- a/lib/v12/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatefulWidget { - final Widget navigator; - - const AppNavigation({super.key,required this.navigator}); - - @override - State createState() => _AppNavigationState(); -} - -class _AppNavigationState extends State { - - @override - void initState() { - print('======_AppNavigationState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_AppNavigationState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: widget.navigator, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v12/app/navigation/views/app_navigation_rail.dart b/lib/v12/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 654650c..0000000 --- a/lib/v12/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined, path: '/color'), - MenuMeta(label: '计数器', icon: Icons.add_chart, path: '/counter'), - MenuMeta(label: '排序', icon: Icons.sort, path: '/sort'), - MenuMeta(label: '我的', icon: Icons.person, path: '/user'), - MenuMeta(label: '设置', icon: Icons.settings, path: '/settings'), - ]; - - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text( - 'V0.1.1', - style: TextStyle(color: Colors.white, fontSize: 12), - ), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: activeIndex, - ), - ); - } - - final RegExp _segReg = RegExp(r'/\w+'); - - int? get activeIndex { - final String path = GoRouterState.of(context).uri.toString(); - RegExpMatch? match = _segReg.firstMatch(path); - if (match == null) return null; - String? target = match.group(0); - int index = deskNavBarMenus.indexWhere((menu) => menu.path!.contains(target??'')); - if (index == -1) return null; - return index; - } - - void _onDestinationSelected(int index) { - String path = deskNavBarMenus[index].path!; - if(index==4){ - GoRouter.of(context).push(path); - }else{ - GoRouter.of(context).go(path); - } - } -} diff --git a/lib/v12/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v12/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index ea7c2da..0000000 --- a/lib/v12/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -// import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - late GoRouterDelegate _delegate ; - - - @override - void initState() { - super.initState(); - _delegate = GoRouter.of(context).routerDelegate; - - _onRouteChange(); - _delegate.addListener(_onRouteChange); - } - - void _onRouteChange() { - - List matches = _delegate.currentConfiguration.matches; - if(matches.isEmpty) return; - RouteMatch match = matches.last; - if(match is ImperativeRouteMatch){ - _controller.text = match.matches.uri.toString(); - }else{ - _controller.text = match.matchedLocation; - } - } - - @override - void dispose() { - _controller.dispose(); - _delegate.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v12/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v12/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index c43932a..0000000 --- a/lib/v12/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,137 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; -import '../../helper/function.dart'; -import '../route_back_indicator.dart'; -import 'app_router_editor.dart'; -import 'route_history_button.dart'; -import 'history_view_icon.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - // alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouteBackIndicator(), - const RouterIndicator(), - // Spacer(), - Expanded( - child: Row(textDirection: TextDirection.rtl, children: [ - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ), - HistoryViewIcon(), - const SizedBox( - width: 12, - ), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) { - GoRouter.of(context).go(path); - // => router.changePath(path) - }, - )), - const SizedBox( - width: 12, - ), - RouteHistoryButton(), - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -class _RouterIndicatorState extends State { - late GoRouterDelegate _delegate; - @override - void initState() { - super.initState(); - _delegate = GoRouter.of(context).routerDelegate; - _delegate.addListener(_onRouterChange); - } - - @override - void dispose() { - _delegate.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List matches = _delegate.currentConfiguration.matches; - if(matches.isEmpty) return const SizedBox(); - RouteMatch match = _delegate.currentConfiguration.matches.last; - - print( - "=========_RouterIndicatorState:build==${match.matchedLocation}========"); - - return TolyBreadcrumb( - items: pathToBreadcrumbItems(context, match.matchedLocation), - onTapItem: (item) { - if (item.to != null) { - GoRouter.of(context).go(item.to!); - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems( - BuildContext context, String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = calcRouteName(context, to); - if (label.isNotEmpty) { - result - .add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - } - return result; - } -} - -Map kRouteLabelMap = { - '': '', - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/sort': '排序算法', - '/sort/player': '演示', - '/sort/settings': '排序配置', - '/user': '我的', - '/settings': '系统设置', -}; diff --git a/lib/v12/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v12/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index 1bb6749..0000000 --- a/lib/v12/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,156 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; -import 'package:iroute/v11/app/navigation/helper/function.dart'; -import '../../helper/router_history.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - RouterHistory routerHistory = RouterHistoryScope.read(context); - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(routerHistory), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar( RouterHistory routerHistory) { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: routerHistory.clear, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final RouteMatchList history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - String path = widget.history.matches.last.matchedLocation; - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(path), - const SizedBox( - height: 2, - ), - Text(calcRouteName(context, path)), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - late RouterHistory _history ; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _history = RouterHistoryScope.of(context); - } - - - @override - Widget build(BuildContext context) { - List histories = _history.histories.reversed.toList(); - if(histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - _history.close(histories[index]); - }, - onPressed: ()async { - Navigator.of(context).pop(); - _history.select(histories[index]); - // router.changeRoute(histories[index].copyWith(recordHistory: false)); - }, - history: histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v12/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v12/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index d94a2ef..0000000 --- a/lib/v12/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; - -import '../../helper/router_history.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - - late RouterHistory _history ; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - _history = RouterHistoryScope.of(context); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = _history.hasHistory; - bool hasBackHistory = _history.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?_history.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?_history.revocation:null, - ), - ], - ); - } -} diff --git a/lib/v12/app/navigation/views/not_find_view.dart b/lib/v12/app/navigation/views/not_find_view.dart deleted file mode 100644 index ccefa16..0000000 --- a/lib/v12/app/navigation/views/not_find_view.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotFindPage extends StatelessWidget { - const NotFindPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Material( - child: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - '404 Page Not Find', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ); - } -} diff --git a/lib/v12/app/navigation/views/route_back_indicator.dart b/lib/v12/app/navigation/views/route_back_indicator.dart deleted file mode 100644 index 2142daa..0000000 --- a/lib/v12/app/navigation/views/route_back_indicator.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -class RouteBackIndicator extends StatefulWidget { - const RouteBackIndicator({super.key}); - - @override - State createState() => _RouteBackIndicatorState(); -} - -class _RouteBackIndicatorState extends State { - - late GoRouterDelegate _delegate ; - - @override - void initState() { - super.initState(); - _delegate = GoRouter.of(context).routerDelegate; - _delegate.addListener(_onChange); - } - - @override - void dispose() { - _delegate.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasPush = _delegate.currentConfiguration.matches - .whereType().isNotEmpty; - if(hasPush){ - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: context.pop, - child: Container( - width: 26, - height: 26, - margin: EdgeInsets.only(right: 8), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Color(0xffE3E5E7), - borderRadius: BorderRadius.circular(6) - ), - child: Icon(Icons.arrow_back_ios_new,size: 14,)), - ), - ); - } - return SizedBox(); - } - - void _onChange() { - setState(() { - - }); - } -} diff --git a/lib/v12/app/unit_app.dart b/lib/v12/app/unit_app.dart deleted file mode 100644 index 375a409..0000000 --- a/lib/v12/app/unit_app.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../app/authentication/auth_scope.dart'; -import 'navigation/router/root.dart'; -import '../pages/sort/provider/state.dart'; -import 'navigation/helper/router_history.dart'; -import 'navigation/transition/fade_page_transitions_builder.dart'; - - -class UnitApp extends StatelessWidget { - UnitApp({super.key}); - - final GoRouter _router = GoRouter( - routes: [rootRoute], - onException: (BuildContext ctx, GoRouterState state, GoRouter router) { - router.go('/404', extra: state.uri.toString()); - }, - redirect: _authRedirect - ); - - late final RouterHistory _routerHistory = RouterHistory( - _router.routerDelegate, - exclusives: ['/login'], - ); - final AuthResult _result = AuthResult(); - - @override - Widget build(BuildContext context) { - return AuthScope( - notifier: _result, - child: SortStateScope( - notifier: SortState(), - child: RouterHistoryScope( - notifier: _routerHistory, - child: MaterialApp.router( - routerConfig: _router, - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - pageTransitionsTheme: const PageTransitionsTheme(builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - }), - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - // home: AppNavigation() - ), - ), - - ), - ); - } - - -} - -FutureOr _authRedirect(BuildContext context, GoRouterState state) async{ - bool loggedIn = AuthScope.read(context).status==AuthStatus.success; - if (!loggedIn) { - return '/login'; - } - return null; -} \ No newline at end of file diff --git a/lib/v12/pages/color/color_add_page.dart b/lib/v12/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v12/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v12/pages/color/color_detail_page.dart b/lib/v12/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v12/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v12/pages/color/color_page.dart b/lib/v12/pages/color/color_page.dart deleted file mode 100644 index 9d9c15c..0000000 --- a/lib/v12/pages/color/color_page.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/project/colors_panel.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, - Colors.black, - Colors.blue, - Colors.green, - Colors.orange, - Colors.pink, - Colors.purple, - Colors.indigo, - Colors.amber, - Colors.cyan, - Colors.redAccent, - Colors.grey, - Colors.blueAccent, - Colors.greenAccent, - Colors.orangeAccent, - Colors.pinkAccent, - Colors.purpleAccent, - Colors.indigoAccent, - Colors.amberAccent, - Colors.cyanAccent, - ]; - - @override - void initState() { - print('======_ColorPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_ColorPageState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color) { - String value = color.value.toRadixString(16); - context.push('/color/detail?color=$value'); - // GoRouter.of(context) .pushNamed('colorDetail', queryParameters: {'color': value}); - } - - void _toAddPage() async { - Color? color = await context.push('/color/add'); - - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} diff --git a/lib/v12/pages/counter/counter_page.dart b/lib/v12/pages/counter/counter_page.dart deleted file mode 100644 index b74a199..0000000 --- a/lib/v12/pages/counter/counter_page.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - @override - void initState() { - print('======_CounterPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_CounterPageState#dispose=============='); - super.dispose(); - } - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v12/pages/empty/empty_page.dart b/lib/v12/pages/empty/empty_page.dart deleted file mode 100644 index 008d529..0000000 --- a/lib/v12/pages/empty/empty_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/components/components.dart'; - -class EmptyPage extends StatelessWidget { - final String msg; - const EmptyPage({super.key, required this.msg}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Scaffold( - appBar: PreferredSize( - preferredSize: Size.fromHeight(46), - child: Row( - children: [ - const SizedBox(width: 20,), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - ), - Spacer(), - const WindowButtons() - ], - ), - ), - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - msg, - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ElevatedButton(onPressed: (){ - context.go('/'); - }, child: Text('返回首页')) - ], - ), - ), - ), - ); - } -} - diff --git a/lib/v12/pages/login/login.dart b/lib/v12/pages/login/login.dart deleted file mode 100644 index b676b80..0000000 --- a/lib/v12/pages/login/login.dart +++ /dev/null @@ -1,178 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; - -import '../../../components/components.dart'; -import '../../app/authentication/auth_scope.dart'; -import 'login_button.dart'; - -class LoginPage extends StatefulWidget { - const LoginPage({super.key}); - - @override - State createState() => _LoginPageState(); -} - -class _LoginPageState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: const PreferredSize( - preferredSize: Size.fromHeight(46), - child: DragToMoveWrap( - child: Row( - children: [ - SizedBox( - width: 20, - ), - Text( - '欢迎登录', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), - ), - Spacer(), - WindowButtons() - ], - ), - ), - ), - body: Center( - child: SizedBox( - width: 360, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'Login Page', - style: TextStyle(fontSize: 24), - ), - const SizedBox( - height: 20, - ), - buildUsernameInput(), - Stack( - alignment: const Alignment(.8, 0), - children: [ - buildPasswordInput(), - GestureDetector( - onTap: () => setState(() => _showPwd = !_showPwd), - child: Icon( - _showPwd ? Icons.remove_red_eye : Icons.hide_source)) - ], - ), - const SizedBox( - height: 20, - ), - LoginButton( - onLogin: () async { - String username = _usernameController.text; - String pwd = _passwordController.text; - (bool, String) result = await AuthScope.read(context).login(username, pwd); - if (result.$1) { - context.go('/'); - }else{ - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - backgroundColor: Colors.redAccent, - content: Text(result.$2))); - } - }, - ) - ], - ), - ), - ), - ); - } - - final _usernameController = TextEditingController(text: '张风捷特烈'); - - final _passwordController = TextEditingController(text: '111111'); - - Widget buildUsernameInput() { - return Column( - children: [ - Container( - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.withOpacity(0.5), - width: 1.0, - ), - borderRadius: BorderRadius.circular(15.0), - ), - margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0), - child: Row( - children: [ - const Padding( - padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0), - child: Icon( - Icons.person_outline, - color: Colors.grey, - ), - ), - Container( - height: 20.0, - width: 1.0, - color: Colors.grey.withOpacity(0.5), - margin: const EdgeInsets.only(left: 00.0, right: 10.0), - ), - Expanded( - child: TextField( - controller: _usernameController, - decoration: const InputDecoration( - border: InputBorder.none, - hintText: '请输入用户名...', - hintStyle: TextStyle(color: Colors.grey), - ), - ), - ) - ], - ), - ) - ], - ); - } - - bool _showPwd = false; - Widget buildPasswordInput() { - return Column( - children: [ - Container( - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.withOpacity(0.5), - width: 1.0, - ), - borderRadius: BorderRadius.circular(15.0), - ), - margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0), - child: Row( - children: [ - const Padding( - padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0), - child: Icon( - Icons.lock_outline, - color: Colors.grey, - ), - ), - Container( - height: 30.0, - width: 1.0, - color: Colors.grey.withOpacity(0.5), - margin: const EdgeInsets.only(left: 00.0, right: 10.0), - ), - Expanded( - child: TextField( - obscureText: !_showPwd, - controller: _passwordController, - decoration: const InputDecoration( - border: InputBorder.none, - hintText: '请输入密码...', - hintStyle: TextStyle(color: Colors.grey), - ), - ), - ) - ], - ), - ) - ], - ); - } -} diff --git a/lib/v12/pages/login/login_button.dart b/lib/v12/pages/login/login_button.dart deleted file mode 100644 index d011f01..0000000 --- a/lib/v12/pages/login/login_button.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import '../../app/authentication/auth_scope.dart'; - -class LoginButton extends StatelessWidget { - final VoidCallback onLogin; - const LoginButton({super.key, required this.onLogin}); - - @override - Widget build(BuildContext context) { - const TextStyle style = TextStyle(fontSize: 16, fontWeight: FontWeight.bold); - AuthResult authResult = AuthScope.of(context); - VoidCallback? action; - Widget child; - switch (authResult.status) { - case AuthStatus.none: - case AuthStatus.success: - case AuthStatus.failed: - case AuthStatus.waitingLoginOut: - action = onLogin; - child = const Text('登 录', style: style); - break; - case AuthStatus.waitingLogin: - action = null; - child = const Wrap( - spacing: 8, - children: [ - CupertinoActivityIndicator(radius: 10), - Text('登录中...', style: style) - ], - ); - } - - return ElevatedButton( - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), minimumSize: const Size(320, 52)), - onPressed: action, - child: child); - } -} diff --git a/lib/v12/pages/login/logout_button.dart b/lib/v12/pages/login/logout_button.dart deleted file mode 100644 index 8cef75f..0000000 --- a/lib/v12/pages/login/logout_button.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/v12/app/authentication/auth_scope.dart'; - -class LogoutButton extends StatelessWidget { - final VoidCallback onLogout; - const LogoutButton({super.key, required this.onLogout}); - - @override - Widget build(BuildContext context) { - AuthResult authResult = AuthScope.of(context); - VoidCallback? action = onLogout; - Widget child = const Icon(Icons.logout,size: 20,); - switch (authResult.status) { - case AuthStatus.none: - case AuthStatus.success: - case AuthStatus.failed: - case AuthStatus.waitingLogin: - break; - case AuthStatus.waitingLoginOut: - action = null; - child = CupertinoActivityIndicator(radius: 10,); - } - - return IconButton( - splashRadius: 20, - onPressed: action, - tooltip: '退出登录', - icon: child, - ); - } -} diff --git a/lib/v12/pages/settings/settings_page.dart b/lib/v12/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v12/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v12/pages/sort/functions.dart b/lib/v12/pages/sort/functions.dart deleted file mode 100644 index 6ae1176..0000000 --- a/lib/v12/pages/sort/functions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'functions/bubble.dart'; -import 'functions/cocktail.dart'; -import 'functions/comb.dart'; -import 'functions/cycle.dart'; -import 'functions/gnome.dart'; -import 'functions/heap.dart'; -import 'functions/insertion.dart'; -import 'functions/merage.dart'; -import 'functions/pigeonHole.dart'; -import 'functions/quick.dart'; -import 'functions/selection.dart'; -import 'functions/shell.dart'; - -typedef SortFunction = Future Function(List src, SortCallback callback); -typedef SortCallback = Future Function(List dist); - -Map sortFunctionMap = { - 'insertion': insertionSort, - 'bubble': bubbleSort, - 'cocktail': cocktailSort, - 'comb': combSort, - 'pigeonHole': pigeonHoleSort, - 'shell': shellSort, - 'selection': selectionSort, - 'gnome': gnomeSort, - 'cycle': cycleSort, - 'heap': heapSort, - 'quick': quickSort, - 'mergeSort': mergeSort, -}; - -Map sortNameMap = { - 'insertion': '插入排序', - 'bubble': '冒泡排序', - 'cocktail': '鸡尾酒排序(双向冒泡排序)', - 'comb': '梳排序', - 'pigeonHole': '鸽巢排序', - 'shell': '希尔排序', - 'selection': '选择排序', - 'gnome': '侏儒排序', - 'cycle': '循环排序', - 'heap': '堆排序', - 'quick': '快速排序', - 'mergeSort': '归并排序', -}; - diff --git a/lib/v12/pages/sort/functions/bubble.dart b/lib/v12/pages/sort/functions/bubble.dart deleted file mode 100644 index 3cf3c99..0000000 --- a/lib/v12/pages/sort/functions/bubble.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///冒泡排序 -Future bubbleSort(List src, SortCallback callback ) async{ - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < src.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < src.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (src[j] > src[j + 1]) { - int temp = src[j]; - src[j] = src[j + 1]; - src[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/cocktail.dart b/lib/v12/pages/sort/functions/cocktail.dart deleted file mode 100644 index 8c2d18c..0000000 --- a/lib/v12/pages/sort/functions/cocktail.dart +++ /dev/null @@ -1,52 +0,0 @@ -import '../functions.dart'; - -///鸡尾酒排序(双向冒泡排序) -Future cocktailSort(List src, SortCallback callback ) async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = src.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/comb.dart b/lib/v12/pages/sort/functions/comb.dart deleted file mode 100644 index 821f4a9..0000000 --- a/lib/v12/pages/sort/functions/comb.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '../functions.dart'; - -///梳排序(Comb Sort) -Future combSort(List src, SortCallback callback) async{ - int gap = src.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < src.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (src[i] > src[i + gap]) { - int temp = src[i]; - src[i] = src[i + gap]; - src[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await callback(src); - } - } -} - -int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/cycle.dart b/lib/v12/pages/sort/functions/cycle.dart deleted file mode 100644 index 4bef6eb..0000000 --- a/lib/v12/pages/sort/functions/cycle.dart +++ /dev/null @@ -1,54 +0,0 @@ -import '../functions.dart'; - -///循环排序 -Future cycleSort(List src, SortCallback callback) async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) { - int item = src[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (item != src[pos]) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/gnome.dart b/lib/v12/pages/sort/functions/gnome.dart deleted file mode 100644 index 5e08fc3..0000000 --- a/lib/v12/pages/sort/functions/gnome.dart +++ /dev/null @@ -1,22 +0,0 @@ -import '../functions.dart'; - -///地精排序 (侏儒排序) -Future gnomeSort(List src, SortCallback callback) async { - int index = 0; - while (index < src.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (src[index] >= src[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = src[index]; - src[index] = src[index - 1]; - src[index - 1] = temp; - index--; - } - await callback(src); - } - return; -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/heap.dart b/lib/v12/pages/sort/functions/heap.dart deleted file mode 100644 index 9f5410b..0000000 --- a/lib/v12/pages/sort/functions/heap.dart +++ /dev/null @@ -1,38 +0,0 @@ -import '../functions.dart'; - -///堆排序 -Future heapSort(List src, SortCallback callback) async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = src.length ~/ 2; i >= 0; i--) { - await heapify(src,callback, src.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = src.length - 1; i >= 0; i--) { - int temp = src[0]; - src[0] = src[i]; - src[i] = temp; - await heapify(src, callback,i, 0); - } -} - -Future heapify(List src, SortCallback callback, int n, int i) async{ - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && src[l] > src[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && src[r] > src[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = src[i]; - src[i] = src[largest]; - src[largest] = temp; - heapify(src,callback, n, largest); - } - await callback(src); -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/insertion.dart b/lib/v12/pages/sort/functions/insertion.dart deleted file mode 100644 index b1c7814..0000000 --- a/lib/v12/pages/sort/functions/insertion.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///插入排序 -Future insertionSort(List src, SortCallback callback) async { - for (int i = 1; i < src.length; i++) { - int temp = src[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < src[j]) { - src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - // 更新排序结果回调 - await callback(src); - } - src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await callback(src); - } -} diff --git a/lib/v12/pages/sort/functions/merage.dart b/lib/v12/pages/sort/functions/merage.dart deleted file mode 100644 index 12135b4..0000000 --- a/lib/v12/pages/sort/functions/merage.dart +++ /dev/null @@ -1,79 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future mergeSort(List src, SortCallback callback) async { - await _mergeSort(src,callback,0,src.length-1); -} - -///归并排序 -Future _mergeSort(List src, SortCallback callback,int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = src[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = src[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - src[k] = leftList[i]; - i++; - } else { - src[k] = rightList[j]; - j++; - } - - await callback(src); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - src[k] = leftList[i]; - i++; - k++; - - await callback(src); - } - - while (j < rightSize) { - src[k] = rightList[j]; - j++; - k++; - - await callback(src); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await _mergeSort(src,callback,leftIndex, middleIndex); - await _mergeSort(src,callback,middleIndex + 1, rightIndex); - - await callback(src); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/oddEven.dart b/lib/v12/pages/sort/functions/oddEven.dart deleted file mode 100644 index bd6f548..0000000 --- a/lib/v12/pages/sort/functions/oddEven.dart +++ /dev/null @@ -1,37 +0,0 @@ -import '../functions.dart'; - -///奇偶排序(Odd-Even Sort) -Future oddEvenSort(List src, SortCallback callback) async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= src.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await callback(src); - } - } - - for (int i = 0; i <= src.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; - await callback(src); - } - } - } - - return; -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/pigeonHole.dart b/lib/v12/pages/sort/functions/pigeonHole.dart deleted file mode 100644 index 83bbce1..0000000 --- a/lib/v12/pages/sort/functions/pigeonHole.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../functions.dart'; - -///鸽巢排序 -Future pigeonHoleSort(List src, SortCallback callback ) async{ - int min = src[0]; - int max = src[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < src.length; a++) { - if (src[a] > max) max = src[a]; - if (src[a] < min) min = src[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < src.length; i++) { - p[src[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - src[index++] = j + min; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/quick.dart b/lib/v12/pages/sort/functions/quick.dart deleted file mode 100644 index 25b9685..0000000 --- a/lib/v12/pages/sort/functions/quick.dart +++ /dev/null @@ -1,65 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future quickSort(List src, SortCallback callback) async { - await _quickSort(src,callback,0,src.length-1); -} - -///快速排序 -Future _quickSort(List src, SortCallback callback,int leftIndex,int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = src[p]; - src[p] = src[right]; - src[right] = temp; - await callback(src); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(src[i], src[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = src[i]; - src[i] = src[cursor]; - src[cursor] = temp; - cursor++; - await callback(src); - } - } - - // 将基准元素放置在游标位置 - temp = src[right]; - src[right] = src[cursor]; - src[cursor] = temp; - - await callback(src); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } -} - -// 比较函数,用于判断两个元素的大小关系 -cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/selection.dart b/lib/v12/pages/sort/functions/selection.dart deleted file mode 100644 index 185dae2..0000000 --- a/lib/v12/pages/sort/functions/selection.dart +++ /dev/null @@ -1,18 +0,0 @@ -import '../functions.dart'; - -///选择排序 -Future selectionSort(List src, SortCallback callback ) async { - for (int i = 0; i < src.length; i++) { - for (int j = i + 1; j < src.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (src[i] > src[j]) { - // 判断当前元素是否比后续元素小 - int temp = src[j]; - // 交换当前元素和后续较小的元素 - src[j] = src[i]; - src[i] = temp; - } - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/functions/shell.dart b/lib/v12/pages/sort/functions/shell.dart deleted file mode 100644 index 232f872..0000000 --- a/lib/v12/pages/sort/functions/shell.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../functions.dart'; - -///希尔排序 -Future shellSort(List src, SortCallback callback) async{ - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < src.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = src[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && src[j - gap] > temp; j -= gap) { - src[j] = src[j - gap]; - } - src[j] = temp; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/provider/sort_config.dart b/lib/v12/pages/sort/provider/sort_config.dart deleted file mode 100644 index 1fc3790..0000000 --- a/lib/v12/pages/sort/provider/sort_config.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -class SortConfig { - final int count; - 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, - }) => - SortConfig( - count:count??this.count, - seed:seed??this.seed, - duration:duration??this.duration, - name:name??this.name, - colorIndex:colorIndex??this.colorIndex, - ); -} - diff --git a/lib/v12/pages/sort/provider/state.dart b/lib/v12/pages/sort/provider/state.dart deleted file mode 100644 index b594b1e..0000000 --- a/lib/v12/pages/sort/provider/state.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -import '../functions.dart'; -import 'sort_config.dart'; - -enum SortStatus{ - none, // 未操作 - sorting, // 排序中 - sorted, // 排序完成 -} - -List 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(){ - reset(); - } - - SortStatus status = SortStatus.none; - - List data = []; - List stepData = []; - - SortConfig _config = SortConfig(); - SortConfig get config => _config; - Random random = Random(); - - set config(SortConfig config){ - _config = config; - reset(); - notifyListeners(); - } - - void selectName(String name){ - if(name==config.name) return; - 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; - notifyListeners(); - int count = config.count; - if(config.seed!=-1){ - random = Random(config.seed); - } - for (int i = 0; i < count; i++) { - //随机往数组中填值 - data.add(random.nextInt(1000)); - } - } - - void sort() async{ - status = SortStatus.sorting; - notifyListeners(); - Stopwatch stopwatch = Stopwatch()..start(); - SortFunction? sortFunction = sortFunctionMap[config.name]; - if(sortFunction!=null){ - await sortFunction(data,(arr) async { - await Future.delayed(config.duration); - notifyListeners(); - }); - } - status = SortStatus.sorted; - notifyListeners(); - stopwatch.stop(); - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - } -} - -/// Provides the current [SortState] to descendant widgets in the tree. -class SortStateScope extends InheritedNotifier { - const SortStateScope({ - required super.notifier, - required super.child, - super.key, - }); - - static SortState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; - - static SortState read(BuildContext context) { - return context.getInheritedWidgetOfExactType()!.notifier!; - } -} \ No newline at end of file diff --git a/lib/v12/pages/sort/views/code_page/code_page.dart b/lib/v12/pages/sort/views/code_page/code_page.dart deleted file mode 100644 index 7d8d4c9..0000000 --- a/lib/v12/pages/sort/views/code_page/code_page.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class CodePage extends StatelessWidget { - const CodePage({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - leading: BackButton(), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - centerTitle: true, - title: Text(sortNameMap[state.config.name]!+'代码实现'), - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text('代码'*1000), - )); - } -} diff --git a/lib/v12/pages/sort/views/player/data_painter.dart b/lib/v12/pages/sort/views/player/data_painter.dart deleted file mode 100644 index 392a9e8..0000000 --- a/lib/v12/pages/sort/views/player/data_painter.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; - - - -class DataPainter extends CustomPainter{ - - final List data; - final MaterialColor color; - - DataPainter( {required this.data,required this.color,}); - - @override - void paint(Canvas canvas, Size size) { - double itemWidth = size.width/data.length; - double height = size.height; - - Paint paint = Paint(); - paint.strokeWidth = itemWidth; - paint.strokeCap = StrokeCap.round; - - - for(int i=0;i 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()), - ), - ); - } -} diff --git a/lib/v12/pages/sort/views/settings/color_picker.dart b/lib/v12/pages/sort/views/settings/color_picker.dart deleted file mode 100644 index b0bb469..0000000 --- a/lib/v12/pages/sort/views/settings/color_picker.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorPicker extends StatelessWidget { - final List colors; - final ValueChanged 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(), - ); - } -} diff --git a/lib/v12/pages/sort/views/settings/sort_setting.dart b/lib/v12/pages/sort/views/settings/sort_setting.dart deleted file mode 100644 index fe86289..0000000 --- a/lib/v12/pages/sort/views/settings/sort_setting.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import '../../provider/state.dart'; -import 'color_picker.dart'; -class SortSettings extends StatefulWidget { - - const SortSettings({super.key,}); - - @override - State createState() => _SortSettingsState(); -} - -class _SortSettingsState extends State { - 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, - automaticallyImplyLeading: false, - // 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.read(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 - ); - GoRouter.of(context).pop(); - // 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('确定设置')) - ], - ), - ), - ); - } -} diff --git a/lib/v12/pages/sort/views/sort_page/sort_button.dart b/lib/v12/pages/sort/views/sort_page/sort_button.dart deleted file mode 100644 index 93df9d9..0000000 --- a/lib/v12/pages/sort/views/sort_page/sort_button.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../provider/state.dart'; - -class SortButton extends StatelessWidget { - const SortButton({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - VoidCallback? action; - IconData icon; - String text = ''; - Color color; - switch (state.status) { - case SortStatus.none: - icon = Icons.not_started_outlined; - color = Colors.green; - action = state.sort; - text = '点击启动'; - break; - case SortStatus.sorting: - icon = Icons.stop_circle_outlined; - color = Colors.grey; - action = null; - text = '排序中...'; - break; - case SortStatus.sorted: - icon = CupertinoIcons.repeat; - color = Colors.black; - action = state.reset; - text = '点击重置'; - break; - } - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: action, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon( - icon, - color: color, - size: 18, - ), - const SizedBox(width: 4,), - Text(text,style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold,color: color),), - ], - ), - ), - ); - } -} diff --git a/lib/v12/pages/sort/views/sort_page/sort_page.dart b/lib/v12/pages/sort/views/sort_page/sort_page.dart deleted file mode 100644 index 6631bff..0000000 --- a/lib/v12/pages/sort/views/sort_page/sort_page.dart +++ /dev/null @@ -1,166 +0,0 @@ - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'sort_button.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class SortNavigation extends StatelessWidget { - final Widget navigator; - const SortNavigation({super.key, required this.navigator}); - - @override - Widget build(BuildContext context) { - return Material( - child: Row( - children: [ - SizedBox( - width: 220, - child: SortRailPanel(), - ), - VerticalDivider( - width: 1, - ), - Expanded( - child: navigator, - ) - ], - ), - ); - } -} - -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: () { - GoRouter.of(context).push('/sort/settings'); - // router.changePath('/app/sort/settings',style: RouteStyle.push); - }, - 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); - GoRouter.of(context).go('/sort/player/$name'); - }, - ), - ), - ], - ); - } -} - -class SortSelectorPanel extends StatelessWidget { - final String active; - final ValueChanged onSelected; - final List 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 createState() => _SortItemTileState(); -} - -class _SortItemTileState extends State { - @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), - ), - ), - ), - ), - ); - } -} diff --git a/lib/v12/pages/user/user_page.dart b/lib/v12/pages/user/user_page.dart deleted file mode 100644 index e6cfbec..0000000 --- a/lib/v12/pages/user/user_page.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:iroute/v12/app/authentication/auth_scope.dart'; - -import '../login/logout_button.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - String? name = AuthScope.of(context).name; - int? coin = AuthScope.of(context).coin; - return Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 18.0,vertical: 12), - child: Row( - children: [ - CircleAvatar( - child: FlutterLogo(), - ), - const SizedBox(width: 12,), - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('$name',style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),), - const SizedBox(height: 4,), - Text('金币: ${coin}',style: TextStyle(fontSize: 12,color: Colors.grey,),) - ], - ), - Spacer(), - LogoutButton( - onLogout: () async { - bool success = await AuthScope.of(context).logout(); - if(success){ - context.go('/'); - } - }, - ) - ], - ), - ) - ); - } -} diff --git a/lib/v2/app.dart b/lib/v2/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v2/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v2/app/navigation/app_router_delegate.dart b/lib/v2/app/navigation/app_router_delegate.dart deleted file mode 100644 index 80d87d0..0000000 --- a/lib/v2/app/navigation/app_router_delegate.dart +++ /dev/null @@ -1,185 +0,0 @@ -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/user/user_page.dart'; -import '../../transition/fade_transition_page.dart'; -import '../../pages/color/color_add_page.dart'; - -const List kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate 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> _completerMap = {}; - - Completer? completer; - - Future changePathForResult(String value) async{ - Completer completer = Completer(); - _completerMap[value] = completer; - path = value; - return completer.future; - } - - set path(String value) { - if (_path == value) return; - _path = value; - notifyListeners(); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPageByPath(path), - ); - } - - List _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 UserPage(); - } - if (path == kDestinationsPaths[3]) { - child = const SettingPage(); - } - return [ - FadeTransitionPage( - // key: ValueKey(path), - child: child ?? const EmptyPage(), - ) - ]; - } - - List buildColorPages(String path){ - List 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 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 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 parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} - - - -// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { -// -// List _value = ['/']; -// -// -// List get value => _value; -// -// set value(List value){ -// _value = value; -// notifyListeners(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Navigator( -// onPopPage: _onPopPage, -// pages: _value.map((e) => _pageMap[e]!).toList(), -// ); -// } -// -// final Map _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? navigatorKey = GlobalKey(); -// -// @override -// Future setNewRoutePath(String configuration) async{ -// } -// } diff --git a/lib/v2/app/navigation/router/iroute.dart b/lib/v2/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/v2/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/v2/app/navigation/views/app_navigation_rail.dart b/lib/v2/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 2899ea2..0000000 --- a/lib/v2/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:flutter/material.dart'; -import '../app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List 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 NavigationRail( - labelType: NavigationRailLabelType.all, - onDestinationSelected: _onDestinationSelected, - destinations: destinations, - selectedIndex: router.activeIndex, - ); - } - - void _onDestinationSelected(int index) { - router.path = kDestinationsPaths[index]; - } - - void _onRouterChange() { - setState(() { - - }); - } -} \ No newline at end of file diff --git a/lib/v2/app/unit_app.dart b/lib/v2/app/unit_app.dart deleted file mode 100644 index 5332b5d..0000000 --- a/lib/v2/app/unit_app.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/app_router_delegate.dart'; -import 'navigation/views/app_navigation_rail.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - )); - } -} - - diff --git a/lib/v2/pages/color/color_add_page.dart b/lib/v2/pages/color/color_add_page.dart deleted file mode 100644 index b3cf660..0000000 --- a/lib/v2/pages/color/color_add_page.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - void _selectColor() { - Navigator.of(context).pop(_color); - } - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v2/pages/color/color_detail_page.dart b/lib/v2/pages/color/color_detail_page.dart deleted file mode 100644 index 2f9c93e..0000000 --- a/lib/v2/pages/color/color_detail_page.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - appBar: AppBar( - systemOverlayStyle: SystemUiOverlayStyle( - statusBarColor: Colors.transparent, - statusBarIconBrightness: Brightness.light - ), - iconTheme: IconThemeData(color: Colors.white), - titleTextStyle:TextStyle(color: Colors.white,fontSize: 18) , - backgroundColor: color, - title: Text('颜色界面',),), - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v2/pages/color/color_page.dart b/lib/v2/pages/color/color_page.dart deleted file mode 100644 index 1419c09..0000000 --- a/lib/v2/pages/color/color_page.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ); - } - - void _selectColor(Color color){ - String value = color.value.toRadixString(16); - router.path = '/color/detail?color=$value'; - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v2/pages/counter/counter_page.dart b/lib/v2/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v2/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v2/pages/empty/empty_page.dart b/lib/v2/pages/empty/empty_page.dart deleted file mode 100644 index e9064a8..0000000 --- a/lib/v2/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('界面走丢了'), - ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v2/pages/settings/settings_page.dart b/lib/v2/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v2/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v2/pages/user/user_page.dart b/lib/v2/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v2/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v2/transition/fade_transition_page.dart b/lib/v2/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v2/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v2/transition/no_transition_page.dart b/lib/v2/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v2/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v3/app.dart b/lib/v3/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v3/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v3/app/navigation/router/app_router_delegate.dart b/lib/v3/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index 6871956..0000000 --- a/lib/v3/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,207 +0,0 @@ -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 kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate 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> _completerMap = {}; - - Completer? completer; - - Future changePathForResult(String value) async{ - Completer 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 parts = path.split('/'); - // String lever1 = '/${parts[1]}'; - // List iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList(); - // - // int counter = 2; - // - // IRoute? result; - // String check = lever1; - // for(int i = 0;i _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 buildColorPages(String path){ - List 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 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 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 parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} - - - -// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { -// -// List _value = ['/']; -// -// -// List get value => _value; -// -// set value(List value){ -// _value = value; -// notifyListeners(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Navigator( -// onPopPage: _onPopPage, -// pages: _value.map((e) => _pageMap[e]!).toList(), -// ); -// } -// -// final Map _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? navigatorKey = GlobalKey(); -// -// @override -// Future setNewRoutePath(String configuration) async{ -// } -// } diff --git a/lib/v3/app/navigation/router/iroute.dart b/lib/v3/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/v3/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/v3/app/navigation/transition/fade_transition_page.dart b/lib/v3/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v3/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v3/app/navigation/transition/no_transition_page.dart b/lib/v3/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v3/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v3/app/navigation/views/app_navigation.dart b/lib/v3/app/navigation/views/app_navigation.dart deleted file mode 100644 index adcab6c..0000000 --- a/lib/v3/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v3/app/navigation/views/app_navigation_rail.dart b/lib/v3/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 13a88ed..0000000 --- a/lib/v3/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined), - MenuMeta(label: '计数器', icon: Icons.add_chart), - MenuMeta(label: '我的', icon: Icons.person), - MenuMeta(label: '设置', icon: Icons.settings), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: router.activeIndex, - ), - ); - - } - - void _onDestinationSelected(int index) { - router.path = kDestinationsPaths[index]; - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v3/app/navigation/views/app_top_bar.dart b/lib/v3/app/navigation/views/app_top_bar.dart deleted file mode 100644 index f98e9b5..0000000 --- a/lib/v3/app/navigation/views/app_top_bar.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: const Row( - children: [ - Expanded(child: SizedBox()), - WindowButtons() - ], - ), - ), - ); - } -} - diff --git a/lib/v3/app/unit_app.dart b/lib/v3/app/unit_app.dart deleted file mode 100644 index 2f98d26..0000000 --- a/lib/v3/app/unit_app.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/views/app_navigation.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - scaffoldBackgroundColor: Colors.white, - fontFamily: "宋体", - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation()); - } -} - - diff --git a/lib/v3/pages/color/color_add_page.dart b/lib/v3/pages/color/color_add_page.dart deleted file mode 100644 index c6ca0cd..0000000 --- a/lib/v3/pages/color/color_add_page.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - void _selectColor() { - Navigator.of(context).pop(_color); - } - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v3/pages/color/color_detail_page.dart b/lib/v3/pages/color/color_detail_page.dart deleted file mode 100644 index 17fcd17..0000000 --- a/lib/v3/pages/color/color_detail_page.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - // appBar: AppBar( - // systemOverlayStyle: SystemUiOverlayStyle( - // statusBarColor: Colors.transparent, - // statusBarIconBrightness: Brightness.light - // ), - // iconTheme: IconThemeData(color: Colors.white), - // titleTextStyle:TextStyle(color: Colors.white,fontSize: 18) , - // backgroundColor: color, - // title: Text('颜色界面',),), - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v3/pages/color/color_navigation.dart b/lib/v3/pages/color/color_navigation.dart deleted file mode 100644 index 7d69e78..0000000 --- a/lib/v3/pages/color/color_navigation.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorNavigation extends StatelessWidget { - const ColorNavigation({super.key}); - - @override - Widget build(BuildContext context) { - return Navigator( - pages: [], - ); - } -} diff --git a/lib/v3/pages/color/color_page.dart b/lib/v3/pages/color/color_page.dart deleted file mode 100644 index 213165b..0000000 --- a/lib/v3/pages/color/color_page.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - String value = color.value.toRadixString(16); - router.path = '/color/detail?color=$value'; - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v3/pages/counter/counter_page.dart b/lib/v3/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v3/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v3/pages/empty/empty_page.dart b/lib/v3/pages/empty/empty_page.dart deleted file mode 100644 index e9064a8..0000000 --- a/lib/v3/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('界面走丢了'), - ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v3/pages/settings/settings_page.dart b/lib/v3/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v3/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v3/pages/sort/sort_page.dart b/lib/v3/pages/sort/sort_page.dart deleted file mode 100644 index 8172cc0..0000000 --- a/lib/v3/pages/sort/sort_page.dart +++ /dev/null @@ -1,859 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; - -class SortPage extends StatefulWidget { - const SortPage({Key? key}) : super(key: key); - - @override - State createState() => _SortPageState(); -} - -class _SortPageState extends State { - //存放随机数组 - List numbers = []; - - //订阅流 - StreamController> streamController = StreamController(); - String currentSort = 'bubble'; - - //柱子的数量 -> 生成排序数组的长度 - double sampleSize = 0; - - //是否排序 - bool isSorted = false; - - //是否在排序中 - bool isSorting = false; - - //排序动画更新的速度 - int speed = 0; - - static int duration = 1500; - - String getTitle() { - switch (currentSort) { - case "bubble": - return "Bubble Sort"; - case "coctail": - return "Coctail Sort"; - case "comb": - return "Comb Sort"; - case "pigeonhole": - return "Pigeonhole Sort"; - case "shell": - return "Shell Sort"; - case "selection": - return "Selection Sort"; - case "cycle": - return "Cycle Sort"; - case "heap": - return "Heap Sort"; - case "insertion": - return "Insertion Sort"; - case "gnome": - return "Gnome Sort"; - case "oddeven": - return "OddEven Sort"; - case "quick": - return "Quick Sort"; - case "merge": - return "Merge Sort"; - } - return ""; - } - - reset() { - isSorted = false; - numbers = []; - for (int i = 0; i < sampleSize; ++i) { - numbers.add(Random().nextInt(500)); - } - streamController.add(numbers); - } - - Duration getDuration() { - return Duration(microseconds: duration); - } - - ///动画时间 - changeSpeed() { - if (speed >= 3) { - speed = 0; - duration = 1500; - } else { - speed++; - duration = duration ~/ 2; - } - setState(() {}); - } - - ///冒泡排序 - bubbleSort() async { - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < numbers.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < numbers.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (numbers[j] > numbers[j + 1]) { - int temp = numbers[j]; - numbers[j] = numbers[j + 1]; - numbers[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); - } - } - } - - ///鸡尾酒排序(双向冒泡排序) - cocktailSort() async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = numbers.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } - } - - ///梳排序(Comb Sort) - combSort() async { - int gap = numbers.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < numbers.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (numbers[i] > numbers[i + gap]) { - int temp = numbers[i]; - numbers[i] = numbers[i + gap]; - numbers[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; - } - - ///鸽巢排序 - pigeonHole() async { - int min = numbers[0]; - int max = numbers[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < numbers.length; a++) { - if (numbers[a] > max) max = numbers[a]; - if (numbers[a] < min) min = numbers[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < numbers.length; i++) { - p[numbers[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - numbers[index++] = j + min; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///希尔排序 - shellSort() async { - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = numbers.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < numbers.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = numbers[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && numbers[j - gap] > temp; j -= gap) { - numbers[j] = numbers[j - gap]; - } - numbers[j] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///选择排序 - selectionSort() async { - for (int i = 0; i < numbers.length; i++) { - for (int j = i + 1; j < numbers.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (numbers[i] > numbers[j]) { - // 判断当前元素是否比后续元素小 - int temp = numbers[j]; - // 交换当前元素和后续较小的元素 - numbers[j] = numbers[i]; - numbers[i] = temp; - } - - await Future.delayed(getDuration(), () {}); - - streamController.add(numbers); - } - } - } - - ///循环排序 - cycleSort() async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= numbers.length - 2; cycleStart++) { - int item = numbers[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (item != numbers[pos]) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///堆排序 - heapSort() async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = numbers.length ~/ 2; i >= 0; i--) { - await heapify(numbers, numbers.length, i); - streamController.add(numbers); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = numbers.length - 1; i >= 0; i--) { - int temp = numbers[0]; - numbers[0] = numbers[i]; - numbers[i] = temp; - await heapify(numbers, i, 0); - streamController.add(numbers); - } - } - - heapify(List arr, int n, int i) async { - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && arr[l] > arr[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && arr[r] > arr[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = numbers[i]; - numbers[i] = numbers[largest]; - numbers[largest] = temp; - heapify(arr, n, largest); - } - - await Future.delayed(getDuration()); // 延迟操作,用于可视化排序过程 - } - - ///插入排序 - insertionSort() async { - for (int i = 1; i < numbers.length; i++) { - int temp = numbers[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < numbers[j]) { - numbers[j + 1] = numbers[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - await Future.delayed(getDuration()); - streamController.add(numbers); // 更新排序结果 - } - - numbers[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); // 更新排序结果 - } - } - - ///地精排序 (侏儒排序) - gnomeSort() async { - int index = 0; - - while (index < numbers.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (numbers[index] >= numbers[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = numbers[index]; - numbers[index] = numbers[index - 1]; - numbers[index - 1] = temp; - index--; - } - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - return; - } - - ///奇偶排序(Odd-Even Sort) - oddEvenSort() async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= numbers.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - for (int i = 0; i <= numbers.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - return; - } - - ///快速排序 - quickSort(int leftIndex, int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = numbers[p]; - numbers[p] = numbers[right]; - numbers[right] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(numbers[i], numbers[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = numbers[i]; - numbers[i] = numbers[cursor]; - numbers[cursor] = temp; - cursor++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 将基准元素放置在游标位置 - temp = numbers[right]; - numbers[right] = numbers[cursor]; - numbers[cursor] = temp; - - await Future.delayed(getDuration()); - streamController.add(numbers); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await quickSort(leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await quickSort(p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } - } - - // 比较函数,用于判断两个元素的大小关系 - cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } - } - - ///归并排序 - mergeSort(int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = numbers[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = numbers[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - numbers[k] = leftList[i]; - i++; - } else { - numbers[k] = rightList[j]; - j++; - } - - await Future.delayed(getDuration()); - streamController.add(numbers); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - numbers[k] = leftList[i]; - i++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - while (j < rightSize) { - numbers[k] = rightList[j]; - j++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await mergeSort(leftIndex, middleIndex); - await mergeSort(middleIndex + 1, rightIndex); - - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } - } - - checkAndResetIfSorted() async { - if (isSorted) { - reset(); - await Future.delayed(const Duration(milliseconds: 200)); - } - } - - sort() async { - setState(() { - isSorting = true; - }); - - await checkAndResetIfSorted(); - - Stopwatch stopwatch = Stopwatch()..start(); - - switch (currentSort) { - case "bubble": - await bubbleSort(); - break; - case "coctail": - await cocktailSort(); - break; - case "comb": - await combSort(); - break; - case "pigeonhole": - await pigeonHole(); - break; - case "shell": - await shellSort(); - break; - case "selection": - await selectionSort(); - break; - case "cycle": - await cycleSort(); - break; - case "heap": - await heapSort(); - break; - case "insertion": - await insertionSort(); - break; - case "gnome": - await gnomeSort(); - break; - case "oddeven": - await oddEvenSort(); - break; - case "quick": - await quickSort(0, sampleSize.toInt() - 1); - break; - case "merge": - await mergeSort(0, sampleSize.toInt() - 1); - break; - } - - stopwatch.stop(); - - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - setState(() { - isSorting = false; - isSorted = true; - }); - } - - setSort(String type) { - setState(() { - currentSort = type; - }); - } - - @override - void initState() { - super.initState(); - // reset(); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - sampleSize = MediaQuery.of(context).size.width / 2; - for (int i = 0; i < sampleSize; ++i) { - //随机往数组中填值 - numbers.add(Random().nextInt(500)); - } - setState(() {}); - } - - @override - void dispose() { - streamController.close(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text( - "当前选择的是:${getTitle()}", - style: const TextStyle(fontSize: 14), - ), - actions: [ - PopupMenuButton( - initialValue: currentSort, - itemBuilder: (ctx) { - return const [ - PopupMenuItem( - value: 'bubble', - child: Text("Bubble Sort — 冒泡排序"), - ), - PopupMenuItem( - value: 'coctail', - child: Text("Coctail Sort — 鸡尾酒排序(双向冒泡排序)"), - ), - PopupMenuItem( - value: 'comb', - child: Text("Comb Sort — 梳排序"), - ), - PopupMenuItem( - value: 'pigeonhole', - child: Text("pigeonhole Sort — 鸽巢排序"), - ), - PopupMenuItem( - value: 'shell', - child: Text("shell Sort — 希尔排序"), - ), - PopupMenuItem( - value: 'selection', - child: Text("Selection Sort — 选择排序"), - ), - PopupMenuItem( - value: 'cycle', - child: Text("CycleSort — 循环排序"), - ), - PopupMenuItem( - value: 'heap', - child: Text("HeapSort — 堆排序"), - ), - PopupMenuItem( - value: 'insertion', - child: Text("InsertionSort — 插入排序"), - ), - PopupMenuItem( - value: 'gnome', - child: Text("GnomeSort — 地精排序 (侏儒排序)"), - ), - PopupMenuItem( - value: 'oddeven', - child: Text("OddEvenSort — 奇偶排序"), - ), - PopupMenuItem( - value: 'quick', - child: Text("QuickSort — 快速排序"), - ), - PopupMenuItem( - value: 'merge', - child: Text("MergeSort — 归并排序"), - ), - ]; - }, - onSelected: (String value) { - reset(); - setSort(value); - }, - ) - ], - ), - body: StreamBuilder( - initialData: numbers, - stream: streamController.stream, - builder: (context, snapshot) { - List numbers = snapshot.data as List; - int counter = 0; - return Row( - children: numbers.map((int num) { - counter++; - return CustomPaint( - painter: BarPainter( - width: MediaQuery.of(context).size.width / sampleSize, - value: num, - index: counter, - ), - ); - }).toList(), - ); - }, - ), - bottomNavigationBar: BottomAppBar( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: isSorting - ? null - : () { - reset(); - setSort(currentSort); - }, - child: const Text("重置")), - ElevatedButton( - onPressed: isSorting ? null : sort, child: const Text("开始排序")), - ElevatedButton( - onPressed: isSorting ? null : changeSpeed, - child: Text( - "${speed + 1}x", - style: const TextStyle(fontSize: 20), - ), - ), - ], - ), - ), - ); - } -} - -class BarPainter extends CustomPainter { - //宽度 - final double width; - - //高度(数组中对应的值) - final int value; - - //位置索引 - final int index; - - BarPainter({required this.width, required this.value, required this.index}); - - @override - void paint(Canvas canvas, Size size) { - Paint paint = Paint(); - if (value < 500 * .10) { - paint.color = Colors.blue.shade100; - } else if (value < 500 * .20) { - paint.color = Colors.blue.shade200; - } else if (value < 500 * .30) { - paint.color = Colors.blue.shade300; - } else if (value < 500 * .40) { - paint.color = Colors.blue.shade400; - } else if (value < 500 * .50) { - paint.color = Colors.blue.shade500; - } else if (value < 500 * .60) { - paint.color = Colors.blue.shade600; - } else if (value < 500 * .70) { - paint.color = Colors.blue.shade700; - } else if (value < 500 * .80) { - paint.color = Colors.blue.shade800; - } else if (value < 500 * .90) { - paint.color = Colors.blue.shade900; - } else { - paint.color = const Color(0xFF011E51); - } - - paint.strokeWidth = width; - paint.strokeCap = StrokeCap.round; - - canvas.drawLine( - Offset(index * width, 0), - Offset( - index * width, - value.ceilToDouble(), - ), - paint); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) { - return true; - } -} diff --git a/lib/v3/pages/user/user_page.dart b/lib/v3/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v3/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v4/app.dart b/lib/v4/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v4/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v4/app/navigation/router/app_router_delegate.dart b/lib/v4/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index 71f3820..0000000 --- a/lib/v4/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,201 +0,0 @@ -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 kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate 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> _completerMap = {}; - - Completer? completer; - - final Map _pathExtraMap = {}; - - void setPathForData(String value,dynamic data){ - _pathExtraMap[value] = data; - path = value; - } - - Future changePathForResult(String value) async{ - Completer completer = Completer(); - _completerMap[value] = completer; - path = value; - return completer.future; - } - - set path(String value) { - if (_path == value) return; - _path = value; - notifyListeners(); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPageByPath(path), - ); - } - - List _buildPageByPath(String path) { - Widget? child; - if(path.startsWith('/color')){ - return buildColorPages(path); - } - - 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 buildColorPages(String path){ - List 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 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), - )); - }else{ - Color? selectedColor = _pathExtraMap[path]; - if (selectedColor != null) { - result.add( FadeTransitionPage( - key: const ValueKey('/color/detail'), - child:ColorDetailPage(color: selectedColor), - )); - _pathExtraMap.remove(path); - } - } - } - if(segment == 'add'){ - result.add( const FadeTransitionPage( - key: ValueKey('/color/add'), - child:ColorAddPage(), - )); - } - - } - return result; - } - - @override - Future 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 parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} - - - -// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { -// -// List _value = ['/']; -// -// -// List get value => _value; -// -// set value(List value){ -// _value = value; -// notifyListeners(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Navigator( -// onPopPage: _onPopPage, -// pages: _value.map((e) => _pageMap[e]!).toList(), -// ); -// } -// -// final Map _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? navigatorKey = GlobalKey(); -// -// @override -// Future setNewRoutePath(String configuration) async{ -// } -// } diff --git a/lib/v4/app/navigation/router/iroute.dart b/lib/v4/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/v4/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/v4/app/navigation/transition/fade_transition_page.dart b/lib/v4/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v4/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v4/app/navigation/transition/no_transition_page.dart b/lib/v4/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v4/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v4/app/navigation/views/app_navigation.dart b/lib/v4/app/navigation/views/app_navigation.dart deleted file mode 100644 index adcab6c..0000000 --- a/lib/v4/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v4/app/navigation/views/app_navigation_rail.dart b/lib/v4/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index f1aaa61..0000000 --- a/lib/v4/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined), - MenuMeta(label: '计数器', icon: Icons.add_chart), - MenuMeta(label: '我的', icon: Icons.person), - MenuMeta(label: '设置', icon: Icons.settings), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text('V0.0.4',style: TextStyle(color: Colors.white,fontSize: 12),), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: router.activeIndex, - ), - ); - - } - - void _onDestinationSelected(int index) { - router.path = kDestinationsPaths[index]; - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v4/app/navigation/views/app_router_editor.dart b/lib/v4/app/navigation/views/app_router_editor.dart deleted file mode 100644 index 10d5701..0000000 --- a/lib/v4/app/navigation/views/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v4/app/navigation/views/app_top_bar.dart b/lib/v4/app/navigation/views/app_top_bar.dart deleted file mode 100644 index 1b95110..0000000 --- a/lib/v4/app/navigation/views/app_top_bar.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; -import 'app_router_editor.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.path = path, - )), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -Map kRouteLabelMap = { - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/user': '我的', - '/settings': '系统设置', -}; - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.path = item.to!; - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - return result; - } -} diff --git a/lib/v4/app/unit_app.dart b/lib/v4/app/unit_app.dart deleted file mode 100644 index 1a21114..0000000 --- a/lib/v4/app/unit_app.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/router/app_router_delegate.dart'; -import 'navigation/views/app_navigation.dart'; -import 'navigation/views/app_navigation_rail.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation() - ); - } -} - - diff --git a/lib/v4/pages/color/color_add_page.dart b/lib/v4/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v4/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v4/pages/color/color_detail_page.dart b/lib/v4/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v4/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v4/pages/color/color_page.dart b/lib/v4/pages/color/color_page.dart deleted file mode 100644 index e7b88da..0000000 --- a/lib/v4/pages/color/color_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.setPathForData('/color/detail',color); - - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v4/pages/counter/counter_page.dart b/lib/v4/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v4/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v4/pages/empty/empty_page.dart b/lib/v4/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v4/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v4/pages/settings/settings_page.dart b/lib/v4/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v4/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v4/pages/sort/sort_page.dart b/lib/v4/pages/sort/sort_page.dart deleted file mode 100644 index d440071..0000000 --- a/lib/v4/pages/sort/sort_page.dart +++ /dev/null @@ -1,859 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; - -class SortPage extends StatefulWidget { - const SortPage({Key? key}) : super(key: key); - - @override - State createState() => _SortPageState(); -} - -class _SortPageState extends State { - //存放随机数组 - List numbers = []; - - //订阅流 - StreamController> streamController = StreamController(); - String currentSort = 'bubble'; - - //柱子的数量 -> 生成排序数组的长度 - double sampleSize = 0; - - //是否排序 - bool isSorted = false; - - //是否在排序中 - bool isSorting = false; - - //排序动画更新的速度 - int speed = 0; - - static int duration = 1500; - - String getTitle() { - switch (currentSort) { - case "bubble": - return "Bubble Sort"; - case "coctail": - return "Coctail Sort"; - case "comb": - return "Comb Sort"; - case "pigeonhole": - return "Pigeonhole Sort"; - case "shell": - return "Shell Sort"; - case "selection": - return "Selection Sort"; - case "cycle": - return "Cycle Sort"; - case "heap": - return "Heap Sort"; - case "insertion": - return "Insertion Sort"; - case "gnome": - return "Gnome Sort"; - case "oddeven": - return "OddEven Sort"; - case "quick": - return "Quick Sort"; - case "merge": - return "Merge Sort"; - } - return ""; - } - - reset() { - isSorted = false; - numbers = []; - for (int i = 0; i < sampleSize; ++i) { - numbers.add(Random().nextInt(500)); - } - streamController.add(numbers); - } - - Duration getDuration() { - return Duration(microseconds: duration); - } - - ///动画时间 - changeSpeed() { - if (speed >= 3) { - speed = 0; - duration = 1500; - } else { - speed++; - duration = duration ~/ 2; - } - setState(() {}); - } - - ///冒泡排序 - bubbleSort() async { - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < numbers.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < numbers.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (numbers[j] > numbers[j + 1]) { - int temp = numbers[j]; - numbers[j] = numbers[j + 1]; - numbers[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); - } - } - } - - ///鸡尾酒排序(双向冒泡排序) - cocktailSort() async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = numbers.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } - } - - ///梳排序(Comb Sort) - combSort() async { - int gap = numbers.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < numbers.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (numbers[i] > numbers[i + gap]) { - int temp = numbers[i]; - numbers[i] = numbers[i + gap]; - numbers[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; - } - - ///鸽巢排序 - pigeonHole() async { - int min = numbers[0]; - int max = numbers[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < numbers.length; a++) { - if (numbers[a] > max) max = numbers[a]; - if (numbers[a] < min) min = numbers[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < numbers.length; i++) { - p[numbers[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - numbers[index++] = j + min; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///希尔排序 - shellSort() async { - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = numbers.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < numbers.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = numbers[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && numbers[j - gap] > temp; j -= gap) { - numbers[j] = numbers[j - gap]; - } - numbers[j] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///选择排序 - selectionSort() async { - for (int i = 0; i < numbers.length; i++) { - for (int j = i + 1; j < numbers.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (numbers[i] > numbers[j]) { - // 判断当前元素是否比后续元素小 - int temp = numbers[j]; - // 交换当前元素和后续较小的元素 - numbers[j] = numbers[i]; - numbers[i] = temp; - } - - await Future.delayed(getDuration(), () {}); - - streamController.add(numbers); - } - } - } - - ///循环排序 - cycleSort() async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= numbers.length - 2; cycleStart++) { - int item = numbers[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (item != numbers[pos]) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///堆排序 - heapSort() async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = numbers.length ~/ 2; i >= 0; i--) { - await heapify(numbers, numbers.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = numbers.length - 1; i >= 0; i--) { - int temp = numbers[0]; - numbers[0] = numbers[i]; - numbers[i] = temp; - await heapify(numbers, i, 0); - streamController.add(numbers); - } - } - - heapify(List arr, int n, int i) async { - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && arr[l] > arr[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && arr[r] > arr[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = numbers[i]; - numbers[i] = numbers[largest]; - numbers[largest] = temp; - heapify(arr, n, largest); - } - - await Future.delayed(getDuration()); // 延迟操作,用于可视化排序过程 - streamController.add(numbers); - } - - ///插入排序 - insertionSort() async { - for (int i = 1; i < numbers.length; i++) { - int temp = numbers[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < numbers[j]) { - numbers[j + 1] = numbers[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - await Future.delayed(getDuration()); - streamController.add(numbers); // 更新排序结果 - } - - numbers[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); // 更新排序结果 - } - } - - ///地精排序 (侏儒排序) - gnomeSort() async { - int index = 0; - - while (index < numbers.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (numbers[index] >= numbers[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = numbers[index]; - numbers[index] = numbers[index - 1]; - numbers[index - 1] = temp; - index--; - } - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - return; - } - - ///奇偶排序(Odd-Even Sort) - oddEvenSort() async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= numbers.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - for (int i = 0; i <= numbers.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - return; - } - - ///快速排序 - quickSort(int leftIndex, int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async{ - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = numbers[p]; - numbers[p] = numbers[right]; - numbers[right] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(numbers[i], numbers[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = numbers[i]; - numbers[i] = numbers[cursor]; - numbers[cursor] = temp; - cursor++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 将基准元素放置在游标位置 - temp = numbers[right]; - numbers[right] = numbers[cursor]; - numbers[cursor] = temp; - - await Future.delayed(getDuration()); - streamController.add(numbers); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await quickSort(leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await quickSort(p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } - } - - // 比较函数,用于判断两个元素的大小关系 - cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } - } - - ///归并排序 - mergeSort(int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = numbers[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = numbers[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - numbers[k] = leftList[i]; - i++; - } else { - numbers[k] = rightList[j]; - j++; - } - - await Future.delayed(getDuration()); - streamController.add(numbers); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - numbers[k] = leftList[i]; - i++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - while (j < rightSize) { - numbers[k] = rightList[j]; - j++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await mergeSort(leftIndex, middleIndex); - await mergeSort(middleIndex + 1, rightIndex); - - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } - } - - checkAndResetIfSorted() async { - if (isSorted) { - reset(); - await Future.delayed(const Duration(milliseconds: 200)); - } - } - - sort() async { - setState(() { - isSorting = true; - }); - - await checkAndResetIfSorted(); - - Stopwatch stopwatch = Stopwatch()..start(); - - switch (currentSort) { - case "bubble": - await bubbleSort(); - break; - case "coctail": - await cocktailSort(); - break; - case "comb": - await combSort(); - break; - case "pigeonhole": - await pigeonHole(); - break; - case "shell": - await shellSort(); - break; - case "selection": - await selectionSort(); - break; - case "cycle": - await cycleSort(); - break; - case "heap": - await heapSort(); - break; - case "insertion": - await insertionSort(); - break; - case "gnome": - await gnomeSort(); - break; - case "oddeven": - await oddEvenSort(); - break; - case "quick": - await quickSort(0, sampleSize.toInt() - 1); - break; - case "merge": - await mergeSort(0, sampleSize.toInt() - 1); - break; - } - - stopwatch.stop(); - - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - setState(() { - isSorting = false; - isSorted = true; - }); - } - - setSort(String type) { - setState(() { - currentSort = type; - }); - } - - @override - void initState() { - super.initState(); - // reset(); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - sampleSize = MediaQuery.of(context).size.width / 2; - for (int i = 0; i < sampleSize; ++i) { - //随机往数组中填值 - numbers.add(Random().nextInt(500)); - } - setState(() {}); - } - - @override - void dispose() { - streamController.close(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text( - "当前选择的是:${getTitle()}", - style: const TextStyle(fontSize: 14), - ), - actions: [ - PopupMenuButton( - initialValue: currentSort, - itemBuilder: (ctx) { - return const [ - PopupMenuItem( - value: 'bubble', - child: Text("Bubble Sort — 冒泡排序"), - ), - PopupMenuItem( - value: 'coctail', - child: Text("Coctail Sort — 鸡尾酒排序(双向冒泡排序)"), - ), - PopupMenuItem( - value: 'comb', - child: Text("Comb Sort — 梳排序"), - ), - PopupMenuItem( - value: 'pigeonhole', - child: Text("pigeonhole Sort — 鸽巢排序"), - ), - PopupMenuItem( - value: 'shell', - child: Text("shell Sort — 希尔排序"), - ), - PopupMenuItem( - value: 'selection', - child: Text("Selection Sort — 选择排序"), - ), - PopupMenuItem( - value: 'cycle', - child: Text("CycleSort — 循环排序"), - ), - PopupMenuItem( - value: 'heap', - child: Text("HeapSort — 堆排序"), - ), - PopupMenuItem( - value: 'insertion', - child: Text("InsertionSort — 插入排序"), - ), - PopupMenuItem( - value: 'gnome', - child: Text("GnomeSort — 地精排序 (侏儒排序)"), - ), - PopupMenuItem( - value: 'oddeven', - child: Text("OddEvenSort — 奇偶排序"), - ), - PopupMenuItem( - value: 'quick', - child: Text("QuickSort — 快速排序"), - ), - PopupMenuItem( - value: 'merge', - child: Text("MergeSort — 归并排序"), - ), - ]; - }, - onSelected: (String value) { - reset(); - setSort(value); - }, - ) - ], - ), - body: StreamBuilder( - initialData: numbers, - stream: streamController.stream, - builder: (context, snapshot) { - List numbers = snapshot.data as List; - int counter = 0; - return Row( - children: numbers.map((int num) { - counter++; - return CustomPaint( - painter: BarPainter( - width: MediaQuery.of(context).size.width / sampleSize, - value: num, - index: counter, - ), - ); - }).toList(), - ); - }, - ), - bottomNavigationBar: BottomAppBar( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: isSorting - ? null - : () { - reset(); - setSort(currentSort); - }, - child: const Text("重置")), - ElevatedButton( - onPressed: isSorting ? null : sort, child: const Text("开始排序")), - ElevatedButton( - onPressed: isSorting ? null : changeSpeed, - child: Text( - "${speed + 1}x", - style: const TextStyle(fontSize: 20), - ), - ), - ], - ), - ), - ); - } -} - -class BarPainter extends CustomPainter { - //宽度 - final double width; - - //高度(数组中对应的值) - final int value; - - //位置索引 - final int index; - - BarPainter({required this.width, required this.value, required this.index}); - - @override - void paint(Canvas canvas, Size size) { - Paint paint = Paint(); - if (value < 500 * .10) { - paint.color = Colors.blue.shade100; - } else if (value < 500 * .20) { - paint.color = Colors.blue.shade200; - } else if (value < 500 * .30) { - paint.color = Colors.blue.shade300; - } else if (value < 500 * .40) { - paint.color = Colors.blue.shade400; - } else if (value < 500 * .50) { - paint.color = Colors.blue.shade500; - } else if (value < 500 * .60) { - paint.color = Colors.blue.shade600; - } else if (value < 500 * .70) { - paint.color = Colors.blue.shade700; - } else if (value < 500 * .80) { - paint.color = Colors.blue.shade800; - } else if (value < 500 * .90) { - paint.color = Colors.blue.shade900; - } else { - paint.color = const Color(0xFF011E51); - } - - paint.strokeWidth = width; - paint.strokeCap = StrokeCap.round; - - canvas.drawLine( - Offset(index * width, 0), - Offset( - index * width, - value.ceilToDouble(), - ), - paint); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) { - return true; - } -} diff --git a/lib/v4/pages/user/user_page.dart b/lib/v4/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v4/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v5/app.dart b/lib/v5/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v5/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v5/app/navigation/router/app_router_delegate.dart b/lib/v5/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index 8d5af8b..0000000 --- a/lib/v5/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,244 +0,0 @@ -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/user/user_page.dart'; -import '../transition/fade_transition_page.dart'; -import '../../../pages/color/color_add_page.dart'; - -const List kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - String _path = '/color'; - - String get path => _path; - AppRouterDelegate(){ - // keepAlivePath.add('/color'); - } - 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> _completerMap = {}; - - Completer? completer; - - final Map _pathExtraMap = {}; - - final List keepAlivePath = [] ; - - - void setPathKeepLive(String value){ - if(keepAlivePath.contains(value)){ - keepAlivePath.remove(value); - } - keepAlivePath.add(value); - path = value; - } - - - - void setPathForData(String value,dynamic data){ - _pathExtraMap[value] = data; - path = value; - } - - Future changePathForResult(String value) async{ - Completer completer = Completer(); - _completerMap[value] = completer; - path = value; - return completer.future; - } - - set path(String value) { - if (_path == value) return; - _path = value; - notifyListeners(); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPages(path), - ); - } - - List _buildPages(path){ - List pages = []; - List topPages = _buildPageByPath(path); - - if(keepAlivePath.isNotEmpty){ - for (String alivePath in keepAlivePath) { - if(alivePath!=path){ - pages.addAll(_buildPageByPath(alivePath)) ; - } - } - /// 去除和 topPages 中重复的界面 - pages.removeWhere((element) => topPages.map((e) => e.key).contains(element.key)); - } - - - if(keepAlivePath.isNotEmpty){ - for (String alivePath in keepAlivePath) { - if(alivePath!=path){ - pages.addAll(_buildPageByPath(alivePath)) ; - } - } - /// 去除和 topPages 中重复的界面 - pages.removeWhere((element) => topPages.map((e) => e.key).contains(element.key)); - } - - pages.addAll(topPages); - return pages; - } - - List _buildPageByPath(String path) { - Widget? child; - if(path.startsWith('/color')){ - return buildColorPages(path); - } - - if (path == kDestinationsPaths[1]) { - child = const CounterPage(); - } - if (path == kDestinationsPaths[2]) { - child = const UserPage(); - } - if (path == kDestinationsPaths[3]) { - child = const SettingPage(); - } - return [ - FadeTransitionPage( - key: ValueKey(path), - child: child ?? const EmptyPage(), - ) - ]; - } - - List buildColorPages(String path){ - List 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 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), - )); - }else{ - Color? selectedColor = _pathExtraMap[path]; - if (selectedColor != null) { - result.add( FadeTransitionPage( - key: const ValueKey('/color/detail'), - child:ColorDetailPage(color: selectedColor), - )); - _pathExtraMap.remove(path); - } - } - } - if(segment == 'add'){ - result.add( const FadeTransitionPage( - key: ValueKey('/color/add'), - child:ColorAddPage(), - )); - } - - } - return result; - } - - @override - Future 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 parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} - - - -// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { -// -// List _value = ['/']; -// -// -// List get value => _value; -// -// set value(List value){ -// _value = value; -// notifyListeners(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Navigator( -// onPopPage: _onPopPage, -// pages: _value.map((e) => _pageMap[e]!).toList(), -// ); -// } -// -// final Map _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? navigatorKey = GlobalKey(); -// -// @override -// Future setNewRoutePath(String configuration) async{ -// } -// } diff --git a/lib/v5/app/navigation/router/iroute.dart b/lib/v5/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/v5/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/v5/app/navigation/transition/fade_transition_page.dart b/lib/v5/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v5/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v5/app/navigation/transition/no_transition_page.dart b/lib/v5/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v5/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v5/app/navigation/views/app_navigation.dart b/lib/v5/app/navigation/views/app_navigation.dart deleted file mode 100644 index adcab6c..0000000 --- a/lib/v5/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v5/app/navigation/views/app_navigation_rail.dart b/lib/v5/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 2580ed2..0000000 --- a/lib/v5/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined), - MenuMeta(label: '计数器', icon: Icons.add_chart), - MenuMeta(label: '我的', icon: Icons.person), - MenuMeta(label: '设置', icon: Icons.settings), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text( - 'V0.0.5', - style: TextStyle(color: Colors.white, fontSize: 12), - ), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: router.activeIndex, - ), - ); - } - - void _onDestinationSelected(int index) { - if (index == 1) { - router.setPathKeepLive(kDestinationsPaths[index]); - return; - } - router.path = kDestinationsPaths[index]; - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v5/app/navigation/views/app_router_editor.dart b/lib/v5/app/navigation/views/app_router_editor.dart deleted file mode 100644 index 10d5701..0000000 --- a/lib/v5/app/navigation/views/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v5/app/navigation/views/app_top_bar.dart b/lib/v5/app/navigation/views/app_top_bar.dart deleted file mode 100644 index 1b95110..0000000 --- a/lib/v5/app/navigation/views/app_top_bar.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; -import 'app_router_editor.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.path = path, - )), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -Map kRouteLabelMap = { - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/user': '我的', - '/settings': '系统设置', -}; - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.path = item.to!; - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - return result; - } -} diff --git a/lib/v5/app/unit_app.dart b/lib/v5/app/unit_app.dart deleted file mode 100644 index 1a21114..0000000 --- a/lib/v5/app/unit_app.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/router/app_router_delegate.dart'; -import 'navigation/views/app_navigation.dart'; -import 'navigation/views/app_navigation_rail.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation() - ); - } -} - - diff --git a/lib/v5/pages/color/color_add_page.dart b/lib/v5/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v5/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v5/pages/color/color_detail_page.dart b/lib/v5/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v5/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v5/pages/color/color_page.dart b/lib/v5/pages/color/color_page.dart deleted file mode 100644 index e7b88da..0000000 --- a/lib/v5/pages/color/color_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.setPathForData('/color/detail',color); - - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v5/pages/counter/counter_page.dart b/lib/v5/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v5/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v5/pages/empty/empty_page.dart b/lib/v5/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v5/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v5/pages/settings/settings_page.dart b/lib/v5/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v5/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v5/pages/sort/sort_page.dart b/lib/v5/pages/sort/sort_page.dart deleted file mode 100644 index d440071..0000000 --- a/lib/v5/pages/sort/sort_page.dart +++ /dev/null @@ -1,859 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; - -class SortPage extends StatefulWidget { - const SortPage({Key? key}) : super(key: key); - - @override - State createState() => _SortPageState(); -} - -class _SortPageState extends State { - //存放随机数组 - List numbers = []; - - //订阅流 - StreamController> streamController = StreamController(); - String currentSort = 'bubble'; - - //柱子的数量 -> 生成排序数组的长度 - double sampleSize = 0; - - //是否排序 - bool isSorted = false; - - //是否在排序中 - bool isSorting = false; - - //排序动画更新的速度 - int speed = 0; - - static int duration = 1500; - - String getTitle() { - switch (currentSort) { - case "bubble": - return "Bubble Sort"; - case "coctail": - return "Coctail Sort"; - case "comb": - return "Comb Sort"; - case "pigeonhole": - return "Pigeonhole Sort"; - case "shell": - return "Shell Sort"; - case "selection": - return "Selection Sort"; - case "cycle": - return "Cycle Sort"; - case "heap": - return "Heap Sort"; - case "insertion": - return "Insertion Sort"; - case "gnome": - return "Gnome Sort"; - case "oddeven": - return "OddEven Sort"; - case "quick": - return "Quick Sort"; - case "merge": - return "Merge Sort"; - } - return ""; - } - - reset() { - isSorted = false; - numbers = []; - for (int i = 0; i < sampleSize; ++i) { - numbers.add(Random().nextInt(500)); - } - streamController.add(numbers); - } - - Duration getDuration() { - return Duration(microseconds: duration); - } - - ///动画时间 - changeSpeed() { - if (speed >= 3) { - speed = 0; - duration = 1500; - } else { - speed++; - duration = duration ~/ 2; - } - setState(() {}); - } - - ///冒泡排序 - bubbleSort() async { - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < numbers.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < numbers.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (numbers[j] > numbers[j + 1]) { - int temp = numbers[j]; - numbers[j] = numbers[j + 1]; - numbers[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); - } - } - } - - ///鸡尾酒排序(双向冒泡排序) - cocktailSort() async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = numbers.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } - } - - ///梳排序(Comb Sort) - combSort() async { - int gap = numbers.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < numbers.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (numbers[i] > numbers[i + gap]) { - int temp = numbers[i]; - numbers[i] = numbers[i + gap]; - numbers[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; - } - - ///鸽巢排序 - pigeonHole() async { - int min = numbers[0]; - int max = numbers[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < numbers.length; a++) { - if (numbers[a] > max) max = numbers[a]; - if (numbers[a] < min) min = numbers[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < numbers.length; i++) { - p[numbers[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - numbers[index++] = j + min; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///希尔排序 - shellSort() async { - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = numbers.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < numbers.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = numbers[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && numbers[j - gap] > temp; j -= gap) { - numbers[j] = numbers[j - gap]; - } - numbers[j] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///选择排序 - selectionSort() async { - for (int i = 0; i < numbers.length; i++) { - for (int j = i + 1; j < numbers.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (numbers[i] > numbers[j]) { - // 判断当前元素是否比后续元素小 - int temp = numbers[j]; - // 交换当前元素和后续较小的元素 - numbers[j] = numbers[i]; - numbers[i] = temp; - } - - await Future.delayed(getDuration(), () {}); - - streamController.add(numbers); - } - } - } - - ///循环排序 - cycleSort() async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= numbers.length - 2; cycleStart++) { - int item = numbers[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (item != numbers[pos]) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///堆排序 - heapSort() async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = numbers.length ~/ 2; i >= 0; i--) { - await heapify(numbers, numbers.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = numbers.length - 1; i >= 0; i--) { - int temp = numbers[0]; - numbers[0] = numbers[i]; - numbers[i] = temp; - await heapify(numbers, i, 0); - streamController.add(numbers); - } - } - - heapify(List arr, int n, int i) async { - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && arr[l] > arr[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && arr[r] > arr[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = numbers[i]; - numbers[i] = numbers[largest]; - numbers[largest] = temp; - heapify(arr, n, largest); - } - - await Future.delayed(getDuration()); // 延迟操作,用于可视化排序过程 - streamController.add(numbers); - } - - ///插入排序 - insertionSort() async { - for (int i = 1; i < numbers.length; i++) { - int temp = numbers[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < numbers[j]) { - numbers[j + 1] = numbers[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - await Future.delayed(getDuration()); - streamController.add(numbers); // 更新排序结果 - } - - numbers[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); // 更新排序结果 - } - } - - ///地精排序 (侏儒排序) - gnomeSort() async { - int index = 0; - - while (index < numbers.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (numbers[index] >= numbers[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = numbers[index]; - numbers[index] = numbers[index - 1]; - numbers[index - 1] = temp; - index--; - } - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - return; - } - - ///奇偶排序(Odd-Even Sort) - oddEvenSort() async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= numbers.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - for (int i = 0; i <= numbers.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - return; - } - - ///快速排序 - quickSort(int leftIndex, int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async{ - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = numbers[p]; - numbers[p] = numbers[right]; - numbers[right] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(numbers[i], numbers[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = numbers[i]; - numbers[i] = numbers[cursor]; - numbers[cursor] = temp; - cursor++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 将基准元素放置在游标位置 - temp = numbers[right]; - numbers[right] = numbers[cursor]; - numbers[cursor] = temp; - - await Future.delayed(getDuration()); - streamController.add(numbers); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await quickSort(leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await quickSort(p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } - } - - // 比较函数,用于判断两个元素的大小关系 - cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } - } - - ///归并排序 - mergeSort(int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = numbers[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = numbers[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - numbers[k] = leftList[i]; - i++; - } else { - numbers[k] = rightList[j]; - j++; - } - - await Future.delayed(getDuration()); - streamController.add(numbers); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - numbers[k] = leftList[i]; - i++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - while (j < rightSize) { - numbers[k] = rightList[j]; - j++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await mergeSort(leftIndex, middleIndex); - await mergeSort(middleIndex + 1, rightIndex); - - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } - } - - checkAndResetIfSorted() async { - if (isSorted) { - reset(); - await Future.delayed(const Duration(milliseconds: 200)); - } - } - - sort() async { - setState(() { - isSorting = true; - }); - - await checkAndResetIfSorted(); - - Stopwatch stopwatch = Stopwatch()..start(); - - switch (currentSort) { - case "bubble": - await bubbleSort(); - break; - case "coctail": - await cocktailSort(); - break; - case "comb": - await combSort(); - break; - case "pigeonhole": - await pigeonHole(); - break; - case "shell": - await shellSort(); - break; - case "selection": - await selectionSort(); - break; - case "cycle": - await cycleSort(); - break; - case "heap": - await heapSort(); - break; - case "insertion": - await insertionSort(); - break; - case "gnome": - await gnomeSort(); - break; - case "oddeven": - await oddEvenSort(); - break; - case "quick": - await quickSort(0, sampleSize.toInt() - 1); - break; - case "merge": - await mergeSort(0, sampleSize.toInt() - 1); - break; - } - - stopwatch.stop(); - - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - setState(() { - isSorting = false; - isSorted = true; - }); - } - - setSort(String type) { - setState(() { - currentSort = type; - }); - } - - @override - void initState() { - super.initState(); - // reset(); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - sampleSize = MediaQuery.of(context).size.width / 2; - for (int i = 0; i < sampleSize; ++i) { - //随机往数组中填值 - numbers.add(Random().nextInt(500)); - } - setState(() {}); - } - - @override - void dispose() { - streamController.close(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text( - "当前选择的是:${getTitle()}", - style: const TextStyle(fontSize: 14), - ), - actions: [ - PopupMenuButton( - initialValue: currentSort, - itemBuilder: (ctx) { - return const [ - PopupMenuItem( - value: 'bubble', - child: Text("Bubble Sort — 冒泡排序"), - ), - PopupMenuItem( - value: 'coctail', - child: Text("Coctail Sort — 鸡尾酒排序(双向冒泡排序)"), - ), - PopupMenuItem( - value: 'comb', - child: Text("Comb Sort — 梳排序"), - ), - PopupMenuItem( - value: 'pigeonhole', - child: Text("pigeonhole Sort — 鸽巢排序"), - ), - PopupMenuItem( - value: 'shell', - child: Text("shell Sort — 希尔排序"), - ), - PopupMenuItem( - value: 'selection', - child: Text("Selection Sort — 选择排序"), - ), - PopupMenuItem( - value: 'cycle', - child: Text("CycleSort — 循环排序"), - ), - PopupMenuItem( - value: 'heap', - child: Text("HeapSort — 堆排序"), - ), - PopupMenuItem( - value: 'insertion', - child: Text("InsertionSort — 插入排序"), - ), - PopupMenuItem( - value: 'gnome', - child: Text("GnomeSort — 地精排序 (侏儒排序)"), - ), - PopupMenuItem( - value: 'oddeven', - child: Text("OddEvenSort — 奇偶排序"), - ), - PopupMenuItem( - value: 'quick', - child: Text("QuickSort — 快速排序"), - ), - PopupMenuItem( - value: 'merge', - child: Text("MergeSort — 归并排序"), - ), - ]; - }, - onSelected: (String value) { - reset(); - setSort(value); - }, - ) - ], - ), - body: StreamBuilder( - initialData: numbers, - stream: streamController.stream, - builder: (context, snapshot) { - List numbers = snapshot.data as List; - int counter = 0; - return Row( - children: numbers.map((int num) { - counter++; - return CustomPaint( - painter: BarPainter( - width: MediaQuery.of(context).size.width / sampleSize, - value: num, - index: counter, - ), - ); - }).toList(), - ); - }, - ), - bottomNavigationBar: BottomAppBar( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: isSorting - ? null - : () { - reset(); - setSort(currentSort); - }, - child: const Text("重置")), - ElevatedButton( - onPressed: isSorting ? null : sort, child: const Text("开始排序")), - ElevatedButton( - onPressed: isSorting ? null : changeSpeed, - child: Text( - "${speed + 1}x", - style: const TextStyle(fontSize: 20), - ), - ), - ], - ), - ), - ); - } -} - -class BarPainter extends CustomPainter { - //宽度 - final double width; - - //高度(数组中对应的值) - final int value; - - //位置索引 - final int index; - - BarPainter({required this.width, required this.value, required this.index}); - - @override - void paint(Canvas canvas, Size size) { - Paint paint = Paint(); - if (value < 500 * .10) { - paint.color = Colors.blue.shade100; - } else if (value < 500 * .20) { - paint.color = Colors.blue.shade200; - } else if (value < 500 * .30) { - paint.color = Colors.blue.shade300; - } else if (value < 500 * .40) { - paint.color = Colors.blue.shade400; - } else if (value < 500 * .50) { - paint.color = Colors.blue.shade500; - } else if (value < 500 * .60) { - paint.color = Colors.blue.shade600; - } else if (value < 500 * .70) { - paint.color = Colors.blue.shade700; - } else if (value < 500 * .80) { - paint.color = Colors.blue.shade800; - } else if (value < 500 * .90) { - paint.color = Colors.blue.shade900; - } else { - paint.color = const Color(0xFF011E51); - } - - paint.strokeWidth = width; - paint.strokeCap = StrokeCap.round; - - canvas.drawLine( - Offset(index * width, 0), - Offset( - index * width, - value.ceilToDouble(), - ), - paint); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) { - return true; - } -} diff --git a/lib/v5/pages/user/user_page.dart b/lib/v5/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v5/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v5_02/app.dart b/lib/v5_02/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v5_02/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v5_02/app/navigation/router/app_router_delegate.dart b/lib/v5_02/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index 56c2777..0000000 --- a/lib/v5_02/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,241 +0,0 @@ -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/user/user_page.dart'; -import '../transition/fade_transition_page.dart'; -import '../../../pages/color/color_add_page.dart'; - -const List kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); -ValueNotifier counter = ValueNotifier(0); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - String _path = '/color'; - - String get path => _path; - - AppRouterDelegate(){ - // keepAlivePath.add('/color'); - } - 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> _completerMap = {}; - - Completer? completer; - - final Map _pathExtraMap = {}; - - final List keepAlivePath = [] ; - - void setPathKeepLive(String value){ - if(keepAlivePath.contains(value)){ - keepAlivePath.remove(value); - } - keepAlivePath.add(value); - path = value; - } - - void setPathForData(String value,dynamic data){ - _pathExtraMap[value] = data; - path = value; - } - - Future changePathForResult(String value) async{ - Completer completer = Completer(); - _completerMap[value] = completer; - path = value; - return completer.future; - } - - set path(String value) { - if (_path == value) return; - _path = value; - notifyListeners(); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPages(path), - ); - } - - List _buildPages(path){ - List pages = []; - List topPages = _buildPageByPath(path); - - if(keepAlivePath.isNotEmpty){ - for (String alivePath in keepAlivePath) { - if(alivePath!=path){ - pages.addAll(_buildPageByPath(alivePath)) ; - } - } - /// 去除和 topPages 中重复的界面 - pages.removeWhere((element) => topPages.map((e) => e.key).contains(element.key)); - } - - pages.addAll(topPages); - return pages; - } - - int _counter = 0; - - List _buildPageByPath(String path) { - Widget? child; - if(path.startsWith('/color')){ - return buildColorPages(path); - } - - if (path == kDestinationsPaths[1]) { - child = CounterPage( - counter: _counter, - onAddTap: (){ - _counter++; - notifyListeners(); - }, - ); - } - if (path == kDestinationsPaths[2]) { - child = const UserPage(); - } - if (path == kDestinationsPaths[3]) { - child = const SettingPage(); - } - return [ - FadeTransitionPage( - key: ValueKey(path), - child: child ?? const EmptyPage(), - ) - ]; - } - - List buildColorPages(String path){ - List 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 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), - )); - }else{ - Color? selectedColor = _pathExtraMap[path]; - if (selectedColor != null) { - result.add( FadeTransitionPage( - key: const ValueKey('/color/detail'), - child:ColorDetailPage(color: selectedColor), - )); - _pathExtraMap.remove(path); - } - } - } - if(segment == 'add'){ - result.add( const FadeTransitionPage( - key: ValueKey('/color/add'), - child:ColorAddPage(), - )); - } - - } - return result; - } - - @override - Future 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 parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} - - - -// class AppRouterDelegate extends RouterDelegate with ChangeNotifier, PopNavigatorRouterDelegateMixin { -// -// List _value = ['/']; -// -// -// List get value => _value; -// -// set value(List value){ -// _value = value; -// notifyListeners(); -// } -// -// @override -// Widget build(BuildContext context) { -// return Navigator( -// onPopPage: _onPopPage, -// pages: _value.map((e) => _pageMap[e]!).toList(), -// ); -// } -// -// final Map _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? navigatorKey = GlobalKey(); -// -// @override -// Future setNewRoutePath(String configuration) async{ -// } -// } diff --git a/lib/v5_02/app/navigation/router/iroute.dart b/lib/v5_02/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/v5_02/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/v5_02/app/navigation/transition/fade_transition_page.dart b/lib/v5_02/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v5_02/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v5_02/app/navigation/transition/no_transition_page.dart b/lib/v5_02/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v5_02/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v5_02/app/navigation/views/app_navigation.dart b/lib/v5_02/app/navigation/views/app_navigation.dart deleted file mode 100644 index adcab6c..0000000 --- a/lib/v5_02/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v5_02/app/navigation/views/app_navigation_rail.dart b/lib/v5_02/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index f4e8256..0000000 --- a/lib/v5_02/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined), - MenuMeta(label: '计数器', icon: Icons.add_chart), - MenuMeta(label: '我的', icon: Icons.person), - MenuMeta(label: '设置', icon: Icons.settings), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text('V0.0.5',style: TextStyle(color: Colors.white,fontSize: 12),), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: router.activeIndex, - ), - ); - - } - - void _onDestinationSelected(int index) { - // if(index==1){ - // router.setPathKeepLive(kDestinationsPaths[index]); - // }else{ - // router.path = kDestinationsPaths[index]; - // } - router.path = kDestinationsPaths[index]; - - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v5_02/app/navigation/views/app_router_editor.dart b/lib/v5_02/app/navigation/views/app_router_editor.dart deleted file mode 100644 index 10d5701..0000000 --- a/lib/v5_02/app/navigation/views/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v5_02/app/navigation/views/app_top_bar.dart b/lib/v5_02/app/navigation/views/app_top_bar.dart deleted file mode 100644 index 1b95110..0000000 --- a/lib/v5_02/app/navigation/views/app_top_bar.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; -import 'app_router_editor.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.path = path, - )), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -Map kRouteLabelMap = { - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/user': '我的', - '/settings': '系统设置', -}; - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.path = item.to!; - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - return result; - } -} diff --git a/lib/v5_02/app/unit_app.dart b/lib/v5_02/app/unit_app.dart deleted file mode 100644 index 1a21114..0000000 --- a/lib/v5_02/app/unit_app.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/router/app_router_delegate.dart'; -import 'navigation/views/app_navigation.dart'; -import 'navigation/views/app_navigation_rail.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation() - ); - } -} - - diff --git a/lib/v5_02/pages/color/color_add_page.dart b/lib/v5_02/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v5_02/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v5_02/pages/color/color_detail_page.dart b/lib/v5_02/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v5_02/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v5_02/pages/color/color_page.dart b/lib/v5_02/pages/color/color_page.dart deleted file mode 100644 index e7b88da..0000000 --- a/lib/v5_02/pages/color/color_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.setPathForData('/color/detail',color); - - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v5_02/pages/counter/counter_page.dart b/lib/v5_02/pages/counter/counter_page.dart deleted file mode 100644 index 5591eba..0000000 --- a/lib/v5_02/pages/counter/counter_page.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatelessWidget { - final int counter; - final VoidCallback onAddTap; - - const CounterPage({super.key, required this.counter, required this.onAddTap}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$counter', - style: Theme - .of(context) - .textTheme - .headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: onAddTap, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v5_02/pages/empty/empty_page.dart b/lib/v5_02/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v5_02/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v5_02/pages/settings/settings_page.dart b/lib/v5_02/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v5_02/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v5_02/pages/sort/sort_page.dart b/lib/v5_02/pages/sort/sort_page.dart deleted file mode 100644 index d440071..0000000 --- a/lib/v5_02/pages/sort/sort_page.dart +++ /dev/null @@ -1,859 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; - -class SortPage extends StatefulWidget { - const SortPage({Key? key}) : super(key: key); - - @override - State createState() => _SortPageState(); -} - -class _SortPageState extends State { - //存放随机数组 - List numbers = []; - - //订阅流 - StreamController> streamController = StreamController(); - String currentSort = 'bubble'; - - //柱子的数量 -> 生成排序数组的长度 - double sampleSize = 0; - - //是否排序 - bool isSorted = false; - - //是否在排序中 - bool isSorting = false; - - //排序动画更新的速度 - int speed = 0; - - static int duration = 1500; - - String getTitle() { - switch (currentSort) { - case "bubble": - return "Bubble Sort"; - case "coctail": - return "Coctail Sort"; - case "comb": - return "Comb Sort"; - case "pigeonhole": - return "Pigeonhole Sort"; - case "shell": - return "Shell Sort"; - case "selection": - return "Selection Sort"; - case "cycle": - return "Cycle Sort"; - case "heap": - return "Heap Sort"; - case "insertion": - return "Insertion Sort"; - case "gnome": - return "Gnome Sort"; - case "oddeven": - return "OddEven Sort"; - case "quick": - return "Quick Sort"; - case "merge": - return "Merge Sort"; - } - return ""; - } - - reset() { - isSorted = false; - numbers = []; - for (int i = 0; i < sampleSize; ++i) { - numbers.add(Random().nextInt(500)); - } - streamController.add(numbers); - } - - Duration getDuration() { - return Duration(microseconds: duration); - } - - ///动画时间 - changeSpeed() { - if (speed >= 3) { - speed = 0; - duration = 1500; - } else { - speed++; - duration = duration ~/ 2; - } - setState(() {}); - } - - ///冒泡排序 - bubbleSort() async { - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < numbers.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < numbers.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (numbers[j] > numbers[j + 1]) { - int temp = numbers[j]; - numbers[j] = numbers[j + 1]; - numbers[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); - } - } - } - - ///鸡尾酒排序(双向冒泡排序) - cocktailSort() async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = numbers.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } - } - - ///梳排序(Comb Sort) - combSort() async { - int gap = numbers.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < numbers.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (numbers[i] > numbers[i + gap]) { - int temp = numbers[i]; - numbers[i] = numbers[i + gap]; - numbers[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; - } - - ///鸽巢排序 - pigeonHole() async { - int min = numbers[0]; - int max = numbers[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < numbers.length; a++) { - if (numbers[a] > max) max = numbers[a]; - if (numbers[a] < min) min = numbers[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < numbers.length; i++) { - p[numbers[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - numbers[index++] = j + min; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///希尔排序 - shellSort() async { - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = numbers.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < numbers.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = numbers[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && numbers[j - gap] > temp; j -= gap) { - numbers[j] = numbers[j - gap]; - } - numbers[j] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///选择排序 - selectionSort() async { - for (int i = 0; i < numbers.length; i++) { - for (int j = i + 1; j < numbers.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (numbers[i] > numbers[j]) { - // 判断当前元素是否比后续元素小 - int temp = numbers[j]; - // 交换当前元素和后续较小的元素 - numbers[j] = numbers[i]; - numbers[i] = temp; - } - - await Future.delayed(getDuration(), () {}); - - streamController.add(numbers); - } - } - } - - ///循环排序 - cycleSort() async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= numbers.length - 2; cycleStart++) { - int item = numbers[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (item != numbers[pos]) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///堆排序 - heapSort() async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = numbers.length ~/ 2; i >= 0; i--) { - await heapify(numbers, numbers.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = numbers.length - 1; i >= 0; i--) { - int temp = numbers[0]; - numbers[0] = numbers[i]; - numbers[i] = temp; - await heapify(numbers, i, 0); - streamController.add(numbers); - } - } - - heapify(List arr, int n, int i) async { - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && arr[l] > arr[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && arr[r] > arr[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = numbers[i]; - numbers[i] = numbers[largest]; - numbers[largest] = temp; - heapify(arr, n, largest); - } - - await Future.delayed(getDuration()); // 延迟操作,用于可视化排序过程 - streamController.add(numbers); - } - - ///插入排序 - insertionSort() async { - for (int i = 1; i < numbers.length; i++) { - int temp = numbers[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < numbers[j]) { - numbers[j + 1] = numbers[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - await Future.delayed(getDuration()); - streamController.add(numbers); // 更新排序结果 - } - - numbers[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); // 更新排序结果 - } - } - - ///地精排序 (侏儒排序) - gnomeSort() async { - int index = 0; - - while (index < numbers.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (numbers[index] >= numbers[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = numbers[index]; - numbers[index] = numbers[index - 1]; - numbers[index - 1] = temp; - index--; - } - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - return; - } - - ///奇偶排序(Odd-Even Sort) - oddEvenSort() async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= numbers.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - for (int i = 0; i <= numbers.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - return; - } - - ///快速排序 - quickSort(int leftIndex, int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async{ - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = numbers[p]; - numbers[p] = numbers[right]; - numbers[right] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(numbers[i], numbers[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = numbers[i]; - numbers[i] = numbers[cursor]; - numbers[cursor] = temp; - cursor++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 将基准元素放置在游标位置 - temp = numbers[right]; - numbers[right] = numbers[cursor]; - numbers[cursor] = temp; - - await Future.delayed(getDuration()); - streamController.add(numbers); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await quickSort(leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await quickSort(p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } - } - - // 比较函数,用于判断两个元素的大小关系 - cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } - } - - ///归并排序 - mergeSort(int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = numbers[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = numbers[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - numbers[k] = leftList[i]; - i++; - } else { - numbers[k] = rightList[j]; - j++; - } - - await Future.delayed(getDuration()); - streamController.add(numbers); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - numbers[k] = leftList[i]; - i++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - while (j < rightSize) { - numbers[k] = rightList[j]; - j++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await mergeSort(leftIndex, middleIndex); - await mergeSort(middleIndex + 1, rightIndex); - - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } - } - - checkAndResetIfSorted() async { - if (isSorted) { - reset(); - await Future.delayed(const Duration(milliseconds: 200)); - } - } - - sort() async { - setState(() { - isSorting = true; - }); - - await checkAndResetIfSorted(); - - Stopwatch stopwatch = Stopwatch()..start(); - - switch (currentSort) { - case "bubble": - await bubbleSort(); - break; - case "coctail": - await cocktailSort(); - break; - case "comb": - await combSort(); - break; - case "pigeonhole": - await pigeonHole(); - break; - case "shell": - await shellSort(); - break; - case "selection": - await selectionSort(); - break; - case "cycle": - await cycleSort(); - break; - case "heap": - await heapSort(); - break; - case "insertion": - await insertionSort(); - break; - case "gnome": - await gnomeSort(); - break; - case "oddeven": - await oddEvenSort(); - break; - case "quick": - await quickSort(0, sampleSize.toInt() - 1); - break; - case "merge": - await mergeSort(0, sampleSize.toInt() - 1); - break; - } - - stopwatch.stop(); - - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - setState(() { - isSorting = false; - isSorted = true; - }); - } - - setSort(String type) { - setState(() { - currentSort = type; - }); - } - - @override - void initState() { - super.initState(); - // reset(); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - sampleSize = MediaQuery.of(context).size.width / 2; - for (int i = 0; i < sampleSize; ++i) { - //随机往数组中填值 - numbers.add(Random().nextInt(500)); - } - setState(() {}); - } - - @override - void dispose() { - streamController.close(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text( - "当前选择的是:${getTitle()}", - style: const TextStyle(fontSize: 14), - ), - actions: [ - PopupMenuButton( - initialValue: currentSort, - itemBuilder: (ctx) { - return const [ - PopupMenuItem( - value: 'bubble', - child: Text("Bubble Sort — 冒泡排序"), - ), - PopupMenuItem( - value: 'coctail', - child: Text("Coctail Sort — 鸡尾酒排序(双向冒泡排序)"), - ), - PopupMenuItem( - value: 'comb', - child: Text("Comb Sort — 梳排序"), - ), - PopupMenuItem( - value: 'pigeonhole', - child: Text("pigeonhole Sort — 鸽巢排序"), - ), - PopupMenuItem( - value: 'shell', - child: Text("shell Sort — 希尔排序"), - ), - PopupMenuItem( - value: 'selection', - child: Text("Selection Sort — 选择排序"), - ), - PopupMenuItem( - value: 'cycle', - child: Text("CycleSort — 循环排序"), - ), - PopupMenuItem( - value: 'heap', - child: Text("HeapSort — 堆排序"), - ), - PopupMenuItem( - value: 'insertion', - child: Text("InsertionSort — 插入排序"), - ), - PopupMenuItem( - value: 'gnome', - child: Text("GnomeSort — 地精排序 (侏儒排序)"), - ), - PopupMenuItem( - value: 'oddeven', - child: Text("OddEvenSort — 奇偶排序"), - ), - PopupMenuItem( - value: 'quick', - child: Text("QuickSort — 快速排序"), - ), - PopupMenuItem( - value: 'merge', - child: Text("MergeSort — 归并排序"), - ), - ]; - }, - onSelected: (String value) { - reset(); - setSort(value); - }, - ) - ], - ), - body: StreamBuilder( - initialData: numbers, - stream: streamController.stream, - builder: (context, snapshot) { - List numbers = snapshot.data as List; - int counter = 0; - return Row( - children: numbers.map((int num) { - counter++; - return CustomPaint( - painter: BarPainter( - width: MediaQuery.of(context).size.width / sampleSize, - value: num, - index: counter, - ), - ); - }).toList(), - ); - }, - ), - bottomNavigationBar: BottomAppBar( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: isSorting - ? null - : () { - reset(); - setSort(currentSort); - }, - child: const Text("重置")), - ElevatedButton( - onPressed: isSorting ? null : sort, child: const Text("开始排序")), - ElevatedButton( - onPressed: isSorting ? null : changeSpeed, - child: Text( - "${speed + 1}x", - style: const TextStyle(fontSize: 20), - ), - ), - ], - ), - ), - ); - } -} - -class BarPainter extends CustomPainter { - //宽度 - final double width; - - //高度(数组中对应的值) - final int value; - - //位置索引 - final int index; - - BarPainter({required this.width, required this.value, required this.index}); - - @override - void paint(Canvas canvas, Size size) { - Paint paint = Paint(); - if (value < 500 * .10) { - paint.color = Colors.blue.shade100; - } else if (value < 500 * .20) { - paint.color = Colors.blue.shade200; - } else if (value < 500 * .30) { - paint.color = Colors.blue.shade300; - } else if (value < 500 * .40) { - paint.color = Colors.blue.shade400; - } else if (value < 500 * .50) { - paint.color = Colors.blue.shade500; - } else if (value < 500 * .60) { - paint.color = Colors.blue.shade600; - } else if (value < 500 * .70) { - paint.color = Colors.blue.shade700; - } else if (value < 500 * .80) { - paint.color = Colors.blue.shade800; - } else if (value < 500 * .90) { - paint.color = Colors.blue.shade900; - } else { - paint.color = const Color(0xFF011E51); - } - - paint.strokeWidth = width; - paint.strokeCap = StrokeCap.round; - - canvas.drawLine( - Offset(index * width, 0), - Offset( - index * width, - value.ceilToDouble(), - ), - paint); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) { - return true; - } -} diff --git a/lib/v5_02/pages/user/user_page.dart b/lib/v5_02/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v5_02/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v6/app.dart b/lib/v6/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v6/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v6/app/navigation/router/app_router_delegate.dart b/lib/v6/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index c4af8a6..0000000 --- a/lib/v6/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,258 +0,0 @@ -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/user/user_page.dart'; -import '../transition/fade_transition_page.dart'; -import '../../../pages/color/color_add_page.dart'; -import 'route_history.dart'; - -const List kDestinationsPaths = [ - '/color', - '/counter', - '/user', - '/settings', -]; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - String _path = '/color'; - - String get path => _path; - - AppRouterDelegate() { - // keepAlivePath.add('/color'); - _histories.add(RouteHistory(path)); - } - - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories.reversed.toList(); - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 历史回退操作 - /// 将当前顶层移除,并加入 _backHistories 撤销列表 - /// 并转到前一路径 - void back() { - if (!hasHistory) return; - RouteHistory top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - _path = _histories.last.path; - if (_histories.last.extra != null) { - _pathExtraMap[_path] = _histories.last.extra; - } - notifyListeners(); - } - } - - void toHistory(RouteHistory history) { - _path = history.path; - if (history.extra != null) { - _pathExtraMap[_path] = history.extra; - } - notifyListeners(); - } - - void closeHistory(int index) { - _histories.removeAt(index); - notifyListeners(); - } - - void clearHistory() { - _histories.clear(); - notifyListeners(); - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation() { - RouteHistory target = _backHistories.removeLast(); - _path = target.path; - if (target.extra != null) { - _pathExtraMap[_path] = target.extra; - } - _histories.add(target); - notifyListeners(); - } - - 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> _completerMap = {}; - - Completer? completer; - - final Map _pathExtraMap = {}; - - final List keepAlivePath = []; - - void setPathKeepLive(String value) { - if (keepAlivePath.contains(value)) { - keepAlivePath.remove(value); - } - keepAlivePath.add(value); - path = value; - } - - void setPathForData(String value, dynamic data) { - _pathExtraMap[value] = data; - path = value; - } - - Future changePathForResult(String value) async { - Completer completer = Completer(); - _completerMap[value] = completer; - path = value; - return completer.future; - } - - set path(String value) { - if (_path == value) return; - _path = value; - /// 将路由加入历史列表 - _addPathToHistory(value,_pathExtraMap[path]); - notifyListeners(); - } - - void _addPathToHistory(String value, Object? extra) { - if (_histories.isNotEmpty && value == _histories.last.path) return; - _histories.add(RouteHistory( - value, - extra: _pathExtraMap[path], - )); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPages(path), - ); - } - - List _buildPages(path) { - List pages = []; - List topPages = _buildPageByPath(path); - - if (keepAlivePath.isNotEmpty) { - for (String alivePath in keepAlivePath) { - if (alivePath != path) { - pages.addAll(_buildPageByPath(alivePath)); - } - } - - /// 去除和 topPages 中重复的界面 - pages.removeWhere( - (element) => topPages.map((e) => e.key).contains(element.key)); - } - - pages.addAll(topPages); - return pages; - } - - List _buildPageByPath(String path) { - Widget? child; - if (path.startsWith('/color')) { - return buildColorPages(path); - } - - if (path == kDestinationsPaths[1]) { - child = const CounterPage(); - } - if (path == kDestinationsPaths[2]) { - child = const UserPage(); - } - if (path == kDestinationsPaths[3]) { - child = const SettingPage(); - } - return [ - FadeTransitionPage( - key: ValueKey(path), - child: child ?? const EmptyPage(), - ) - ]; - } - - List buildColorPages(String path) { - List 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 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), - )); - } else { - Color? selectedColor = _pathExtraMap[path]; - if (selectedColor != null) { - result.add(FadeTransitionPage( - key: const ValueKey('/color/detail'), - child: ColorDetailPage(color: selectedColor), - )); - _pathExtraMap.remove(path); - } - } - } - if (segment == 'add') { - result.add(const FadeTransitionPage( - key: ValueKey('/color/add'), - child: ColorAddPage(), - )); - } - } - return result; - } - - @override - Future 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 parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} diff --git a/lib/v6/app/navigation/router/iroute.dart b/lib/v6/app/navigation/router/iroute.dart deleted file mode 100644 index b703af9..0000000 --- a/lib/v6/app/navigation/router/iroute.dart +++ /dev/null @@ -1,37 +0,0 @@ -class IRoute { - final String path; - final List children; - - const IRoute({required this.path, this.children = const []}); - - @override - String toString() { - return 'IRoute{path: $path, children: $children}'; - } - - List list(){ - - return []; - } - -} - - -const List kDestinationsIRoutes = [ - IRoute( - path: '/color', - children: [ - IRoute(path: '/color/add'), - IRoute(path: '/color/detail'), - ], - ), - IRoute( - path: '/counter', - ), - IRoute( - path: '/user', - ), - IRoute( - path: '/settings', - ), -]; diff --git a/lib/v6/app/navigation/router/route_history.dart b/lib/v6/app/navigation/router/route_history.dart deleted file mode 100644 index 02b5430..0000000 --- a/lib/v6/app/navigation/router/route_history.dart +++ /dev/null @@ -1,6 +0,0 @@ -class RouteHistory{ - final String path; - final Object? extra; - - RouteHistory(this.path, { this.extra}); -} \ No newline at end of file diff --git a/lib/v6/app/navigation/transition/fade_transition_page.dart b/lib/v6/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index 552171b..0000000 --- a/lib/v6/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => - PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v6/app/navigation/transition/no_transition_page.dart b/lib/v6/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v6/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v6/app/navigation/views/app_navigation.dart b/lib/v6/app/navigation/views/app_navigation.dart deleted file mode 100644 index 5abca82..0000000 --- a/lib/v6/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v6/app/navigation/views/app_navigation_rail.dart b/lib/v6/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index b47b8ef..0000000 --- a/lib/v6/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined), - MenuMeta(label: '计数器', icon: Icons.add_chart), - MenuMeta(label: '我的', icon: Icons.person), - MenuMeta(label: '设置', icon: Icons.settings), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text('V0.0.6',style: TextStyle(color: Colors.white,fontSize: 12),), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: router.activeIndex, - ), - ); - - } - - void _onDestinationSelected(int index) { - if(index==1){ - router.setPathKeepLive(kDestinationsPaths[index]); - }else{ - router.path=kDestinationsPaths[index]; - } - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v6/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v6/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index 40516a7..0000000 --- a/lib/v6/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v6/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v6/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index cd9bb25..0000000 --- a/lib/v6/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import 'app_router_editor.dart'; -import 'history_view_icon.dart'; -import 'route_history_button.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - RouteHistoryButton(), - const SizedBox(width: 12,), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.path = path, - )), - const SizedBox(width: 12,), - HistoryViewIcon(), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -Map kRouteLabelMap = { - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/user': '我的', - '/settings': '系统设置', -}; - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.path = item.to!; - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - return result; - } -} diff --git a/lib/v6/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v6/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index e7dd0a5..0000000 --- a/lib/v6/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,156 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/route_history.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar() { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: router.clearHistory, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final RouteHistory history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(widget.history.path), - const SizedBox( - height: 2, - ), - Text(kRouteLabelMap[widget.history.path]!), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if(router.histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: router.histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - int fixIndex = router.histories.length - 1 - index; - router.closeHistory(fixIndex); - }, - onPressed: (){ - router.toHistory(router.histories[index]); - Navigator.of(context).pop(); - }, - history: router.histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v6/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v6/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index e02439f..0000000 --- a/lib/v6/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = router.hasHistory; - bool hasBackHistory = router.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?router.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?router.revocation:null, - ), - ], - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v6/app/unit_app.dart b/lib/v6/app/unit_app.dart deleted file mode 100644 index 1a21114..0000000 --- a/lib/v6/app/unit_app.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/router/app_router_delegate.dart'; -import 'navigation/views/app_navigation.dart'; -import 'navigation/views/app_navigation_rail.dart'; - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return MaterialApp( - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation() - ); - } -} - - diff --git a/lib/v6/pages/color/color_add_page.dart b/lib/v6/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v6/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v6/pages/color/color_detail_page.dart b/lib/v6/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v6/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v6/pages/color/color_page.dart b/lib/v6/pages/color/color_page.dart deleted file mode 100644 index e7b88da..0000000 --- a/lib/v6/pages/color/color_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.setPathForData('/color/detail',color); - - } - - void _toAddPage() async { - Color? color = await router.changePathForResult('/color/add'); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v6/pages/counter/counter_page.dart b/lib/v6/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v6/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v6/pages/empty/empty_page.dart b/lib/v6/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v6/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v6/pages/settings/settings_page.dart b/lib/v6/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v6/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v6/pages/sort/sort_page.dart b/lib/v6/pages/sort/sort_page.dart deleted file mode 100644 index d440071..0000000 --- a/lib/v6/pages/sort/sort_page.dart +++ /dev/null @@ -1,859 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; - -class SortPage extends StatefulWidget { - const SortPage({Key? key}) : super(key: key); - - @override - State createState() => _SortPageState(); -} - -class _SortPageState extends State { - //存放随机数组 - List numbers = []; - - //订阅流 - StreamController> streamController = StreamController(); - String currentSort = 'bubble'; - - //柱子的数量 -> 生成排序数组的长度 - double sampleSize = 0; - - //是否排序 - bool isSorted = false; - - //是否在排序中 - bool isSorting = false; - - //排序动画更新的速度 - int speed = 0; - - static int duration = 1500; - - String getTitle() { - switch (currentSort) { - case "bubble": - return "Bubble Sort"; - case "coctail": - return "Coctail Sort"; - case "comb": - return "Comb Sort"; - case "pigeonhole": - return "Pigeonhole Sort"; - case "shell": - return "Shell Sort"; - case "selection": - return "Selection Sort"; - case "cycle": - return "Cycle Sort"; - case "heap": - return "Heap Sort"; - case "insertion": - return "Insertion Sort"; - case "gnome": - return "Gnome Sort"; - case "oddeven": - return "OddEven Sort"; - case "quick": - return "Quick Sort"; - case "merge": - return "Merge Sort"; - } - return ""; - } - - reset() { - isSorted = false; - numbers = []; - for (int i = 0; i < sampleSize; ++i) { - numbers.add(Random().nextInt(500)); - } - streamController.add(numbers); - } - - Duration getDuration() { - return Duration(microseconds: duration); - } - - ///动画时间 - changeSpeed() { - if (speed >= 3) { - speed = 0; - duration = 1500; - } else { - speed++; - duration = duration ~/ 2; - } - setState(() {}); - } - - ///冒泡排序 - bubbleSort() async { - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < numbers.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < numbers.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (numbers[j] > numbers[j + 1]) { - int temp = numbers[j]; - numbers[j] = numbers[j + 1]; - numbers[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); - } - } - } - - ///鸡尾酒排序(双向冒泡排序) - cocktailSort() async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = numbers.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } - } - - ///梳排序(Comb Sort) - combSort() async { - int gap = numbers.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < numbers.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (numbers[i] > numbers[i + gap]) { - int temp = numbers[i]; - numbers[i] = numbers[i + gap]; - numbers[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; - } - - ///鸽巢排序 - pigeonHole() async { - int min = numbers[0]; - int max = numbers[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < numbers.length; a++) { - if (numbers[a] > max) max = numbers[a]; - if (numbers[a] < min) min = numbers[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < numbers.length; i++) { - p[numbers[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - numbers[index++] = j + min; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///希尔排序 - shellSort() async { - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = numbers.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < numbers.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = numbers[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && numbers[j - gap] > temp; j -= gap) { - numbers[j] = numbers[j - gap]; - } - numbers[j] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///选择排序 - selectionSort() async { - for (int i = 0; i < numbers.length; i++) { - for (int j = i + 1; j < numbers.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (numbers[i] > numbers[j]) { - // 判断当前元素是否比后续元素小 - int temp = numbers[j]; - // 交换当前元素和后续较小的元素 - numbers[j] = numbers[i]; - numbers[i] = temp; - } - - await Future.delayed(getDuration(), () {}); - - streamController.add(numbers); - } - } - } - - ///循环排序 - cycleSort() async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= numbers.length - 2; cycleStart++) { - int item = numbers[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < numbers.length; i++) { - if (numbers[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == numbers[pos]) { - pos += 1; - } - if (item != numbers[pos]) { - int temp = item; - item = numbers[pos]; - numbers[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - ///堆排序 - heapSort() async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = numbers.length ~/ 2; i >= 0; i--) { - await heapify(numbers, numbers.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = numbers.length - 1; i >= 0; i--) { - int temp = numbers[0]; - numbers[0] = numbers[i]; - numbers[i] = temp; - await heapify(numbers, i, 0); - streamController.add(numbers); - } - } - - heapify(List arr, int n, int i) async { - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && arr[l] > arr[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && arr[r] > arr[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = numbers[i]; - numbers[i] = numbers[largest]; - numbers[largest] = temp; - heapify(arr, n, largest); - } - - await Future.delayed(getDuration()); // 延迟操作,用于可视化排序过程 - streamController.add(numbers); - } - - ///插入排序 - insertionSort() async { - for (int i = 1; i < numbers.length; i++) { - int temp = numbers[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < numbers[j]) { - numbers[j + 1] = numbers[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - await Future.delayed(getDuration()); - streamController.add(numbers); // 更新排序结果 - } - - numbers[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await Future.delayed(getDuration(), () {}); - streamController.add(numbers); // 更新排序结果 - } - } - - ///地精排序 (侏儒排序) - gnomeSort() async { - int index = 0; - - while (index < numbers.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (numbers[index] >= numbers[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = numbers[index]; - numbers[index] = numbers[index - 1]; - numbers[index - 1] = temp; - index--; - } - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - return; - } - - ///奇偶排序(Odd-Even Sort) - oddEvenSort() async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= numbers.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - for (int i = 0; i <= numbers.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (numbers[i] > numbers[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = numbers[i]; - numbers[i] = numbers[i + 1]; - numbers[i + 1] = temp; - isSorted = false; - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - } - - return; - } - - ///快速排序 - quickSort(int leftIndex, int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async{ - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = numbers[p]; - numbers[p] = numbers[right]; - numbers[right] = temp; - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(numbers[i], numbers[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = numbers[i]; - numbers[i] = numbers[cursor]; - numbers[cursor] = temp; - cursor++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 将基准元素放置在游标位置 - temp = numbers[right]; - numbers[right] = numbers[cursor]; - numbers[cursor] = temp; - - await Future.delayed(getDuration()); - streamController.add(numbers); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await quickSort(leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await quickSort(p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } - } - - // 比较函数,用于判断两个元素的大小关系 - cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } - } - - ///归并排序 - mergeSort(int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = numbers[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = numbers[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - numbers[k] = leftList[i]; - i++; - } else { - numbers[k] = rightList[j]; - j++; - } - - await Future.delayed(getDuration()); - streamController.add(numbers); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - numbers[k] = leftList[i]; - i++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - - while (j < rightSize) { - numbers[k] = rightList[j]; - j++; - k++; - - await Future.delayed(getDuration()); - streamController.add(numbers); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await mergeSort(leftIndex, middleIndex); - await mergeSort(middleIndex + 1, rightIndex); - - await Future.delayed(getDuration()); - streamController.add(numbers); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } - } - - checkAndResetIfSorted() async { - if (isSorted) { - reset(); - await Future.delayed(const Duration(milliseconds: 200)); - } - } - - sort() async { - setState(() { - isSorting = true; - }); - - await checkAndResetIfSorted(); - - Stopwatch stopwatch = Stopwatch()..start(); - - switch (currentSort) { - case "bubble": - await bubbleSort(); - break; - case "coctail": - await cocktailSort(); - break; - case "comb": - await combSort(); - break; - case "pigeonhole": - await pigeonHole(); - break; - case "shell": - await shellSort(); - break; - case "selection": - await selectionSort(); - break; - case "cycle": - await cycleSort(); - break; - case "heap": - await heapSort(); - break; - case "insertion": - await insertionSort(); - break; - case "gnome": - await gnomeSort(); - break; - case "oddeven": - await oddEvenSort(); - break; - case "quick": - await quickSort(0, sampleSize.toInt() - 1); - break; - case "merge": - await mergeSort(0, sampleSize.toInt() - 1); - break; - } - - stopwatch.stop(); - - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - setState(() { - isSorting = false; - isSorted = true; - }); - } - - setSort(String type) { - setState(() { - currentSort = type; - }); - } - - @override - void initState() { - super.initState(); - // reset(); - } - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - sampleSize = MediaQuery.of(context).size.width / 2; - for (int i = 0; i < sampleSize; ++i) { - //随机往数组中填值 - numbers.add(Random().nextInt(500)); - } - setState(() {}); - } - - @override - void dispose() { - streamController.close(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text( - "当前选择的是:${getTitle()}", - style: const TextStyle(fontSize: 14), - ), - actions: [ - PopupMenuButton( - initialValue: currentSort, - itemBuilder: (ctx) { - return const [ - PopupMenuItem( - value: 'bubble', - child: Text("Bubble Sort — 冒泡排序"), - ), - PopupMenuItem( - value: 'coctail', - child: Text("Coctail Sort — 鸡尾酒排序(双向冒泡排序)"), - ), - PopupMenuItem( - value: 'comb', - child: Text("Comb Sort — 梳排序"), - ), - PopupMenuItem( - value: 'pigeonhole', - child: Text("pigeonhole Sort — 鸽巢排序"), - ), - PopupMenuItem( - value: 'shell', - child: Text("shell Sort — 希尔排序"), - ), - PopupMenuItem( - value: 'selection', - child: Text("Selection Sort — 选择排序"), - ), - PopupMenuItem( - value: 'cycle', - child: Text("CycleSort — 循环排序"), - ), - PopupMenuItem( - value: 'heap', - child: Text("HeapSort — 堆排序"), - ), - PopupMenuItem( - value: 'insertion', - child: Text("InsertionSort — 插入排序"), - ), - PopupMenuItem( - value: 'gnome', - child: Text("GnomeSort — 地精排序 (侏儒排序)"), - ), - PopupMenuItem( - value: 'oddeven', - child: Text("OddEvenSort — 奇偶排序"), - ), - PopupMenuItem( - value: 'quick', - child: Text("QuickSort — 快速排序"), - ), - PopupMenuItem( - value: 'merge', - child: Text("MergeSort — 归并排序"), - ), - ]; - }, - onSelected: (String value) { - reset(); - setSort(value); - }, - ) - ], - ), - body: StreamBuilder( - initialData: numbers, - stream: streamController.stream, - builder: (context, snapshot) { - List numbers = snapshot.data as List; - int counter = 0; - return Row( - children: numbers.map((int num) { - counter++; - return CustomPaint( - painter: BarPainter( - width: MediaQuery.of(context).size.width / sampleSize, - value: num, - index: counter, - ), - ); - }).toList(), - ); - }, - ), - bottomNavigationBar: BottomAppBar( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: isSorting - ? null - : () { - reset(); - setSort(currentSort); - }, - child: const Text("重置")), - ElevatedButton( - onPressed: isSorting ? null : sort, child: const Text("开始排序")), - ElevatedButton( - onPressed: isSorting ? null : changeSpeed, - child: Text( - "${speed + 1}x", - style: const TextStyle(fontSize: 20), - ), - ), - ], - ), - ), - ); - } -} - -class BarPainter extends CustomPainter { - //宽度 - final double width; - - //高度(数组中对应的值) - final int value; - - //位置索引 - final int index; - - BarPainter({required this.width, required this.value, required this.index}); - - @override - void paint(Canvas canvas, Size size) { - Paint paint = Paint(); - if (value < 500 * .10) { - paint.color = Colors.blue.shade100; - } else if (value < 500 * .20) { - paint.color = Colors.blue.shade200; - } else if (value < 500 * .30) { - paint.color = Colors.blue.shade300; - } else if (value < 500 * .40) { - paint.color = Colors.blue.shade400; - } else if (value < 500 * .50) { - paint.color = Colors.blue.shade500; - } else if (value < 500 * .60) { - paint.color = Colors.blue.shade600; - } else if (value < 500 * .70) { - paint.color = Colors.blue.shade700; - } else if (value < 500 * .80) { - paint.color = Colors.blue.shade800; - } else if (value < 500 * .90) { - paint.color = Colors.blue.shade900; - } else { - paint.color = const Color(0xFF011E51); - } - - paint.strokeWidth = width; - paint.strokeCap = StrokeCap.round; - - canvas.drawLine( - Offset(index * width, 0), - Offset( - index * width, - value.ceilToDouble(), - ), - paint); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) { - return true; - } -} diff --git a/lib/v6/pages/user/user_page.dart b/lib/v6/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v6/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v7/app.dart b/lib/v7/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v7/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v7/app/navigation/router/app_router_delegate.dart b/lib/v7/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index be3d580..0000000 --- a/lib/v7/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,177 +0,0 @@ -import 'dart:async'; -import 'package:flutter/material.dart'; -import 'iroute.dart'; -import 'iroute_config.dart'; -import 'route_history_manager.dart'; -import 'routes.dart'; -import 'views/not_find_view.dart'; - -AppRouterDelegate router = AppRouterDelegate(); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - String _path = '/color'; - - String get path => _path; - - final IRoutePageBuilder? notFindPageBuilder; - - AppRouterDelegate({this.notFindPageBuilder}) { - _historyManager.recode(IRouteConfig(uri: Uri.parse(path))); - } - - Page _defaultNotFindPageBuilder(_, __) => const MaterialPage( - child: Material(child: NotFindPage()), - ); - - final RouteHistoryManager _historyManager = RouteHistoryManager(); - - RouteHistoryManager get historyManager => _historyManager; - - /// 历史回退操作 - /// 详见: [RouteHistoryManager.back] - void back() => _historyManager.back(changeRoute); - - /// 撤销回退操作 - /// 详见: [RouteHistoryManager.revocation] - void revocation() => _historyManager.revocation(changeRoute); - - void closeHistory(int index) { - _historyManager.close(index); - notifyListeners(); - } - - void clearHistory() { - _historyManager.clear(); - notifyListeners(); - } - - final Map> _completerMap = {}; - final Map _pathExtraMap = {}; - final List keepAlivePath = []; - - FutureOr changeRoute(IRouteConfig config) { - String value = config.uri.path; - if (_path == value) null; - if (config.forResult) { - _completerMap[value] = Completer(); - } - if (config.keepAlive) { - if (keepAlivePath.contains(value)) { - keepAlivePath.remove(value); - } - keepAlivePath.add(value); - } - if (config.extra != null) { - _pathExtraMap[value] = config.extra; - } - - if (config.recordHistory) { - _historyManager.recode(config); - } - - _path = value; - notifyListeners(); - if (config.forResult) { - return _completerMap[value]!.future; - } - } - - FutureOr changePath( - String value, { - bool forResult = false, - Object? extra, - bool keepAlive = false, - bool recordHistory = true, - }) { - return changeRoute(IRouteConfig( - uri: Uri.parse(value), - forResult: forResult, - extra: extra, - keepAlive: keepAlive, - recordHistory: recordHistory, - )); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPages(context, path), - ); - } - - List _buildPages(BuildContext context, String path) { - List pages = []; - List topPages = _buildPageByPathFromTree(context, path); - - if (keepAlivePath.isNotEmpty) { - for (String alivePath in keepAlivePath) { - if (alivePath != path) { - pages.addAll(_buildPageByPathFromTree(context, alivePath)); - } - } - - /// 去除和 topPages 中重复的界面 - pages.removeWhere( - (element) => topPages.map((e) => e.key).contains(element.key)); - } - - pages.addAll(topPages); - return pages; - } - - List _buildPageByPathFromTree(BuildContext context, String path) { - List result = []; - List iRoutes = rootRoute.find(path); - if (iRoutes.isNotEmpty) { - for (int i = 0; i < iRoutes.length; i++) { - IRouteNode iroute = iRoutes[i]; - String path = iroute.path; - Object? extra = _pathExtraMap[path]; - bool keepAlive = keepAlivePath.contains(path); - bool forResult = _completerMap.containsKey(path); - IRouteConfig config = IRouteConfig( - uri: Uri.parse(path), - extra: extra, - keepAlive: keepAlive, - forResult: forResult, - ); - Page? page; - if (iroute is NotFindNode) { - page = (notFindPageBuilder ?? _defaultNotFindPageBuilder)(context, config); - } else { - page = iroute.createPage(context, config); - } - if (page != null) { - result.add(page); - } - } - } - return result; - } - - @override - Future popRoute() async { - print('=======popRoute========='); - return true; - } - - bool _onPopPage(Route route, result) { - if (_completerMap.containsKey(path)) { - _completerMap[path]?.complete(result); - _completerMap.remove(path); - } - changePath(backPath(path), recordHistory: false); - return route.didPop(result); - } - - String backPath(String path) { - Uri uri = Uri.parse(path); - if (uri.pathSegments.length == 1) return path; - List parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} diff --git a/lib/v7/app/navigation/router/iroute.dart b/lib/v7/app/navigation/router/iroute.dart deleted file mode 100644 index ce6e132..0000000 --- a/lib/v7/app/navigation/router/iroute.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'iroute_config.dart'; - -typedef IRoutePageBuilder = Page? Function( - BuildContext context, - IRouteConfig data, -); - -typedef IRouteWidgetBuilder = Widget? Function( - BuildContext context, - IRouteConfig data, -); - -abstract class IRouteNode { - final String path; - final List children; - - const IRouteNode({ - required this.path, - required this.children, - }); - - Page? createPage(BuildContext context, IRouteConfig config); - - List find(String input,) { - return findNodes(this, Uri.parse(input), 0, '/', []); - } - - List findNodes( - IRouteNode node, - Uri uri, - int deep, - String prefix, - List result, - ) { - List parts = uri.pathSegments; - if (deep > parts.length - 1) { - return result; - } - String target = parts[deep]; - if (node.children.isNotEmpty) { - target = prefix + target; - List nodes = node.children.where((e) => e.path == target).toList(); - bool match = nodes.isNotEmpty; - if (match) { - IRouteNode matched = nodes.first; - result.add(matched); - String nextPrefix = '${matched.path}/'; - findNodes(matched, uri, ++deep, nextPrefix, result); - }else{ - result.add(NotFindNode(path: target)); - return result; - } - } - return result; - } -} - -/// 优先调用 [pageBuilder] 构建 Page -/// 没有 [pageBuilder] 时, 使用 [widgetBuilder] 构建组件 -/// 没有 [pageBuilder] 和 [widgetBuilder] 时, 使用 [widget] 构建组件 -class IRoute extends IRouteNode { - final IRoutePageBuilder? pageBuilder; - final IRouteWidgetBuilder? widgetBuilder; - final Widget? widget; - final Map? mata; - - const IRoute({ - required super.path, - super.children = const [], - this.mata, - this.widget, - this.pageBuilder, - this.widgetBuilder, - }); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - if (pageBuilder != null) { - return pageBuilder!(context, config); - } - Widget? child; - if (widgetBuilder != null) { - child = widgetBuilder!(context, config); - } - child ??= widget; - if (child != null) { - return MaterialPage(child: child, key: config.pageKey); - } - return null; - } -} - - - -class NotFindNode extends IRouteNode{ - NotFindNode({required super.path, super.children= const[]}); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - return null; - } -} - diff --git a/lib/v7/app/navigation/router/iroute_config.dart b/lib/v7/app/navigation/router/iroute_config.dart deleted file mode 100644 index 36a58ed..0000000 --- a/lib/v7/app/navigation/router/iroute_config.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; - -class IRouteConfig { - final Object? extra; - final bool forResult; - final Uri uri; - final bool keepAlive; - final bool recordHistory; - - const IRouteConfig({ - this.extra, - required this.uri, - this.forResult = false, - this.keepAlive = false, - this.recordHistory = false, - }); - - String get path => uri.path; - - IRouteConfig copyWith({ - Object? extra, - bool? forResult, - bool? keepAlive, - bool? recordHistory, - }) => - IRouteConfig( - extra: extra ?? this.extra, - forResult: forResult ?? this.forResult, - keepAlive: keepAlive ?? this.keepAlive, - recordHistory: recordHistory ?? this.recordHistory, - uri: uri, - ); - - ValueKey get pageKey => ValueKey(path); -} diff --git a/lib/v7/app/navigation/router/route_history_manager.dart b/lib/v7/app/navigation/router/route_history_manager.dart deleted file mode 100644 index 8844898..0000000 --- a/lib/v7/app/navigation/router/route_history_manager.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'iroute_config.dart'; - -typedef OnRouteChange = void Function(IRouteConfig config); - -class RouteHistoryManager{ - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories.reversed.toList(); - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 将 [config] 加入历史记录 - void recode(IRouteConfig config){ - if (_histories.isNotEmpty && config.path == _histories.last.path) return; - _histories.add(config); - } - - /// 历史回退操作 - /// 将当前顶层移除,并加入 [_backHistories] 撤销列表 - /// 并转到前一路径 [_histories.last] - void back(OnRouteChange callback) { - if (!hasHistory) return; - IRouteConfig top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - callback(_histories.last); - } - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation(OnRouteChange callback) { - IRouteConfig target = _backHistories.removeLast(); - callback(target); - } - - void close(int index) { - _histories.removeAt(index); - } - - void clear() { - _histories.clear(); - } -} \ No newline at end of file diff --git a/lib/v7/app/navigation/router/routes.dart b/lib/v7/app/navigation/router/routes.dart deleted file mode 100644 index 0400bde..0000000 --- a/lib/v7/app/navigation/router/routes.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'iroute_config.dart'; -import 'iroute.dart'; -import '../../../pages/color/color_add_page.dart'; -import '../../../pages/color/color_detail_page.dart'; -import '../../../pages/color/color_page.dart'; -import '../../../pages/counter/counter_page.dart'; -import '../../../pages/user/user_page.dart'; -import '../../../pages/settings/settings_page.dart'; -import '../../../pages/sort/views/sort_page.dart'; - - -IRoute rootRoute = const IRoute( - path: 'root', - children: [ - IRoute( - path: '/color', - widget: ColorPage(), - children: [ - IRoute(path: '/color/detail', widgetBuilder: _buildColorDetail), - IRoute(path: '/color/add', widget: ColorAddPage()), - ], - ), - IRoute(path: '/counter', widget: CounterPage()), - IRoute(path: '/sort', widget: SortPage()), - IRoute(path: '/user', widget: UserPage()), - IRoute(path: '/settings', widget: SettingPage()), - ], -); - -Widget? _buildColorDetail(BuildContext context, IRouteConfig data) { - final Map queryParams = data.uri.queryParameters; - String? selectedColor = queryParams['color']; - Color color = Colors.black; - if (selectedColor != null) { - color = Color(int.parse(selectedColor, radix: 16)); - } else if (data.extra is Color) { - color = data.extra as Color; - } - return ColorDetailPage(color: color); -} diff --git a/lib/v7/app/navigation/router/views/not_find_view.dart b/lib/v7/app/navigation/router/views/not_find_view.dart deleted file mode 100644 index ccefa16..0000000 --- a/lib/v7/app/navigation/router/views/not_find_view.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotFindPage extends StatelessWidget { - const NotFindPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Material( - child: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - '404 Page Not Find', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ); - } -} diff --git a/lib/v7/app/navigation/transition/fade_page_transitions_builder.dart b/lib/v7/app/navigation/transition/fade_page_transitions_builder.dart deleted file mode 100644 index 0587ecc..0000000 --- a/lib/v7/app/navigation/transition/fade_page_transitions_builder.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class FadePageTransitionsBuilder extends PageTransitionsBuilder { - - const FadePageTransitionsBuilder(); - - @override - Widget buildTransitions( - PageRoute? route, - BuildContext? context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return _FadePagePageTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - child: child, - ); - } -} - -class _FadePagePageTransition extends StatelessWidget { - - const _FadePagePageTransition({ - required this.animation, - required this.secondaryAnimation, - required this.child, - }); - - final Animation animation; - final Animation secondaryAnimation; - final Widget child; - - @override - Widget build(BuildContext context) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: child, - ); - } -} \ No newline at end of file diff --git a/lib/v7/app/navigation/transition/fade_transition_page.dart b/lib/v7/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index fc4e6e6..0000000 --- a/lib/v7/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v7/app/navigation/transition/no_transition_page.dart b/lib/v7/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v7/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v7/app/navigation/views/app_navigation.dart b/lib/v7/app/navigation/views/app_navigation.dart deleted file mode 100644 index 5abca82..0000000 --- a/lib/v7/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v7/app/navigation/views/app_navigation_rail.dart b/lib/v7/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 67a986c..0000000 --- a/lib/v7/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined,path: '/color'), - MenuMeta(label: '计数器', icon: Icons.add_chart,path: '/counter'), - MenuMeta(label: '排序', icon: Icons.sort,path: '/sort'), - MenuMeta(label: '我的', icon: Icons.person,path: '/user'), - MenuMeta(label: '设置', icon: Icons.settings,path: '/settings'), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text('V0.0.7',style: TextStyle(color: Colors.white,fontSize: 12),), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: activeIndex, - ), - ); - } - - RegExp _segReg = RegExp(r'/\w+'); - - int? get activeIndex{ - String path = router.path; - RegExpMatch? match = _segReg.firstMatch(path); - if(match==null) return null; - String? target = match.group(0); - int index = deskNavBarMenus.indexWhere((menu) => menu.path==target); - if(index==-1) return null; - return index; -} - - void _onDestinationSelected(int index) { - String path = deskNavBarMenus[index].path!; - if(index==1){ - router.changePath(path,keepAlive: true); - }else{ - router.changePath(path); - } - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v7/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v7/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index 40516a7..0000000 --- a/lib/v7/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v7/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v7/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index ad7d875..0000000 --- a/lib/v7/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import 'app_router_editor.dart'; -import 'history_view_icon.dart'; -import 'route_history_button.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - RouteHistoryButton(), - const SizedBox(width: 12,), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.changePath(path), - )), - const SizedBox(width: 12,), - HistoryViewIcon(), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -Map kRouteLabelMap = { - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/sort': '可视化排序算法', - '/user': '我的', - '/settings': '系统设置', -}; - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.changePath(item.to!); - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - return result; - } -} diff --git a/lib/v7/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v7/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index 6ba4926..0000000 --- a/lib/v7/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,157 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/iroute_config.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar() { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: router.clearHistory, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final IRouteConfig history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(widget.history.path), - const SizedBox( - height: 2, - ), - Text(kRouteLabelMap[widget.history.path]??'未知路由'), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List histories = router.historyManager.histories; - if(histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - int fixIndex = histories.length - 1 - index; - router.closeHistory(fixIndex); - }, - onPressed: (){ - router.changeRoute(histories[index].copyWith(recordHistory: false)); - Navigator.of(context).pop(); - }, - history: histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v7/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v7/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index 3ee6513..0000000 --- a/lib/v7/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = router.historyManager.hasHistory; - bool hasBackHistory = router.historyManager.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?router.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?router.revocation:null, - ), - ], - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v7/app/unit_app.dart b/lib/v7/app/unit_app.dart deleted file mode 100644 index 33f59bf..0000000 --- a/lib/v7/app/unit_app.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import '../pages/sort/provider/state.dart'; -import 'navigation/transition/fade_page_transitions_builder.dart'; -import 'navigation/views/app_navigation.dart'; - - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return SortStateScope( - notifier: SortState(), - child: MaterialApp( - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - } - ), - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation() - ), - ); - } -} - - diff --git a/lib/v7/pages/color/color_add_page.dart b/lib/v7/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v7/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v7/pages/color/color_detail_page.dart b/lib/v7/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v7/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v7/pages/color/color_page.dart b/lib/v7/pages/color/color_page.dart deleted file mode 100644 index 8fdbe13..0000000 --- a/lib/v7/pages/color/color_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.changePath('/color/detail',extra: color); - - } - - void _toAddPage() async { - Color? color = await router.changePath('/color/add',forResult: true,recordHistory: false); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v7/pages/counter/counter_page.dart b/lib/v7/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v7/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v7/pages/empty/empty_page.dart b/lib/v7/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v7/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v7/pages/settings/settings_page.dart b/lib/v7/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v7/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v7/pages/sort/functions.dart b/lib/v7/pages/sort/functions.dart deleted file mode 100644 index 6ae1176..0000000 --- a/lib/v7/pages/sort/functions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'functions/bubble.dart'; -import 'functions/cocktail.dart'; -import 'functions/comb.dart'; -import 'functions/cycle.dart'; -import 'functions/gnome.dart'; -import 'functions/heap.dart'; -import 'functions/insertion.dart'; -import 'functions/merage.dart'; -import 'functions/pigeonHole.dart'; -import 'functions/quick.dart'; -import 'functions/selection.dart'; -import 'functions/shell.dart'; - -typedef SortFunction = Future Function(List src, SortCallback callback); -typedef SortCallback = Future Function(List dist); - -Map sortFunctionMap = { - 'insertion': insertionSort, - 'bubble': bubbleSort, - 'cocktail': cocktailSort, - 'comb': combSort, - 'pigeonHole': pigeonHoleSort, - 'shell': shellSort, - 'selection': selectionSort, - 'gnome': gnomeSort, - 'cycle': cycleSort, - 'heap': heapSort, - 'quick': quickSort, - 'mergeSort': mergeSort, -}; - -Map sortNameMap = { - 'insertion': '插入排序', - 'bubble': '冒泡排序', - 'cocktail': '鸡尾酒排序(双向冒泡排序)', - 'comb': '梳排序', - 'pigeonHole': '鸽巢排序', - 'shell': '希尔排序', - 'selection': '选择排序', - 'gnome': '侏儒排序', - 'cycle': '循环排序', - 'heap': '堆排序', - 'quick': '快速排序', - 'mergeSort': '归并排序', -}; - diff --git a/lib/v7/pages/sort/functions/bubble.dart b/lib/v7/pages/sort/functions/bubble.dart deleted file mode 100644 index 3cf3c99..0000000 --- a/lib/v7/pages/sort/functions/bubble.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///冒泡排序 -Future bubbleSort(List src, SortCallback callback ) async{ - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < src.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < src.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (src[j] > src[j + 1]) { - int temp = src[j]; - src[j] = src[j + 1]; - src[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/cocktail.dart b/lib/v7/pages/sort/functions/cocktail.dart deleted file mode 100644 index 8c2d18c..0000000 --- a/lib/v7/pages/sort/functions/cocktail.dart +++ /dev/null @@ -1,52 +0,0 @@ -import '../functions.dart'; - -///鸡尾酒排序(双向冒泡排序) -Future cocktailSort(List src, SortCallback callback ) async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = src.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/comb.dart b/lib/v7/pages/sort/functions/comb.dart deleted file mode 100644 index 821f4a9..0000000 --- a/lib/v7/pages/sort/functions/comb.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '../functions.dart'; - -///梳排序(Comb Sort) -Future combSort(List src, SortCallback callback) async{ - int gap = src.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < src.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (src[i] > src[i + gap]) { - int temp = src[i]; - src[i] = src[i + gap]; - src[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await callback(src); - } - } -} - -int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/cycle.dart b/lib/v7/pages/sort/functions/cycle.dart deleted file mode 100644 index 4bef6eb..0000000 --- a/lib/v7/pages/sort/functions/cycle.dart +++ /dev/null @@ -1,54 +0,0 @@ -import '../functions.dart'; - -///循环排序 -Future cycleSort(List src, SortCallback callback) async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) { - int item = src[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (item != src[pos]) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/gnome.dart b/lib/v7/pages/sort/functions/gnome.dart deleted file mode 100644 index 5e08fc3..0000000 --- a/lib/v7/pages/sort/functions/gnome.dart +++ /dev/null @@ -1,22 +0,0 @@ -import '../functions.dart'; - -///地精排序 (侏儒排序) -Future gnomeSort(List src, SortCallback callback) async { - int index = 0; - while (index < src.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (src[index] >= src[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = src[index]; - src[index] = src[index - 1]; - src[index - 1] = temp; - index--; - } - await callback(src); - } - return; -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/heap.dart b/lib/v7/pages/sort/functions/heap.dart deleted file mode 100644 index 9f5410b..0000000 --- a/lib/v7/pages/sort/functions/heap.dart +++ /dev/null @@ -1,38 +0,0 @@ -import '../functions.dart'; - -///堆排序 -Future heapSort(List src, SortCallback callback) async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = src.length ~/ 2; i >= 0; i--) { - await heapify(src,callback, src.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = src.length - 1; i >= 0; i--) { - int temp = src[0]; - src[0] = src[i]; - src[i] = temp; - await heapify(src, callback,i, 0); - } -} - -Future heapify(List src, SortCallback callback, int n, int i) async{ - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && src[l] > src[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && src[r] > src[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = src[i]; - src[i] = src[largest]; - src[largest] = temp; - heapify(src,callback, n, largest); - } - await callback(src); -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/insertion.dart b/lib/v7/pages/sort/functions/insertion.dart deleted file mode 100644 index b1c7814..0000000 --- a/lib/v7/pages/sort/functions/insertion.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///插入排序 -Future insertionSort(List src, SortCallback callback) async { - for (int i = 1; i < src.length; i++) { - int temp = src[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < src[j]) { - src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - // 更新排序结果回调 - await callback(src); - } - src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await callback(src); - } -} diff --git a/lib/v7/pages/sort/functions/merage.dart b/lib/v7/pages/sort/functions/merage.dart deleted file mode 100644 index 12135b4..0000000 --- a/lib/v7/pages/sort/functions/merage.dart +++ /dev/null @@ -1,79 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future mergeSort(List src, SortCallback callback) async { - await _mergeSort(src,callback,0,src.length-1); -} - -///归并排序 -Future _mergeSort(List src, SortCallback callback,int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = src[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = src[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - src[k] = leftList[i]; - i++; - } else { - src[k] = rightList[j]; - j++; - } - - await callback(src); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - src[k] = leftList[i]; - i++; - k++; - - await callback(src); - } - - while (j < rightSize) { - src[k] = rightList[j]; - j++; - k++; - - await callback(src); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await _mergeSort(src,callback,leftIndex, middleIndex); - await _mergeSort(src,callback,middleIndex + 1, rightIndex); - - await callback(src); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/oddEven.dart b/lib/v7/pages/sort/functions/oddEven.dart deleted file mode 100644 index bd6f548..0000000 --- a/lib/v7/pages/sort/functions/oddEven.dart +++ /dev/null @@ -1,37 +0,0 @@ -import '../functions.dart'; - -///奇偶排序(Odd-Even Sort) -Future oddEvenSort(List src, SortCallback callback) async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= src.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await callback(src); - } - } - - for (int i = 0; i <= src.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; - await callback(src); - } - } - } - - return; -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/pigeonHole.dart b/lib/v7/pages/sort/functions/pigeonHole.dart deleted file mode 100644 index 83bbce1..0000000 --- a/lib/v7/pages/sort/functions/pigeonHole.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../functions.dart'; - -///鸽巢排序 -Future pigeonHoleSort(List src, SortCallback callback ) async{ - int min = src[0]; - int max = src[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < src.length; a++) { - if (src[a] > max) max = src[a]; - if (src[a] < min) min = src[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < src.length; i++) { - p[src[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - src[index++] = j + min; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/quick.dart b/lib/v7/pages/sort/functions/quick.dart deleted file mode 100644 index 25b9685..0000000 --- a/lib/v7/pages/sort/functions/quick.dart +++ /dev/null @@ -1,65 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future quickSort(List src, SortCallback callback) async { - await _quickSort(src,callback,0,src.length-1); -} - -///快速排序 -Future _quickSort(List src, SortCallback callback,int leftIndex,int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = src[p]; - src[p] = src[right]; - src[right] = temp; - await callback(src); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(src[i], src[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = src[i]; - src[i] = src[cursor]; - src[cursor] = temp; - cursor++; - await callback(src); - } - } - - // 将基准元素放置在游标位置 - temp = src[right]; - src[right] = src[cursor]; - src[cursor] = temp; - - await callback(src); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } -} - -// 比较函数,用于判断两个元素的大小关系 -cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/selection.dart b/lib/v7/pages/sort/functions/selection.dart deleted file mode 100644 index 185dae2..0000000 --- a/lib/v7/pages/sort/functions/selection.dart +++ /dev/null @@ -1,18 +0,0 @@ -import '../functions.dart'; - -///选择排序 -Future selectionSort(List src, SortCallback callback ) async { - for (int i = 0; i < src.length; i++) { - for (int j = i + 1; j < src.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (src[i] > src[j]) { - // 判断当前元素是否比后续元素小 - int temp = src[j]; - // 交换当前元素和后续较小的元素 - src[j] = src[i]; - src[i] = temp; - } - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/functions/shell.dart b/lib/v7/pages/sort/functions/shell.dart deleted file mode 100644 index 232f872..0000000 --- a/lib/v7/pages/sort/functions/shell.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../functions.dart'; - -///希尔排序 -Future shellSort(List src, SortCallback callback) async{ - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < src.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = src[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && src[j - gap] > temp; j -= gap) { - src[j] = src[j - gap]; - } - src[j] = temp; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v7/pages/sort/provider/sort_config.dart b/lib/v7/pages/sort/provider/sort_config.dart deleted file mode 100644 index 2ad50ed..0000000 --- a/lib/v7/pages/sort/provider/sort_config.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -class SortConfig { - final int count; - final int seed; - final Duration duration; - final String name; - - SortConfig({ - this.count = 100, - this.duration = const Duration(microseconds: 1500), - this.seed = -1, - this.name = 'insertion', - }); - - SortConfig copyWith({ - int? count, - int? seed, - Duration? duration, - String? name, - }) => - SortConfig( - count:count??this.count, - seed:seed??this.seed, - duration:duration??this.duration, - name:name??this.name, - ); -} - diff --git a/lib/v7/pages/sort/provider/state.dart b/lib/v7/pages/sort/provider/state.dart deleted file mode 100644 index 90803cf..0000000 --- a/lib/v7/pages/sort/provider/state.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/cupertino.dart'; - -import '../functions.dart'; -import 'sort_config.dart'; - -enum SortStatus{ - none, // 未操作 - sorting, // 排序中 - sorted, // 排序完成 -} - -class SortState with ChangeNotifier{ - - SortState(){ - reset(); - } - - SortStatus status = SortStatus.none; - - List data = []; - List stepData = []; - - SortConfig _config = SortConfig(); - SortConfig get config => _config; - Random random = Random(); - - set config(SortConfig config){ - _config = config; - reset(); - notifyListeners(); - } - - void selectName(String name){ - if(name==config.name) return; - config = config.copyWith(name: name); - } - - void reset(){ - data.clear(); - status = SortStatus.none; - notifyListeners(); - int count = config.count; - if(config.seed!=-1){ - random = Random(config.seed); - } - for (int i = 0; i < count; i++) { - //随机往数组中填值 - data.add(random.nextInt(1000)); - } - } - - void sort() async{ - status = SortStatus.sorting; - notifyListeners(); - Stopwatch stopwatch = Stopwatch()..start(); - SortFunction? sortFunction = sortFunctionMap[config.name]; - if(sortFunction!=null){ - await sortFunction(data,(arr) async { - await Future.delayed(config.duration); - notifyListeners(); - }); - } - status = SortStatus.sorted; - notifyListeners(); - stopwatch.stop(); - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - } -} - -/// Provides the current [SortState] to descendant widgets in the tree. -class SortStateScope extends InheritedNotifier { - const SortStateScope({ - required super.notifier, - required super.child, - super.key, - }); - - static SortState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; -} \ No newline at end of file diff --git a/lib/v7/pages/sort/views/data_painter.dart b/lib/v7/pages/sort/views/data_painter.dart deleted file mode 100644 index d23e2f5..0000000 --- a/lib/v7/pages/sort/views/data_painter.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:flutter/material.dart'; - - - -class DataPainter extends CustomPainter{ - - final List data; - - DataPainter({required this.data}); - - @override - void paint(Canvas canvas, Size size) { - double itemWidth = size.width/data.length; - double height = size.height; - - Paint paint = Paint(); - paint.strokeWidth = itemWidth; - paint.strokeCap = StrokeCap.round; - - for(int i=0;i numbers = state.data; - return Scaffold( - body: Row( - children: [ - SizedBox( - width: 220, - child: Column( - children: [ - Container( - // color: Color(0xffF4F4F4), - padding: const EdgeInsets.symmetric(horizontal: 12,vertical: 8), - child: const Row( - children: [ - SortButton(), - Spacer(), - ], - ), - ), - const Divider(height: 1,), - Expanded( - child: SortSelectorPanel( - active: state.config.name, - options: sortNameMap.values.toList(), - onSelected: state.selectName, - ), - ), - - ], - ), - ), - const VerticalDivider(width: 1,), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: CustomPaint( - painter: DataPainter(data: numbers), - child: ConstrainedBox(constraints: const BoxConstraints.expand()), - ), - ), - ) - ], - ), - ); - } -} - -class SortSelectorPanel extends StatelessWidget { - final String active; - final ValueChanged onSelected; - final List 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 createState() => _SortItemTileState(); -} - -class _SortItemTileState extends State { - @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 - ), - ), - ), - ), - ), - ); - } -} - diff --git a/lib/v7/pages/sort/views/sort_setting.dart b/lib/v7/pages/sort/views/sort_setting.dart deleted file mode 100644 index 9a96a88..0000000 --- a/lib/v7/pages/sort/views/sort_setting.dart +++ /dev/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 createState() => _SortSettingsState(); -} - -class _SortSettingsState extends State { - 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('确定设置')) - ], - ), - ), - ); - } -} diff --git a/lib/v7/pages/user/user_page.dart b/lib/v7/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v7/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v8/app.dart b/lib/v8/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v8/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v8/app/navigation/router/app_router_delegate.dart b/lib/v8/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index 999afc2..0000000 --- a/lib/v8/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,225 +0,0 @@ -import 'dart:async'; -import 'package:flutter/material.dart'; -import 'iroute.dart'; -import 'iroute_config.dart'; -import 'route_history_manager.dart'; -import 'routes.dart'; -import 'views/not_find_view.dart'; - -AppRouterDelegate router = AppRouterDelegate( - initial: IRouteConfig(uri: Uri.parse('/color')), -); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - - /// 核心数据,路由配置数据列表 - final List _configs = []; - - String get path => current.uri.path; - - IRouteConfig get current => _configs.last; - - final IRoutePageBuilder? notFindPageBuilder; - - AppRouterDelegate({ - this.notFindPageBuilder, - required IRouteConfig initial, - }) { - _configs.add(initial); - _historyManager.recode(initial); - } - - Page _defaultNotFindPageBuilder(_, __) => const MaterialPage( - child: Material(child: NotFindPage()), - ); - - final RouteHistoryManager _historyManager = RouteHistoryManager(); - - RouteHistoryManager get historyManager => _historyManager; - - /// 历史回退操作 - /// 详见: [RouteHistoryManager.back] - void back() => _historyManager.back(changeRoute); - - /// 撤销回退操作 - /// 详见: [RouteHistoryManager.revocation] - void revocation() => _historyManager.revocation(changeRoute); - - void closeHistory(int index) { - _historyManager.close(index); - notifyListeners(); - } - - void clearHistory() { - _historyManager.clear(); - notifyListeners(); - } - - // final List _pathStack = []; - - bool get canPop => _configs.where((e) => e.routeStyle==RouteStyle.push).isNotEmpty; - - final Map> _completerMap = {}; - - FutureOr changeRoute(IRouteConfig config) { - String value = config.uri.path; - if (current == config) null; - _handleChangeStyle(config); - - if (config.forResult) { - _completerMap[value] = Completer(); - } - - if (config.recordHistory) { - _historyManager.recode(config); - } - - notifyListeners(); - if (config.forResult) { - return _completerMap[value]!.future; - } - } - - void _handleChangeStyle(IRouteConfig config){ - switch (config.routeStyle) { - case RouteStyle.push: - if (_configs.contains(config)) { - _configs.remove(config); - } - _configs.add(config); - break; - case RouteStyle.replace: - List liveRoutes = _configs.where((e) => e.keepAlive&&e!=config).toList(); - _configs.clear(); - _configs.addAll([...liveRoutes,config]); - break; - } - } - - - - FutureOr changePath( - String value, { - bool forResult = false, - Object? extra, - bool keepAlive = false, - bool recordHistory = false, - RouteStyle style = RouteStyle.replace, - }) { - return changeRoute(IRouteConfig( - uri: Uri.parse(value), - forResult: forResult, - extra: extra, - routeStyle: style, - keepAlive: keepAlive, - recordHistory: recordHistory, - )); - } - - @override - Widget build(BuildContext context) { - return Navigator( - onPopPage: _onPopPage, - pages: _buildPages(context, _configs), - ); - } - - List _buildPages(BuildContext context, List configs) { - IRouteConfig top = configs.last; - List bottoms = _configs.sublist(0,_configs.length-1).toList(); - List pages = []; - List topPages = _buildPageByPathFromTree(context, top); - pages = _buildLivePageByPathList(context, bottoms, top, topPages); - pages.addAll(topPages); - return pages; - } - - List _buildLivePageByPathList( - BuildContext context, - List paths, - IRouteConfig curConfig, - List curPages, - ) { - List pages = []; - if (paths.isNotEmpty) { - for (IRouteConfig path in paths) { - if (path != curConfig) { - pages.addAll(_buildPageByPathFromTree(context, path)); - } - } - /// 去除和 curPages 中重复的界面 - pages.removeWhere((page) => curPages.map((e) => e.key).contains(page.key)); - } - return pages; - } - - List _buildPageByPathFromTree( - BuildContext context, IRouteConfig config) { - List result = []; - List iRoutes = rootRoute.find(config.path); - if (iRoutes.isNotEmpty) { - for (int i = 0; i < iRoutes.length; i++) { - IRouteNode iroute = iRoutes[i]; - IRouteConfig fixConfig = config; - if(iroute.path!=config.uri.path){ - fixConfig = IRouteConfig(uri: Uri.parse(iroute.path)); - } - Page? page; - if (iroute is NotFindNode) { - page = (notFindPageBuilder ?? _defaultNotFindPageBuilder)(context, config); - } else { - page = iroute.createPage(context, fixConfig); - } - if (page != null) { - result.add(page); - } - if(iroute is CellIRoute){ - break; - } - } - } - return result; - } - - @override - Future popRoute() async { - print('=======popRoute========='); - return true; - } - - void backStack() { - if (_configs.isNotEmpty) { - _configs.removeLast(); - if (_configs.isNotEmpty) { - changeRoute(_configs.last); - } else { - changeRoute(current); - } - } - } - - bool _onPopPage(Route route, result) { - if (_completerMap.containsKey(path)) { - _completerMap[path]?.complete(result); - _completerMap.remove(path); - } - - if (canPop) { - _configs.removeLast(); - notifyListeners(); - } else { - changePath(backPath(path), recordHistory: false); - } - return route.didPop(result); - } - - String backPath(String path) { - Uri uri = Uri.parse(path); - if (uri.pathSegments.length == 1) return path; - List parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} diff --git a/lib/v8/app/navigation/router/iroute.dart b/lib/v8/app/navigation/router/iroute.dart deleted file mode 100644 index 8e1de0f..0000000 --- a/lib/v8/app/navigation/router/iroute.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'iroute_config.dart'; - -typedef IRoutePageBuilder = Page? Function( - BuildContext context, - IRouteConfig data, -); - -typedef IRouteWidgetBuilder = Widget? Function( - BuildContext context, - IRouteConfig data, -); - -abstract class IRouteNode { - final String path; - final List children; - - const IRouteNode({ - required this.path, - required this.children, - }); - - Page? createPage(BuildContext context, IRouteConfig config); - - List find( - String input, - ) { - return findNodes(this, Uri.parse(input), 0, '/', []); - } - - List findNodes( - IRouteNode node, - Uri uri, - int deep, - String prefix, - List result, - ) { - List parts = uri.pathSegments; - if (deep > parts.length - 1) { - return result; - } - String target = parts[deep]; - if (node.children.isNotEmpty) { - target = prefix + target; - List nodes = - node.children.where((e) => e.path == target).toList(); - bool match = nodes.isNotEmpty; - if (match) { - IRouteNode matched = nodes.first; - result.add(matched); - String nextPrefix = '${matched.path}/'; - findNodes(matched, uri, ++deep, nextPrefix, result); - } else { - result.add(NotFindNode(path: target)); - return result; - } - } - return result; - } -} - -/// 优先调用 [pageBuilder] 构建 Page -/// 没有 [pageBuilder] 时, 使用 [widgetBuilder] 构建组件 -/// 没有 [pageBuilder] 和 [widgetBuilder] 时, 使用 [widget] 构建组件 -class IRoute extends IRouteNode { - final IRoutePageBuilder? pageBuilder; - final IRouteWidgetBuilder? widgetBuilder; - final Widget? widget; - - const IRoute({ - required super.path, - super.children = const [], - this.widget, - this.pageBuilder, - this.widgetBuilder, - }); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - if (pageBuilder != null) { - return pageBuilder!(context, config); - } - Widget? child; - if (widgetBuilder != null) { - child = widgetBuilder!(context, config); - } - child ??= widget; - if (child != null) { - return MaterialPage(child: child, key: config.pageKey); - } - return null; - } -} - -/// 未知路由 -class NotFindNode extends IRouteNode { - NotFindNode({required super.path, super.children = const []}); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - return null; - } -} - - -class CellIRoute extends IRoute { - const CellIRoute({ - required super.path, - super.pageBuilder, - super.children, - super.widget, - }); -} - -typedef CellBuilder = Widget Function(BuildContext context,IRouteConfig config, CellIRoute cell); diff --git a/lib/v8/app/navigation/router/iroute_config.dart b/lib/v8/app/navigation/router/iroute_config.dart deleted file mode 100644 index f526e71..0000000 --- a/lib/v8/app/navigation/router/iroute_config.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:flutter/material.dart'; - -enum RouteStyle{ - push, - replace, -} - - -class IRouteConfig { - final Object? extra; - final bool forResult; - final Uri uri; - final bool keepAlive; - final RouteStyle routeStyle; - final bool recordHistory; - - const IRouteConfig({ - this.extra, - required this.uri, - this.forResult = false, - this.keepAlive = false, - this.routeStyle = RouteStyle.replace, - this.recordHistory = false, - }); - - String get path => uri.path; - - IRouteConfig copyWith({ - Object? extra, - bool? forResult, - bool? keepAlive, - bool? recordHistory, - String? path, - }) => - IRouteConfig( - extra: extra ?? this.extra, - forResult: forResult ?? this.forResult, - keepAlive: keepAlive ?? this.keepAlive, - recordHistory: recordHistory ?? this.recordHistory, - uri: path!=null?Uri.parse(path):uri, - ); - - ValueKey get pageKey => ValueKey(hashCode); - - - @override - String toString() { - return 'IRouteConfig{extra: $extra, forResult: $forResult, uri: $uri, keepAlive: $keepAlive, routeStyle: $routeStyle, recordHistory: $recordHistory}'; - } - - @override - bool operator ==(Object other) => - identical(this, other) || - other is IRouteConfig && - runtimeType == other.runtimeType && - extra == other.extra && - forResult == other.forResult && - uri == other.uri && - keepAlive == other.keepAlive && - routeStyle == other.routeStyle && - recordHistory == other.recordHistory; - - @override - int get hashCode => - extra.hashCode ^ - forResult.hashCode ^ - uri.hashCode ^ - keepAlive.hashCode ^ - routeStyle.hashCode ^ - recordHistory.hashCode; -} diff --git a/lib/v8/app/navigation/router/route_history_manager.dart b/lib/v8/app/navigation/router/route_history_manager.dart deleted file mode 100644 index 8844898..0000000 --- a/lib/v8/app/navigation/router/route_history_manager.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'iroute_config.dart'; - -typedef OnRouteChange = void Function(IRouteConfig config); - -class RouteHistoryManager{ - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories.reversed.toList(); - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 将 [config] 加入历史记录 - void recode(IRouteConfig config){ - if (_histories.isNotEmpty && config.path == _histories.last.path) return; - _histories.add(config); - } - - /// 历史回退操作 - /// 将当前顶层移除,并加入 [_backHistories] 撤销列表 - /// 并转到前一路径 [_histories.last] - void back(OnRouteChange callback) { - if (!hasHistory) return; - IRouteConfig top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - callback(_histories.last); - } - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation(OnRouteChange callback) { - IRouteConfig target = _backHistories.removeLast(); - callback(target); - } - - void close(int index) { - _histories.removeAt(index); - } - - void clear() { - _histories.clear(); - } -} \ No newline at end of file diff --git a/lib/v8/app/navigation/router/routes.dart b/lib/v8/app/navigation/router/routes.dart deleted file mode 100644 index da6fb72..0000000 --- a/lib/v8/app/navigation/router/routes.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../../pages/sort/views/player/sort_player.dart'; -import 'iroute_config.dart'; -import 'iroute.dart'; -import '../../../pages/color/color_add_page.dart'; -import '../../../pages/color/color_detail_page.dart'; -import '../../../pages/color/color_page.dart'; -import '../../../pages/counter/counter_page.dart'; -import '../../../pages/user/user_page.dart'; -import '../../../pages/settings/settings_page.dart'; -import '../../../pages/sort/views/sort_page/sort_page.dart'; -import '../../../pages/sort/views/settings/sort_setting.dart'; - -IRoute rootRoute = const IRoute( - path: 'root', - children: [ - IRoute( - path: '/color', - widget: ColorPage(), - children: [ - IRoute(path: '/color/detail', widgetBuilder: _buildColorDetail), - IRoute(path: '/color/add', widget: ColorAddPage()), - ], - ), - IRoute(path: '/counter', widget: CounterPage()), - CellIRoute( - path: '/sort', - widget: SortPage(), - children: [ - IRoute( - path: '/sort/settings', - widget: SortSettings(), - ), - IRoute( - path: '/sort/player', - widget: SortPlayer(), - ), - ], - ), - IRoute(path: '/user', widget: UserPage()), - IRoute(path: '/settings', widget: SettingPage()), - ], -); - -Widget? _buildColorDetail(BuildContext context, IRouteConfig data) { - final Map queryParams = data.uri.queryParameters; - String? selectedColor = queryParams['color']; - Color color = Colors.black; - if (selectedColor != null) { - color = Color(int.parse(selectedColor, radix: 16)); - } else if (data.extra is Color) { - color = data.extra as Color; - } - return ColorDetailPage(color: color); -} diff --git a/lib/v8/app/navigation/router/views/not_find_view.dart b/lib/v8/app/navigation/router/views/not_find_view.dart deleted file mode 100644 index ccefa16..0000000 --- a/lib/v8/app/navigation/router/views/not_find_view.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotFindPage extends StatelessWidget { - const NotFindPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Material( - child: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - '404 Page Not Find', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ); - } -} diff --git a/lib/v8/app/navigation/router/views/route_back_indicator.dart b/lib/v8/app/navigation/router/views/route_back_indicator.dart deleted file mode 100644 index 5be781a..0000000 --- a/lib/v8/app/navigation/router/views/route_back_indicator.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import '../app_router_delegate.dart'; -class RouteBackIndicator extends StatefulWidget { - const RouteBackIndicator({super.key}); - - @override - State createState() => _RouteBackIndicatorState(); -} - -class _RouteBackIndicatorState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if(router.canPop){ - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: router.backStack, - child: Container( - width: 26, - height: 26, - margin: EdgeInsets.only(right: 8), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Color(0xffE3E5E7), - borderRadius: BorderRadius.circular(6) - ), - child: Icon(Icons.arrow_back_ios_new,size: 14,)), - ), - ); - } - return SizedBox(); - } - - void _onChange() { - setState(() { - - }); - } -} diff --git a/lib/v8/app/navigation/transition/fade_page_transitions_builder.dart b/lib/v8/app/navigation/transition/fade_page_transitions_builder.dart deleted file mode 100644 index 0587ecc..0000000 --- a/lib/v8/app/navigation/transition/fade_page_transitions_builder.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class FadePageTransitionsBuilder extends PageTransitionsBuilder { - - const FadePageTransitionsBuilder(); - - @override - Widget buildTransitions( - PageRoute? route, - BuildContext? context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return _FadePagePageTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - child: child, - ); - } -} - -class _FadePagePageTransition extends StatelessWidget { - - const _FadePagePageTransition({ - required this.animation, - required this.secondaryAnimation, - required this.child, - }); - - final Animation animation; - final Animation secondaryAnimation; - final Widget child; - - @override - Widget build(BuildContext context) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: child, - ); - } -} \ No newline at end of file diff --git a/lib/v8/app/navigation/transition/fade_transition_page.dart b/lib/v8/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index fc4e6e6..0000000 --- a/lib/v8/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v8/app/navigation/transition/no_transition_page.dart b/lib/v8/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v8/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v8/app/navigation/views/app_navigation.dart b/lib/v8/app/navigation/views/app_navigation.dart deleted file mode 100644 index 5abca82..0000000 --- a/lib/v8/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatelessWidget { - const AppNavigation({super.key}); - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: Router( - routerDelegate: router, - backButtonDispatcher: RootBackButtonDispatcher(), - ), - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v8/app/navigation/views/app_navigation_rail.dart b/lib/v8/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 8ea2fb0..0000000 --- a/lib/v8/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; -import '../router/iroute_config.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - final List deskNavBarMenus = const [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined, path: '/color'), - MenuMeta(label: '计数器', icon: Icons.add_chart, path: '/counter'), - MenuMeta(label: '排序', icon: Icons.sort, path: '/sort'), - MenuMeta(label: '我的', icon: Icons.person, path: '/user'), - MenuMeta(label: '设置', icon: Icons.settings, path: '/settings'), - ]; - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text( - 'V0.0.8', - style: TextStyle(color: Colors.white, fontSize: 12), - ), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: activeIndex, - ), - ); - } - - RegExp _segReg = RegExp(r'/\w+'); - - int? get activeIndex { - String path = router.path; - RegExpMatch? match = _segReg.firstMatch(path); - if (match == null) return null; - String? target = match.group(0); - int index = deskNavBarMenus.indexWhere((menu) => menu.path == target); - if (index == -1) return null; - return index; - } - - void _onDestinationSelected(int index) { - String path = deskNavBarMenus[index].path!; - if (index == 1) { - router.changePath(path, keepAlive: true); - return; - } - if (index == 4) { - router.changePath(path, style: RouteStyle.push); - return; - } else { - router.changePath(path); - } - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v8/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v8/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index 40516a7..0000000 --- a/lib/v8/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v8/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v8/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index 072a838..0000000 --- a/lib/v8/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/views/route_back_indicator.dart'; -import 'app_router_editor.dart'; -import 'history_view_icon.dart'; -import 'route_history_button.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouteBackIndicator(), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - RouteHistoryButton(), - const SizedBox(width: 12,), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.changePath(path), - )), - const SizedBox(width: 12,), - HistoryViewIcon(), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - -Map kRouteLabelMap = { - '/color': '颜色板', - '/color/add': '添加颜色', - '/color/detail': '颜色详情', - '/counter': '计数器', - '/sort': '可视化排序算法', - '/sort/settings': '排序配置', - '/user': '我的', - '/settings': '系统设置', -}; - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.changePath(item.to!); - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - return result; - } -} diff --git a/lib/v8/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v8/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index 3390a49..0000000 --- a/lib/v8/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/iroute.dart'; -import '../../router/iroute_config.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar() { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: router.clearHistory, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final IRouteConfig history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(widget.history.path), - const SizedBox( - height: 2, - ), - Text(kRouteLabelMap[widget.history.path]??'未知路由'), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List histories = router.historyManager.histories; - if(histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - int fixIndex = histories.length - 1 - index; - router.closeHistory(fixIndex); - }, - onPressed: (){ - router.changeRoute(histories[index].copyWith(recordHistory: false)); - Navigator.of(context).pop(); - }, - history: histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v8/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v8/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index 3ee6513..0000000 --- a/lib/v8/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = router.historyManager.hasHistory; - bool hasBackHistory = router.historyManager.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?router.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?router.revocation:null, - ), - ], - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v8/app/unit_app.dart b/lib/v8/app/unit_app.dart deleted file mode 100644 index 33f59bf..0000000 --- a/lib/v8/app/unit_app.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import '../pages/sort/provider/state.dart'; -import 'navigation/transition/fade_page_transitions_builder.dart'; -import 'navigation/views/app_navigation.dart'; - - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return SortStateScope( - notifier: SortState(), - child: MaterialApp( - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - } - ), - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - home: AppNavigation() - ), - ); - } -} - - diff --git a/lib/v8/pages/color/color_add_page.dart b/lib/v8/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v8/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v8/pages/color/color_detail_page.dart b/lib/v8/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v8/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v8/pages/color/color_page.dart b/lib/v8/pages/color/color_page.dart deleted file mode 100644 index 8fdbe13..0000000 --- a/lib/v8/pages/color/color_page.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.changePath('/color/detail',extra: color); - - } - - void _toAddPage() async { - Color? color = await router.changePath('/color/add',forResult: true,recordHistory: false); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v8/pages/counter/counter_page.dart b/lib/v8/pages/counter/counter_page.dart deleted file mode 100644 index b5b2e17..0000000 --- a/lib/v8/pages/counter/counter_page.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v8/pages/empty/empty_page.dart b/lib/v8/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v8/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v8/pages/settings/settings_page.dart b/lib/v8/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v8/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v8/pages/sort/functions.dart b/lib/v8/pages/sort/functions.dart deleted file mode 100644 index 6ae1176..0000000 --- a/lib/v8/pages/sort/functions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'functions/bubble.dart'; -import 'functions/cocktail.dart'; -import 'functions/comb.dart'; -import 'functions/cycle.dart'; -import 'functions/gnome.dart'; -import 'functions/heap.dart'; -import 'functions/insertion.dart'; -import 'functions/merage.dart'; -import 'functions/pigeonHole.dart'; -import 'functions/quick.dart'; -import 'functions/selection.dart'; -import 'functions/shell.dart'; - -typedef SortFunction = Future Function(List src, SortCallback callback); -typedef SortCallback = Future Function(List dist); - -Map sortFunctionMap = { - 'insertion': insertionSort, - 'bubble': bubbleSort, - 'cocktail': cocktailSort, - 'comb': combSort, - 'pigeonHole': pigeonHoleSort, - 'shell': shellSort, - 'selection': selectionSort, - 'gnome': gnomeSort, - 'cycle': cycleSort, - 'heap': heapSort, - 'quick': quickSort, - 'mergeSort': mergeSort, -}; - -Map sortNameMap = { - 'insertion': '插入排序', - 'bubble': '冒泡排序', - 'cocktail': '鸡尾酒排序(双向冒泡排序)', - 'comb': '梳排序', - 'pigeonHole': '鸽巢排序', - 'shell': '希尔排序', - 'selection': '选择排序', - 'gnome': '侏儒排序', - 'cycle': '循环排序', - 'heap': '堆排序', - 'quick': '快速排序', - 'mergeSort': '归并排序', -}; - diff --git a/lib/v8/pages/sort/functions/bubble.dart b/lib/v8/pages/sort/functions/bubble.dart deleted file mode 100644 index 3cf3c99..0000000 --- a/lib/v8/pages/sort/functions/bubble.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///冒泡排序 -Future bubbleSort(List src, SortCallback callback ) async{ - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < src.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < src.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (src[j] > src[j + 1]) { - int temp = src[j]; - src[j] = src[j + 1]; - src[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/cocktail.dart b/lib/v8/pages/sort/functions/cocktail.dart deleted file mode 100644 index 8c2d18c..0000000 --- a/lib/v8/pages/sort/functions/cocktail.dart +++ /dev/null @@ -1,52 +0,0 @@ -import '../functions.dart'; - -///鸡尾酒排序(双向冒泡排序) -Future cocktailSort(List src, SortCallback callback ) async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = src.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/comb.dart b/lib/v8/pages/sort/functions/comb.dart deleted file mode 100644 index 821f4a9..0000000 --- a/lib/v8/pages/sort/functions/comb.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '../functions.dart'; - -///梳排序(Comb Sort) -Future combSort(List src, SortCallback callback) async{ - int gap = src.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < src.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (src[i] > src[i + gap]) { - int temp = src[i]; - src[i] = src[i + gap]; - src[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await callback(src); - } - } -} - -int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/cycle.dart b/lib/v8/pages/sort/functions/cycle.dart deleted file mode 100644 index 4bef6eb..0000000 --- a/lib/v8/pages/sort/functions/cycle.dart +++ /dev/null @@ -1,54 +0,0 @@ -import '../functions.dart'; - -///循环排序 -Future cycleSort(List src, SortCallback callback) async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) { - int item = src[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (item != src[pos]) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/gnome.dart b/lib/v8/pages/sort/functions/gnome.dart deleted file mode 100644 index 5e08fc3..0000000 --- a/lib/v8/pages/sort/functions/gnome.dart +++ /dev/null @@ -1,22 +0,0 @@ -import '../functions.dart'; - -///地精排序 (侏儒排序) -Future gnomeSort(List src, SortCallback callback) async { - int index = 0; - while (index < src.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (src[index] >= src[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = src[index]; - src[index] = src[index - 1]; - src[index - 1] = temp; - index--; - } - await callback(src); - } - return; -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/heap.dart b/lib/v8/pages/sort/functions/heap.dart deleted file mode 100644 index 9f5410b..0000000 --- a/lib/v8/pages/sort/functions/heap.dart +++ /dev/null @@ -1,38 +0,0 @@ -import '../functions.dart'; - -///堆排序 -Future heapSort(List src, SortCallback callback) async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = src.length ~/ 2; i >= 0; i--) { - await heapify(src,callback, src.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = src.length - 1; i >= 0; i--) { - int temp = src[0]; - src[0] = src[i]; - src[i] = temp; - await heapify(src, callback,i, 0); - } -} - -Future heapify(List src, SortCallback callback, int n, int i) async{ - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && src[l] > src[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && src[r] > src[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = src[i]; - src[i] = src[largest]; - src[largest] = temp; - heapify(src,callback, n, largest); - } - await callback(src); -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/insertion.dart b/lib/v8/pages/sort/functions/insertion.dart deleted file mode 100644 index b1c7814..0000000 --- a/lib/v8/pages/sort/functions/insertion.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///插入排序 -Future insertionSort(List src, SortCallback callback) async { - for (int i = 1; i < src.length; i++) { - int temp = src[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < src[j]) { - src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - // 更新排序结果回调 - await callback(src); - } - src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await callback(src); - } -} diff --git a/lib/v8/pages/sort/functions/merage.dart b/lib/v8/pages/sort/functions/merage.dart deleted file mode 100644 index 12135b4..0000000 --- a/lib/v8/pages/sort/functions/merage.dart +++ /dev/null @@ -1,79 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future mergeSort(List src, SortCallback callback) async { - await _mergeSort(src,callback,0,src.length-1); -} - -///归并排序 -Future _mergeSort(List src, SortCallback callback,int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = src[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = src[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - src[k] = leftList[i]; - i++; - } else { - src[k] = rightList[j]; - j++; - } - - await callback(src); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - src[k] = leftList[i]; - i++; - k++; - - await callback(src); - } - - while (j < rightSize) { - src[k] = rightList[j]; - j++; - k++; - - await callback(src); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await _mergeSort(src,callback,leftIndex, middleIndex); - await _mergeSort(src,callback,middleIndex + 1, rightIndex); - - await callback(src); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/oddEven.dart b/lib/v8/pages/sort/functions/oddEven.dart deleted file mode 100644 index bd6f548..0000000 --- a/lib/v8/pages/sort/functions/oddEven.dart +++ /dev/null @@ -1,37 +0,0 @@ -import '../functions.dart'; - -///奇偶排序(Odd-Even Sort) -Future oddEvenSort(List src, SortCallback callback) async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= src.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await callback(src); - } - } - - for (int i = 0; i <= src.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; - await callback(src); - } - } - } - - return; -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/pigeonHole.dart b/lib/v8/pages/sort/functions/pigeonHole.dart deleted file mode 100644 index 83bbce1..0000000 --- a/lib/v8/pages/sort/functions/pigeonHole.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../functions.dart'; - -///鸽巢排序 -Future pigeonHoleSort(List src, SortCallback callback ) async{ - int min = src[0]; - int max = src[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < src.length; a++) { - if (src[a] > max) max = src[a]; - if (src[a] < min) min = src[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < src.length; i++) { - p[src[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - src[index++] = j + min; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/quick.dart b/lib/v8/pages/sort/functions/quick.dart deleted file mode 100644 index 25b9685..0000000 --- a/lib/v8/pages/sort/functions/quick.dart +++ /dev/null @@ -1,65 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future quickSort(List src, SortCallback callback) async { - await _quickSort(src,callback,0,src.length-1); -} - -///快速排序 -Future _quickSort(List src, SortCallback callback,int leftIndex,int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = src[p]; - src[p] = src[right]; - src[right] = temp; - await callback(src); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(src[i], src[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = src[i]; - src[i] = src[cursor]; - src[cursor] = temp; - cursor++; - await callback(src); - } - } - - // 将基准元素放置在游标位置 - temp = src[right]; - src[right] = src[cursor]; - src[cursor] = temp; - - await callback(src); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } -} - -// 比较函数,用于判断两个元素的大小关系 -cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/selection.dart b/lib/v8/pages/sort/functions/selection.dart deleted file mode 100644 index 185dae2..0000000 --- a/lib/v8/pages/sort/functions/selection.dart +++ /dev/null @@ -1,18 +0,0 @@ -import '../functions.dart'; - -///选择排序 -Future selectionSort(List src, SortCallback callback ) async { - for (int i = 0; i < src.length; i++) { - for (int j = i + 1; j < src.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (src[i] > src[j]) { - // 判断当前元素是否比后续元素小 - int temp = src[j]; - // 交换当前元素和后续较小的元素 - src[j] = src[i]; - src[i] = temp; - } - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/functions/shell.dart b/lib/v8/pages/sort/functions/shell.dart deleted file mode 100644 index 232f872..0000000 --- a/lib/v8/pages/sort/functions/shell.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../functions.dart'; - -///希尔排序 -Future shellSort(List src, SortCallback callback) async{ - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < src.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = src[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && src[j - gap] > temp; j -= gap) { - src[j] = src[j - gap]; - } - src[j] = temp; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v8/pages/sort/provider/sort_config.dart b/lib/v8/pages/sort/provider/sort_config.dart deleted file mode 100644 index 1fc3790..0000000 --- a/lib/v8/pages/sort/provider/sort_config.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -class SortConfig { - final int count; - 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, - }) => - SortConfig( - count:count??this.count, - seed:seed??this.seed, - duration:duration??this.duration, - name:name??this.name, - colorIndex:colorIndex??this.colorIndex, - ); -} - diff --git a/lib/v8/pages/sort/provider/state.dart b/lib/v8/pages/sort/provider/state.dart deleted file mode 100644 index 1e79b05..0000000 --- a/lib/v8/pages/sort/provider/state.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -import '../functions.dart'; -import 'sort_config.dart'; - -enum SortStatus{ - none, // 未操作 - sorting, // 排序中 - sorted, // 排序完成 -} - -List 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(){ - reset(); - } - - SortStatus status = SortStatus.none; - - List data = []; - List stepData = []; - - SortConfig _config = SortConfig(); - SortConfig get config => _config; - Random random = Random(); - - set config(SortConfig config){ - _config = config; - reset(); - notifyListeners(); - } - - void selectName(String name){ - if(name==config.name) return; - 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; - notifyListeners(); - int count = config.count; - if(config.seed!=-1){ - random = Random(config.seed); - } - for (int i = 0; i < count; i++) { - //随机往数组中填值 - data.add(random.nextInt(1000)); - } - } - - void sort() async{ - status = SortStatus.sorting; - notifyListeners(); - Stopwatch stopwatch = Stopwatch()..start(); - SortFunction? sortFunction = sortFunctionMap[config.name]; - if(sortFunction!=null){ - await sortFunction(data,(arr) async { - await Future.delayed(config.duration); - notifyListeners(); - }); - } - status = SortStatus.sorted; - notifyListeners(); - stopwatch.stop(); - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - } -} - -/// Provides the current [SortState] to descendant widgets in the tree. -class SortStateScope extends InheritedNotifier { - const SortStateScope({ - required super.notifier, - required super.child, - super.key, - }); - - static SortState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; -} \ No newline at end of file diff --git a/lib/v8/pages/sort/views/code_page/code_page.dart b/lib/v8/pages/sort/views/code_page/code_page.dart deleted file mode 100644 index 7d8d4c9..0000000 --- a/lib/v8/pages/sort/views/code_page/code_page.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class CodePage extends StatelessWidget { - const CodePage({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - leading: BackButton(), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - centerTitle: true, - title: Text(sortNameMap[state.config.name]!+'代码实现'), - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text('代码'*1000), - )); - } -} diff --git a/lib/v8/pages/sort/views/player/data_painter.dart b/lib/v8/pages/sort/views/player/data_painter.dart deleted file mode 100644 index 392a9e8..0000000 --- a/lib/v8/pages/sort/views/player/data_painter.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; - - - -class DataPainter extends CustomPainter{ - - final List data; - final MaterialColor color; - - DataPainter( {required this.data,required this.color,}); - - @override - void paint(Canvas canvas, Size size) { - double itemWidth = size.width/data.length; - double height = size.height; - - Paint paint = Paint(); - paint.strokeWidth = itemWidth; - paint.strokeCap = StrokeCap.round; - - - for(int i=0;i 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()), - ), - ); - } -} diff --git a/lib/v8/pages/sort/views/settings/color_picker.dart b/lib/v8/pages/sort/views/settings/color_picker.dart deleted file mode 100644 index b0bb469..0000000 --- a/lib/v8/pages/sort/views/settings/color_picker.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorPicker extends StatelessWidget { - final List colors; - final ValueChanged 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(), - ); - } -} diff --git a/lib/v8/pages/sort/views/settings/sort_setting.dart b/lib/v8/pages/sort/views/settings/sort_setting.dart deleted file mode 100644 index 654d549..0000000 --- a/lib/v8/pages/sort/views/settings/sort_setting.dart +++ /dev/null @@ -1,169 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../provider/state.dart'; -import 'color_picker.dart'; -class SortSettings extends StatefulWidget { - - const SortSettings({super.key,}); - - @override - State createState() => _SortSettingsState(); -} - -class _SortSettingsState extends State { - 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('确定设置')) - ], - ), - ), - ); - } -} diff --git a/lib/v8/pages/sort/views/sort_page/sort_button.dart b/lib/v8/pages/sort/views/sort_page/sort_button.dart deleted file mode 100644 index 93df9d9..0000000 --- a/lib/v8/pages/sort/views/sort_page/sort_button.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../provider/state.dart'; - -class SortButton extends StatelessWidget { - const SortButton({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - VoidCallback? action; - IconData icon; - String text = ''; - Color color; - switch (state.status) { - case SortStatus.none: - icon = Icons.not_started_outlined; - color = Colors.green; - action = state.sort; - text = '点击启动'; - break; - case SortStatus.sorting: - icon = Icons.stop_circle_outlined; - color = Colors.grey; - action = null; - text = '排序中...'; - break; - case SortStatus.sorted: - icon = CupertinoIcons.repeat; - color = Colors.black; - action = state.reset; - text = '点击重置'; - break; - } - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: action, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon( - icon, - color: color, - size: 18, - ), - const SizedBox(width: 4,), - Text(text,style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold,color: color),), - ], - ), - ), - ); - } -} diff --git a/lib/v8/pages/sort/views/sort_page/sort_page.dart b/lib/v8/pages/sort/views/sort_page/sort_page.dart deleted file mode 100644 index 7c11b9a..0000000 --- a/lib/v8/pages/sort/views/sort_page/sort_page.dart +++ /dev/null @@ -1,230 +0,0 @@ -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 createState() => _SortPageState(); -} - -class _SortPageState extends State { - @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 createState() => _SortNavigatorScopeState(); -} - -class _SortNavigatorScopeState extends State { - @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 pages = buildPagesByPath(context, path); - return Navigator( - onPopPage: _onPopPage, - pages: pages, - ); - } - - bool _onPopPage(Route route, result) { - return route.didPop(result); - } - - List 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 onSelected; - final List 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 createState() => _SortItemTileState(); -} - -class _SortItemTileState extends State { - @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), - ), - ), - ), - ), - ); - } -} diff --git a/lib/v8/pages/user/user_page.dart b/lib/v8/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v8/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/lib/v9/app.dart b/lib/v9/app.dart deleted file mode 100644 index c9460c2..0000000 --- a/lib/v9/app.dart +++ /dev/null @@ -1 +0,0 @@ -export 'app/unit_app.dart'; \ No newline at end of file diff --git a/lib/v9/app/navigation/router/app_router_delegate.dart b/lib/v9/app/navigation/router/app_router_delegate.dart deleted file mode 100644 index 435953c..0000000 --- a/lib/v9/app/navigation/router/app_router_delegate.dart +++ /dev/null @@ -1,174 +0,0 @@ -import 'dart:async'; -import 'package:flutter/material.dart'; -import 'views/navigator_scope.dart'; -import 'iroute.dart'; -import 'iroute_config.dart'; -import 'route_history_manager.dart'; -import 'routes.dart'; -import 'views/not_find_view.dart'; - -AppRouterDelegate router = AppRouterDelegate( - initial: IRouteConfig( - uri: Uri.parse('/app/color'), - ), - node: appRoute); - -class AppRouterDelegate extends RouterDelegate with ChangeNotifier { - /// 核心数据,路由配置数据列表 - final List _configs = []; - - String get path => current.uri.path; - - IRouteConfig get current => _configs.last; - - final IRoutePageBuilder? notFindPageBuilder; - - final IRouteNode node; - - AppRouterDelegate({ - this.notFindPageBuilder, - required this.node, - required IRouteConfig initial, - }) { - _configs.add(initial); - _historyManager.recode(initial); - } - - Page _defaultNotFindPageBuilder(_, __) => const MaterialPage( - child: Material(child: NotFindPage()), - ); - - final RouteHistoryManager _historyManager = RouteHistoryManager(); - - RouteHistoryManager get historyManager => _historyManager; - - /// 历史回退操作 - /// 详见: [RouteHistoryManager.back] - void back() => _historyManager.back(changeRoute); - - /// 撤销回退操作 - /// 详见: [RouteHistoryManager.revocation] - void revocation() => _historyManager.revocation(changeRoute); - - void closeHistory(int index) { - _historyManager.close(index); - notifyListeners(); - } - - void clearHistory() { - _historyManager.clear(); - notifyListeners(); - } - - // final List _pathStack = []; - - bool get canPop => _configs.where((e) => e.routeStyle == RouteStyle.push).isNotEmpty; - - final Map> _completerMap = {}; - - FutureOr changeRoute(IRouteConfig config) { - String value = config.uri.path; - if (current == config) null; - _handleChangeStyle(config); - - if (config.forResult) { - _completerMap[value] = Completer(); - } - - if (config.recordHistory) { - _historyManager.recode(config); - } - - notifyListeners(); - if (config.forResult) { - return _completerMap[value]!.future; - } - } - - void _handleChangeStyle(IRouteConfig config) { - switch (config.routeStyle) { - case RouteStyle.push: - if (_configs.contains(config)) { - _configs.remove(config); - } - _configs.add(config); - break; - case RouteStyle.replace: - List liveRoutes = - _configs.where((e) => e.keepAlive && e != config).toList(); - _configs.clear(); - _configs.addAll([...liveRoutes, config]); - break; - } - } - - FutureOr changePath( - String value, { - bool forResult = false, - Object? extra, - bool keepAlive = false, - bool recordHistory = false, - RouteStyle style = RouteStyle.replace, - }) { - return changeRoute(IRouteConfig( - uri: Uri.parse(value), - forResult: forResult, - extra: extra, - routeStyle: style, - keepAlive: keepAlive, - recordHistory: recordHistory, - )); - } - - @override - Widget build(BuildContext context) { - return NavigatorScope( - node: node, - onPopPage: _onPopPage, - configs: _configs, - notFindPageBuilder: (notFindPageBuilder ?? _defaultNotFindPageBuilder), - ); - } - - @override - Future popRoute() async { - print('=======popRoute========='); - return true; - } - - void backStack() { - if (_configs.isNotEmpty) { - _configs.removeLast(); - if (_configs.isNotEmpty) { - changeRoute(_configs.last); - } else { - changeRoute(current); - } - } - } - - bool _onPopPage(Route route, result) { - if (_completerMap.containsKey(path)) { - _completerMap[path]?.complete(result); - _completerMap.remove(path); - } - - if (canPop) { - _configs.removeLast(); - notifyListeners(); - } else { - changePath(backPath(path), recordHistory: false); - } - return route.didPop(result); - } - - String backPath(String path) { - Uri uri = Uri.parse(path); - if (uri.pathSegments.length == 1) return path; - List parts = List.of(uri.pathSegments)..removeLast(); - return '/${parts.join('/')}'; - } - - @override - Future setNewRoutePath(configuration) async {} -} diff --git a/lib/v9/app/navigation/router/iroute.dart b/lib/v9/app/navigation/router/iroute.dart deleted file mode 100644 index f7d245e..0000000 --- a/lib/v9/app/navigation/router/iroute.dart +++ /dev/null @@ -1,156 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/v9/app/navigation/router/views/navigator_scope.dart'; - -import 'iroute_config.dart'; - -typedef IRoutePageBuilder = Page? Function( - BuildContext context, - IRouteConfig data, -); - - - -typedef IRouteWidgetBuilder = Widget? Function( - BuildContext context, - IRouteConfig data, -); - -abstract class IRouteNode { - final String path; - final List children; - - const IRouteNode({ - required this.path, - required this.children, - }); - - Page? createPage(BuildContext context, IRouteConfig config); - - List find( - String input, - ) { - String prefix = '/'; - if (this is CellIRoute) { - input = input.replaceFirst(path, ''); - if (path != '/') { - prefix = path + "/"; - } - } - - return findNodes(this, Uri.parse(input), 0, prefix, []); - } - - List findNodes( - IRouteNode node, - Uri uri, - int deep, - String prefix, - List result, - ) { - List parts = uri.pathSegments; - if (deep > parts.length - 1) { - return result; - } - String target = parts[deep]; - if (node.children.isNotEmpty) { - target = prefix + target; - - List nodes = - node.children.where((e) => e.path == target).toList(); - bool match = nodes.isNotEmpty; - if (match) { - IRouteNode matched = nodes.first; - result.add(matched); - String nextPrefix = '${matched.path}/'; - findNodes(matched, uri, ++deep, nextPrefix, result); - } else { - result.add(NotFindNode(path: target)); - return result; - } - } - return result; - } -} - -/// 优先调用 [pageBuilder] 构建 Page -/// 没有 [pageBuilder] 时, 使用 [widgetBuilder] 构建组件 -/// 没有 [pageBuilder] 和 [widgetBuilder] 时, 使用 [widget] 构建组件 -class IRoute extends IRouteNode { - final IRoutePageBuilder? pageBuilder; - final IRouteWidgetBuilder? widgetBuilder; - final Widget? widget; - - const IRoute({ - required super.path, - super.children = const [], - this.widget, - this.pageBuilder, - this.widgetBuilder, - }); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - if (pageBuilder != null) { - return pageBuilder!(context, config); - } - Widget? child; - if (widgetBuilder != null) { - child = widgetBuilder!(context, config); - } - child ??= widget; - if (child != null) { - return MaterialPage(child: child, key: config.pageKey); - } - return null; - } -} - -/// 未知路由 -class NotFindNode extends IRouteNode { - NotFindNode({required super.path, super.children = const []}); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - return null; - } -} - -typedef CellBuilder = Widget Function( - BuildContext context, - IRouteConfig config, - Widget navigator, -); - -typedef CellIRoutePageBuilder = Page? Function( - BuildContext context, - IRouteConfig data, - Widget child, - ); - -class CellIRoute extends IRouteNode { - final CellBuilder cellBuilder; - final CellIRoutePageBuilder? pageBuilder; - - const CellIRoute({ - required this.cellBuilder, - this.pageBuilder, - required super.path, - required super.children, - }); - - @override - Page? createPage(BuildContext context, IRouteConfig config) { - return null; - } - - Page? createCellPage(BuildContext context, IRouteConfig config, - Widget child) { - if (pageBuilder != null) { - return pageBuilder!(context, config, child); - } - return MaterialPage( - child: child, - key: config.pageKey, - ); - } -} \ No newline at end of file diff --git a/lib/v9/app/navigation/router/iroute_config.dart b/lib/v9/app/navigation/router/iroute_config.dart deleted file mode 100644 index f526e71..0000000 --- a/lib/v9/app/navigation/router/iroute_config.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:flutter/material.dart'; - -enum RouteStyle{ - push, - replace, -} - - -class IRouteConfig { - final Object? extra; - final bool forResult; - final Uri uri; - final bool keepAlive; - final RouteStyle routeStyle; - final bool recordHistory; - - const IRouteConfig({ - this.extra, - required this.uri, - this.forResult = false, - this.keepAlive = false, - this.routeStyle = RouteStyle.replace, - this.recordHistory = false, - }); - - String get path => uri.path; - - IRouteConfig copyWith({ - Object? extra, - bool? forResult, - bool? keepAlive, - bool? recordHistory, - String? path, - }) => - IRouteConfig( - extra: extra ?? this.extra, - forResult: forResult ?? this.forResult, - keepAlive: keepAlive ?? this.keepAlive, - recordHistory: recordHistory ?? this.recordHistory, - uri: path!=null?Uri.parse(path):uri, - ); - - ValueKey get pageKey => ValueKey(hashCode); - - - @override - String toString() { - return 'IRouteConfig{extra: $extra, forResult: $forResult, uri: $uri, keepAlive: $keepAlive, routeStyle: $routeStyle, recordHistory: $recordHistory}'; - } - - @override - bool operator ==(Object other) => - identical(this, other) || - other is IRouteConfig && - runtimeType == other.runtimeType && - extra == other.extra && - forResult == other.forResult && - uri == other.uri && - keepAlive == other.keepAlive && - routeStyle == other.routeStyle && - recordHistory == other.recordHistory; - - @override - int get hashCode => - extra.hashCode ^ - forResult.hashCode ^ - uri.hashCode ^ - keepAlive.hashCode ^ - routeStyle.hashCode ^ - recordHistory.hashCode; -} diff --git a/lib/v9/app/navigation/router/route_history_manager.dart b/lib/v9/app/navigation/router/route_history_manager.dart deleted file mode 100644 index 8844898..0000000 --- a/lib/v9/app/navigation/router/route_history_manager.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'iroute_config.dart'; - -typedef OnRouteChange = void Function(IRouteConfig config); - -class RouteHistoryManager{ - final List _histories = []; - final List _backHistories = []; - - List get histories => _histories.reversed.toList(); - - bool get hasHistory => _histories.length > 1; - - bool get hasBackHistory => _backHistories.isNotEmpty; - - /// 将 [config] 加入历史记录 - void recode(IRouteConfig config){ - if (_histories.isNotEmpty && config.path == _histories.last.path) return; - _histories.add(config); - } - - /// 历史回退操作 - /// 将当前顶层移除,并加入 [_backHistories] 撤销列表 - /// 并转到前一路径 [_histories.last] - void back(OnRouteChange callback) { - if (!hasHistory) return; - IRouteConfig top = _histories.removeLast(); - _backHistories.add(top); - if (_histories.isNotEmpty) { - callback(_histories.last); - } - } - - /// 撤销回退操作 - /// 取出回退列表的最后元素,跳转到该路径 - void revocation(OnRouteChange callback) { - IRouteConfig target = _backHistories.removeLast(); - callback(target); - } - - void close(int index) { - _histories.removeAt(index); - } - - void clear() { - _histories.clear(); - } -} \ No newline at end of file diff --git a/lib/v9/app/navigation/router/routes.dart b/lib/v9/app/navigation/router/routes.dart deleted file mode 100644 index 356f8b2..0000000 --- a/lib/v9/app/navigation/router/routes.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../../pages/login/login.dart'; -import '../transition/no_transition_page.dart'; -import '../../../pages/sort/views/player/sort_player.dart'; -import 'iroute_config.dart'; -import '../views/app_navigation.dart'; -import 'iroute.dart'; -import '../../../pages/color/color_add_page.dart'; -import '../../../pages/color/color_detail_page.dart'; -import '../../../pages/color/color_page.dart'; -import '../../../pages/counter/counter_page.dart'; -import '../../../pages/user/user_page.dart'; -import '../../../pages/settings/settings_page.dart'; -import '../../../pages/sort/views/sort_page/sort_page.dart'; -import '../../../pages/sort/views/settings/sort_setting.dart'; - -CellIRoute appRoute = CellIRoute( - cellBuilder: (_, __, navigator) => AppNavigation( - navigator: navigator, - ), - path: '/app', - children: [ - IRoute( - path: '/app/color', - widget: ColorPage(), - children: [ - IRoute(path: '/app/color/detail', widgetBuilder: _buildColorDetail), - IRoute(path: '/app/color/add', widget: ColorAddPage()), - ], - ), - const IRoute(path: '/app/counter', widget: CounterPage()), - CellIRoute( - cellBuilder: (_, __, navigator) => SortNavigation(navigator: navigator), - // pageBuilder: (_,config,child)=> NoTransitionPage( - // child: child, - // key: config.pageKey - // ), - path: '/app/sort', - children: [ - const IRoute( - path: '/app/sort/settings', - widget: SortSettings(), - ), - const IRoute( - path: '/app/sort/player', - widget: SortPlayer(), - ), - ], - ), - const IRoute(path: '/app/user', widget: UserPage()), - const IRoute(path: '/app/settings', widget: SettingPage()), - ], -); - -IRoute rootRoute = IRoute(path: '/', children: [ - appRoute, - const IRoute( - path: '/login', - widget: LoginPage() - ) -]); - -Widget? _buildColorDetail(BuildContext context, IRouteConfig data) { - final Map queryParams = data.uri.queryParameters; - String? selectedColor = queryParams['color']; - Color color = Colors.black; - if (selectedColor != null) { - color = Color(int.parse(selectedColor, radix: 16)); - } else if (data.extra is Color) { - color = data.extra as Color; - } - return ColorDetailPage(color: color); -} - -Map kRouteLabelMap = { - '/app': '', - '/app/color': '颜色板', - '/app/color/add': '添加颜色', - '/app/color/detail': '颜色详情', - '/app/counter': '计数器', - '/app/sort': '排序算法', - '/app/sort/player': '演示', - '/app/sort/settings': '排序配置', - '/app/user': '我的', - '/app/settings': '系统设置', -}; - -const List deskNavBarMenus = [ - MenuMeta(label: '颜色板', icon: Icons.color_lens_outlined, path: '/app/color'), - MenuMeta(label: '计数器', icon: Icons.add_chart, path: '/app/counter'), - MenuMeta(label: '排序', icon: Icons.sort, path: '/app/sort/player'), - MenuMeta(label: '我的', icon: Icons.person, path: '/app/user'), - MenuMeta(label: '设置', icon: Icons.settings, path: '/app/settings'), -]; diff --git a/lib/v9/app/navigation/router/views/navigator_scope.dart b/lib/v9/app/navigation/router/views/navigator_scope.dart deleted file mode 100644 index be7b1d8..0000000 --- a/lib/v9/app/navigation/router/views/navigator_scope.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'package:flutter/material.dart'; -import '../iroute.dart'; - -import '../iroute_config.dart'; - -class NavigatorScope extends StatefulWidget { - final IRouteNode node; - final PopPageCallback onPopPage; - final List configs; - final IRoutePageBuilder notFindPageBuilder; - - const NavigatorScope({ - super.key, - required this.node, - required this.onPopPage, - required this.configs, - required this.notFindPageBuilder, - }); - - @override - State createState() => _NavigatorScopeState(); -} - -class _NavigatorScopeState extends State { - @override - Widget build(BuildContext context) { - Widget content = Navigator( - onPopPage: widget.onPopPage, - pages: _buildPages(context, widget.configs), - ); - - if(widget.node is CellIRoute){ - content = (widget.node as CellIRoute).cellBuilder(context,widget.configs.last,content); - } - return HeroControllerScope( - controller: MaterialApp.createMaterialHeroController(), - child: content, - ); - } - - List _buildPages(BuildContext context, List configs) { - IRouteConfig top = configs.last; - List bottoms = - configs.sublist(0, configs.length - 1).toList(); - List pages = []; - List topPages = _buildPageByPathFromTree(context, top); - pages = _buildLivePageByPathList(context, bottoms, top, topPages); - pages.addAll(topPages); - return pages; - } - - List _buildLivePageByPathList( - BuildContext context, - List paths, - IRouteConfig curConfig, - List curPages, - ) { - List pages = []; - if (paths.isNotEmpty) { - for (IRouteConfig path in paths) { - if (path != curConfig) { - pages.addAll(_buildPageByPathFromTree(context, path)); - } - } - /// 去除和 curPages 中重复的界面 - pages.removeWhere((page) => curPages.map((e) => e.key).contains(page.key)); - } - return pages; - } - - List _buildPageByPathFromTree( - BuildContext context, IRouteConfig config) { - List result = []; - List iRoutes = widget.node.find(config.path); - - if (iRoutes.isNotEmpty) { - for (int i = 0; i < iRoutes.length; i++) { - IRouteNode iroute = iRoutes[i]; - IRouteConfig fixConfig = config; - - if(iroute.path!=config.uri.path){ - fixConfig = IRouteConfig(uri: Uri.parse(iroute.path)); - } - - Page? page; - if (iroute is NotFindNode) { - page = widget.notFindPageBuilder(context, config); - } else if (iroute is CellIRoute) { - Widget scope = NavigatorScope( - node: iroute, - onPopPage: widget.onPopPage, - configs: widget.configs, - notFindPageBuilder: widget.notFindPageBuilder, - ); - page = iroute.createCellPage(context, fixConfig, scope); - } else { - page = iroute.createPage(context, fixConfig); - } - if (page != null) { - result.add(page); - } - if (iroute is CellIRoute) { - break; - } - } - } - return result; - } -} diff --git a/lib/v9/app/navigation/router/views/not_find_view.dart b/lib/v9/app/navigation/router/views/not_find_view.dart deleted file mode 100644 index ccefa16..0000000 --- a/lib/v9/app/navigation/router/views/not_find_view.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotFindPage extends StatelessWidget { - const NotFindPage({super.key}); - - @override - Widget build(BuildContext context) { - return const Material( - child: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.redAccent), - Text( - '404 Page Not Find', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ); - } -} diff --git a/lib/v9/app/navigation/router/views/route_back_indicator.dart b/lib/v9/app/navigation/router/views/route_back_indicator.dart deleted file mode 100644 index 5be781a..0000000 --- a/lib/v9/app/navigation/router/views/route_back_indicator.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import '../app_router_delegate.dart'; -class RouteBackIndicator extends StatefulWidget { - const RouteBackIndicator({super.key}); - - @override - State createState() => _RouteBackIndicatorState(); -} - -class _RouteBackIndicatorState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - if(router.canPop){ - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: router.backStack, - child: Container( - width: 26, - height: 26, - margin: EdgeInsets.only(right: 8), - alignment: Alignment.center, - decoration: BoxDecoration( - color: Color(0xffE3E5E7), - borderRadius: BorderRadius.circular(6) - ), - child: Icon(Icons.arrow_back_ios_new,size: 14,)), - ), - ); - } - return SizedBox(); - } - - void _onChange() { - setState(() { - - }); - } -} diff --git a/lib/v9/app/navigation/transition/fade_page_transitions_builder.dart b/lib/v9/app/navigation/transition/fade_page_transitions_builder.dart deleted file mode 100644 index 0587ecc..0000000 --- a/lib/v9/app/navigation/transition/fade_page_transitions_builder.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class FadePageTransitionsBuilder extends PageTransitionsBuilder { - - const FadePageTransitionsBuilder(); - - @override - Widget buildTransitions( - PageRoute? route, - BuildContext? context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) { - return _FadePagePageTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - child: child, - ); - } -} - -class _FadePagePageTransition extends StatelessWidget { - - const _FadePagePageTransition({ - required this.animation, - required this.secondaryAnimation, - required this.child, - }); - - final Animation animation; - final Animation secondaryAnimation; - final Widget child; - - @override - Widget build(BuildContext context) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: child, - ); - } -} \ No newline at end of file diff --git a/lib/v9/app/navigation/transition/fade_transition_page.dart b/lib/v9/app/navigation/transition/fade_transition_page.dart deleted file mode 100644 index fc4e6e6..0000000 --- a/lib/v9/app/navigation/transition/fade_transition_page.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class FadeTransitionPage extends Page { - final Widget child; - final Duration duration; - - const FadeTransitionPage({ - super.key, - required this.child, - this.duration = const Duration(milliseconds: 300), - }); - - @override - Route createRoute(BuildContext context) => PageBasedFadeTransitionRoute(this); -} - -class PageBasedFadeTransitionRoute extends PageRoute { - final FadeTransitionPage _page; - - PageBasedFadeTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => _page.duration; - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - var curveTween = CurveTween(curve: Curves.easeIn); - return FadeTransition( - opacity: animation.drive(curveTween), - child: (settings as FadeTransitionPage).child, - ); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v9/app/navigation/transition/no_transition_page.dart b/lib/v9/app/navigation/transition/no_transition_page.dart deleted file mode 100644 index 291910b..0000000 --- a/lib/v9/app/navigation/transition/no_transition_page.dart +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2021, the Flutter project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:flutter/material.dart'; - -class NoTransitionPage extends Page { - final Widget child; - - const NoTransitionPage({ - super.key, - required this.child, - }); - - @override - Route createRoute(BuildContext context) => NoTransitionRoute(this); -} - -class NoTransitionRoute extends PageRoute { - - final NoTransitionPage _page; - - NoTransitionRoute(this._page) : super(settings: _page); - - @override - Color? get barrierColor => null; - - @override - String? get barrierLabel => null; - - @override - Duration get transitionDuration => const Duration(milliseconds: 0); - - @override - bool get maintainState => true; - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return (settings as NoTransitionPage).child; - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) => - child; -} diff --git a/lib/v9/app/navigation/views/app_navigation.dart b/lib/v9/app/navigation/views/app_navigation.dart deleted file mode 100644 index 9360abf..0000000 --- a/lib/v9/app/navigation/views/app_navigation.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import '../router/app_router_delegate.dart'; -import 'app_navigation_rail.dart'; -import 'app_top_bar/app_top_bar.dart'; - -class AppNavigation extends StatefulWidget { - final Widget navigator; - - const AppNavigation({super.key,required this.navigator}); - - @override - State createState() => _AppNavigationState(); -} - -class _AppNavigationState extends State { - - @override - void initState() { - print('======_AppNavigationState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_AppNavigationState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - double px1 = 1/View.of(context).devicePixelRatio; - return Scaffold( - body: Row( - children: [ - const AppNavigationRail(), - Expanded( - child: Column( - children: [ - const AppTopBar(), - Divider(height: px1,), - Expanded( - child: widget.navigator, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/v9/app/navigation/views/app_navigation_rail.dart b/lib/v9/app/navigation/views/app_navigation_rail.dart deleted file mode 100644 index 09b54e8..0000000 --- a/lib/v9/app/navigation/views/app_navigation_rail.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../router/app_router_delegate.dart'; -import '../router/iroute_config.dart'; -import '../router/routes.dart'; - -class AppNavigationRail extends StatefulWidget { - const AppNavigationRail({super.key}); - - @override - State createState() => _AppNavigationRailState(); -} - -class _AppNavigationRailState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: TolyNavigationRail( - items: deskNavBarMenus, - leading: const Padding( - padding: EdgeInsets.symmetric(vertical: 18.0), - child: FlutterLogo(), - ), - tail: Padding( - padding: const EdgeInsets.only(bottom: 6.0), - child: Text( - 'V0.0.9', - style: TextStyle(color: Colors.white, fontSize: 12), - ), - ), - backgroundColor: const Color(0xff3975c6), - onDestinationSelected: _onDestinationSelected, - selectedIndex: activeIndex, - ), - ); - } - - RegExp _segReg = RegExp(r'/app/\w+'); - - int? get activeIndex { - String path = router.path; - RegExpMatch? match = _segReg.firstMatch(path); - if (match == null) return null; - String? target = match.group(0); - int index = deskNavBarMenus.indexWhere((menu) => menu.path!.contains(target??'')); - if (index == -1) return null; - return index; - } - - void _onDestinationSelected(int index) { - String path = deskNavBarMenus[index].path!; - if (index == 1) { - router.changePath(path, keepAlive: true); - return; - } - if (index == 4) { - router.changePath(path, style: RouteStyle.push); - return; - } else { - router.changePath(path); - } - } - - void _onRouterChange() { - setState(() {}); - } -} diff --git a/lib/v9/app/navigation/views/app_top_bar/app_router_editor.dart b/lib/v9/app/navigation/views/app_top_bar/app_router_editor.dart deleted file mode 100644 index 40516a7..0000000 --- a/lib/v9/app/navigation/views/app_top_bar/app_router_editor.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class AppRouterEditor extends StatefulWidget { - final ValueChanged? onSubmit; - const AppRouterEditor({super.key, this.onSubmit}); - - @override - State createState() => _AppRouterEditorState(); -} - -class _AppRouterEditorState extends State { - - final TextEditingController _controller = TextEditingController(); - - - @override - void initState() { - super.initState(); - _onRouteChange(); - router.addListener(_onRouteChange); - } - - void _onRouteChange() { - _controller.text=router.path; - } - - @override - void dispose() { - _controller.dispose(); - router.removeListener(_onRouteChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Stack( - alignment: Alignment.centerRight, - children: [ - SizedBox( - child: CupertinoTextField( - controller: _controller, - style: TextStyle(fontSize: 14), - padding: EdgeInsets.only(left:12,top: 6,bottom: 6,right: 32), - placeholder: '输入路由地址导航', - onSubmitted: widget.onSubmit, - decoration: BoxDecoration(color: Color(0xffF1F2F3),borderRadius: BorderRadius.circular(6)), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: HoverIconButton( - icon: Icons.directions_outlined, - defaultColor: Color(0xff68696B), - onPressed:()=>widget.onSubmit?.call(_controller.text), - size: 20 - ), - ) - ], - ); - } -} diff --git a/lib/v9/app/navigation/views/app_top_bar/app_top_bar.dart b/lib/v9/app/navigation/views/app_top_bar/app_top_bar.dart deleted file mode 100644 index 150ac6b..0000000 --- a/lib/v9/app/navigation/views/app_top_bar/app_top_bar.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/routes.dart'; -import '../../router/views/route_back_indicator.dart'; -import 'app_router_editor.dart'; -import 'history_view_icon.dart'; -import 'route_history_button.dart'; - -class AppTopBar extends StatelessWidget { - const AppTopBar({super.key}); - - @override - Widget build(BuildContext context) { - return DragToMoveWrap( - child: Container( - alignment: Alignment.center, - height: 46, - child: Row( - children: [ - const SizedBox(width: 16), - const RouteBackIndicator(), - const RouterIndicator(), - Expanded( - child: Row(children: [ - const Spacer(), - RouteHistoryButton(), - const SizedBox(width: 12,), - SizedBox( - width: 250, - child: AppRouterEditor( - onSubmit: (path) => router.changePath(path), - )), - const SizedBox(width: 12,), - HistoryViewIcon(), - const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: VerticalDivider( - width: 32, - ), - ) - ])), - const WindowButtons() - ], - ), - ), - ); - } -} - -class RouterIndicator extends StatefulWidget { - const RouterIndicator({super.key}); - - @override - State createState() => _RouterIndicatorState(); -} - - -class _RouterIndicatorState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onRouterChange); - } - - @override - void dispose() { - router.removeListener(_onRouterChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return TolyBreadcrumb( - items: pathToBreadcrumbItems(router.path), - onTapItem: (item) { - if (item.to != null) { - router.changePath(item.to!); - } - }, - ); - } - - void _onRouterChange() { - setState(() {}); - } - - List pathToBreadcrumbItems(String path) { - Uri uri = Uri.parse(path); - List result = []; - String to = ''; - - String distPath = ''; - for (String segment in uri.pathSegments) { - distPath += '/$segment'; - } - - for (String segment in uri.pathSegments) { - to += '/$segment'; - String label = kRouteLabelMap[to] ?? '未知路由'; - if(label.isNotEmpty){ - result.add(BreadcrumbItem(to: to, label: label, active: to == distPath)); - } - } - return result; - } -} diff --git a/lib/v9/app/navigation/views/app_top_bar/history_view_icon.dart b/lib/v9/app/navigation/views/app_top_bar/history_view_icon.dart deleted file mode 100644 index e2ad492..0000000 --- a/lib/v9/app/navigation/views/app_top_bar/history_view_icon.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/components.dart'; -import '../../router/app_router_delegate.dart'; -import '../../router/routes.dart'; -import '../../router/iroute_config.dart'; -import 'app_top_bar.dart'; - -class HistoryViewIcon extends StatelessWidget{ - const HistoryViewIcon({super.key}); - - @override - Widget build(BuildContext context) { - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: PopPanel( - offset: const Offset(0, 10), - panel: SizedBox( - height: 350, - child: Column( - children: [ - _buildTopBar(), - const Expanded( - child:HistoryPanel(), - ), - ], - ), - ), - child: const Icon( - Icons.history, - size: 20, - ), - ), - ); - } - - Widget _buildTopBar() { - return Container( - decoration: BoxDecoration( - color: const Color(0xffFAFAFC), - borderRadius: BorderRadius.circular(6), - ), - padding: - const EdgeInsets.only(top: 10, left: 12, right: 12, bottom: 8), - child: Row( - children: [ - const Text( - '浏览历史', - style: TextStyle(fontWeight: FontWeight.bold), - ), - const Spacer(), - TextButton(onPressed: router.clearHistory, child: const Text('清空历史')) - ], - )); - } -} - -class HistoryItem extends StatefulWidget { - final IRouteConfig history; - final VoidCallback onPressed; - final VoidCallback onDelete; - - const HistoryItem({super.key, required this.history, required this.onPressed, required this.onDelete}); - - @override - State createState() => _HistoryItemState(); -} - -class _HistoryItemState extends State { - @override - Widget build(BuildContext context) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: widget.onPressed, - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(widget.history.path), - const SizedBox( - height: 2, - ), - Text(kRouteLabelMap[widget.history.path]??'未知路由'), - ], - )), - GestureDetector( - onTap: widget.onDelete, - child: const Icon( - Icons.close, - size: 18, - color: Color(0xff8E92A9), - ), - ), - ], - ), - ), - ); - } -} - -class HistoryPanel extends StatefulWidget { - const HistoryPanel({super.key}); - - @override - State createState() => _HistoryPanelState(); -} - -class _HistoryPanelState extends State { - - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List histories = router.historyManager.histories; - if(histories.isEmpty){ - return const Center( - child: Text( - '暂无浏览历史记录', - style: TextStyle(fontSize: 14, color: Colors.grey), - ), - ); - } - return ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), - itemExtent: 46, - itemCount: histories.length, - itemBuilder: (_, index) => - HistoryItem( - onDelete: (){ - int fixIndex = histories.length - 1 - index; - router.closeHistory(fixIndex); - }, - onPressed: (){ - router.changeRoute(histories[index].copyWith(recordHistory: false)); - Navigator.of(context).pop(); - }, - history: histories[index]), - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v9/app/navigation/views/app_top_bar/route_history_button.dart b/lib/v9/app/navigation/views/app_top_bar/route_history_button.dart deleted file mode 100644 index 3ee6513..0000000 --- a/lib/v9/app/navigation/views/app_top_bar/route_history_button.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:iroute/components/toly_ui/button/hover_icon_button.dart'; -import '../../router/app_router_delegate.dart'; - -class RouteHistoryButton extends StatefulWidget { - const RouteHistoryButton({super.key}); - - @override - State createState() => _RouteHistoryButtonState(); -} - -class _RouteHistoryButtonState extends State { - @override - void initState() { - super.initState(); - router.addListener(_onChange); - } - - @override - void dispose() { - router.removeListener(_onChange); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - bool hasHistory = router.historyManager.hasHistory; - bool hasBackHistory = router.historyManager.hasBackHistory; - Color activeColor = const Color(0xff9195AC); - Color inActiveColor = const Color(0xffC7CAD5); - Color historyColor = hasHistory?activeColor:inActiveColor; - Color backHistoryColor = hasBackHistory?activeColor:inActiveColor; - return Wrap( - children: [ - HoverIconButton( - size: 20, - hoverColor: historyColor, - defaultColor: historyColor, - icon: CupertinoIcons.arrow_left_circle, - onPressed: hasHistory?router.back:null, - ), - const SizedBox(width: 8,), - HoverIconButton( - size: 20, - hoverColor: backHistoryColor, - defaultColor: backHistoryColor, - icon: CupertinoIcons.arrow_right_circle, - onPressed: hasBackHistory?router.revocation:null, - ), - ], - ); - } - - void _onChange() { - setState(() {}); - } -} diff --git a/lib/v9/app/unit_app.dart b/lib/v9/app/unit_app.dart deleted file mode 100644 index de14a7e..0000000 --- a/lib/v9/app/unit_app.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; -import 'navigation/router/app_router_delegate.dart'; -import '../pages/sort/provider/state.dart'; -import 'navigation/transition/fade_page_transitions_builder.dart'; -import 'navigation/views/app_navigation.dart'; - - -class UnitApp extends StatelessWidget { - const UnitApp({super.key}); - - @override - Widget build(BuildContext context) { - - return SortStateScope( - notifier: SortState(), - child: MaterialApp.router( - routerDelegate: router, - theme: ThemeData( - fontFamily: "宋体", - scaffoldBackgroundColor: Colors.white, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - TargetPlatform.macOS: FadePageTransitionsBuilder(), - TargetPlatform.windows: FadePageTransitionsBuilder(), - TargetPlatform.linux: FadePageTransitionsBuilder(), - } - ), - appBarTheme: const AppBarTheme( - elevation: 0, - iconTheme: IconThemeData(color: Colors.black), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 18, - fontWeight: FontWeight.bold, - ))), - debugShowCheckedModeBanner: false, - // home: AppNavigation() - ), - ); - } -} - - diff --git a/lib/v9/pages/color/color_add_page.dart b/lib/v9/pages/color/color_add_page.dart deleted file mode 100644 index 48e6dc6..0000000 --- a/lib/v9/pages/color/color_add_page.dart +++ /dev/null @@ -1,99 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; - -class ColorAddPage extends StatefulWidget { - const ColorAddPage({super.key}); - - @override - State createState() => _ColorAddPageState(); -} - -class _ColorAddPageState extends State { - late Color _color; - - @override - void initState() { - super.initState(); - _color = randomColor; - } - - @override - Widget build(BuildContext context) { - String text = '# ${_color.value.toRadixString(16)}'; - return Scaffold( - bottomNavigationBar: Container( - margin: EdgeInsets.only(right:20,bottom: 20), - // color: Colors.redAccent, - child: Row( - textDirection:TextDirection.rtl, - children: [ - ElevatedButton(onPressed: (){ - Navigator.of(context).pop(_color); - - }, child: Text('添加')), - SizedBox(width: 12,), - OutlinedButton(onPressed: (){ - Navigator.of(context).pop(); - }, child: Text('取消')), - ], - ), - ), - body: Column( - // mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0,vertical: 16), - child: Row( - children: [ - Expanded(child: Text(text,style: TextStyle(color: _color,fontSize: 24,letterSpacing: 4),)), - Container( - margin: EdgeInsets.only(left: 10), - width: 40, - height: 40, - child: Icon( - Icons.sell_outlined, - color: Colors.white, - ), - decoration: BoxDecoration( - color: _color, - borderRadius: BorderRadius.circular(8), - ), - ), - ], - ), - ), - ColorPicker( - colorPickerWidth:200, - // enableAlpha: false, - displayThumbColor:true, - pickerColor: _color, - paletteType: PaletteType.hueWheel, - onColorChanged: changeColor, - - ), - ], - ), - ); - } - - Random _random = Random(); - - Color get randomColor { - return Color.fromARGB( - 255, - _random.nextInt(256), - _random.nextInt(256), - _random.nextInt(256), - ); - } - - - void changeColor(Color value) { - _color = value; - setState(() { - - }); - } -} diff --git a/lib/v9/pages/color/color_detail_page.dart b/lib/v9/pages/color/color_detail_page.dart deleted file mode 100644 index 7dfed86..0000000 --- a/lib/v9/pages/color/color_detail_page.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class ColorDetailPage extends StatelessWidget { - final Color color; - const ColorDetailPage({super.key, required this.color}); - - @override - Widget build(BuildContext context) { - - const TextStyle style = TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white - ); - String text = '# ${color.value.toRadixString(16)}'; - return Scaffold( - body: Container( - alignment: Alignment.center, - color: color, - child: Text(text ,style: style,), - ), - ); - } -} diff --git a/lib/v9/pages/color/color_page.dart b/lib/v9/pages/color/color_page.dart deleted file mode 100644 index 644005e..0000000 --- a/lib/v9/pages/color/color_page.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:iroute/components/project/colors_panel.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class ColorPage extends StatefulWidget { - const ColorPage({super.key}); - - @override - State createState() => _ColorPageState(); -} - -class _ColorPageState extends State { - final List _colors = [ - Colors.red, Colors.black, Colors.blue, Colors.green, Colors.orange, - Colors.pink, Colors.purple, Colors.indigo, Colors.amber, Colors.cyan, - Colors.redAccent, Colors.grey, Colors.blueAccent, Colors.greenAccent, Colors.orangeAccent, - Colors.pinkAccent, Colors.purpleAccent, Colors.indigoAccent, Colors.amberAccent, Colors.cyanAccent, - ]; - - @override - void initState() { - print('======_ColorPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_ColorPageState#dispose=============='); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar(title:const Text('颜色主页')), - floatingActionButton: FloatingActionButton( - onPressed: _toAddPage, - child: const Icon(Icons.add), - ), - body: Align( - alignment: Alignment.topCenter, - child: ColorsPanel( - colors: _colors, - onSelect: _selectColor, - ), - ), - ); - } - - void _selectColor(Color color){ - // String value = color.value.toRadixString(16); - // router.path = '/color/detail?color=$value'; - router.changePath('/app/color/detail',extra: color); - - } - - void _toAddPage() async { - Color? color = await router.changePath('/app/color/add',forResult: true,recordHistory: false); - if (color != null) { - setState(() { - _colors.add(color); - }); - } - } -} \ No newline at end of file diff --git a/lib/v9/pages/counter/counter_page.dart b/lib/v9/pages/counter/counter_page.dart deleted file mode 100644 index b74a199..0000000 --- a/lib/v9/pages/counter/counter_page.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; - -class CounterPage extends StatefulWidget { - const CounterPage({super.key}); - - @override - State createState() => _CounterPageState(); -} - -class _CounterPageState extends State { - int _counter = 0; - - @override - void initState() { - print('======_CounterPageState#initState=============='); - super.initState(); - } - - @override - void dispose() { - print('======_CounterPageState#dispose=============='); - super.dispose(); - } - - void _incrementCounter() { - setState(() { - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), - ); - } -} \ No newline at end of file diff --git a/lib/v9/pages/empty/empty_page.dart b/lib/v9/pages/empty/empty_page.dart deleted file mode 100644 index b05f56f..0000000 --- a/lib/v9/pages/empty/empty_page.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; - -class EmptyPage extends StatelessWidget { - const EmptyPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - // appBar: AppBar( - // title: Text('界面走丢了'), - // ), - body: Scaffold( - body: Center( - child: Wrap( - spacing: 16, - crossAxisAlignment: WrapCrossAlignment.center, - direction: Axis.vertical, - children: [ - Icon(Icons.nearby_error,size: 64, color: Colors.grey), - Text( - '404 界面丢失', - style: TextStyle(fontSize: 24, color: Colors.grey), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/v9/pages/login/login.dart b/lib/v9/pages/login/login.dart deleted file mode 100644 index af1568a..0000000 --- a/lib/v9/pages/login/login.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../app/navigation/router/app_router_delegate.dart'; - -class LoginPage extends StatelessWidget { - const LoginPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Login Page',style: TextStyle(fontSize: 24),), - const SizedBox(height: 20,), - ElevatedButton(onPressed: (){ - router.changePath('/app/color'); - }, child: Text('点击进入')) - ], - ), - ), - ); - } -} diff --git a/lib/v9/pages/settings/settings_page.dart b/lib/v9/pages/settings/settings_page.dart deleted file mode 100644 index 0b53503..0000000 --- a/lib/v9/pages/settings/settings_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class SettingPage extends StatelessWidget { - const SettingPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('SettingPage'))); - } -} diff --git a/lib/v9/pages/sort/functions.dart b/lib/v9/pages/sort/functions.dart deleted file mode 100644 index 6ae1176..0000000 --- a/lib/v9/pages/sort/functions.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'functions/bubble.dart'; -import 'functions/cocktail.dart'; -import 'functions/comb.dart'; -import 'functions/cycle.dart'; -import 'functions/gnome.dart'; -import 'functions/heap.dart'; -import 'functions/insertion.dart'; -import 'functions/merage.dart'; -import 'functions/pigeonHole.dart'; -import 'functions/quick.dart'; -import 'functions/selection.dart'; -import 'functions/shell.dart'; - -typedef SortFunction = Future Function(List src, SortCallback callback); -typedef SortCallback = Future Function(List dist); - -Map sortFunctionMap = { - 'insertion': insertionSort, - 'bubble': bubbleSort, - 'cocktail': cocktailSort, - 'comb': combSort, - 'pigeonHole': pigeonHoleSort, - 'shell': shellSort, - 'selection': selectionSort, - 'gnome': gnomeSort, - 'cycle': cycleSort, - 'heap': heapSort, - 'quick': quickSort, - 'mergeSort': mergeSort, -}; - -Map sortNameMap = { - 'insertion': '插入排序', - 'bubble': '冒泡排序', - 'cocktail': '鸡尾酒排序(双向冒泡排序)', - 'comb': '梳排序', - 'pigeonHole': '鸽巢排序', - 'shell': '希尔排序', - 'selection': '选择排序', - 'gnome': '侏儒排序', - 'cycle': '循环排序', - 'heap': '堆排序', - 'quick': '快速排序', - 'mergeSort': '归并排序', -}; - diff --git a/lib/v9/pages/sort/functions/bubble.dart b/lib/v9/pages/sort/functions/bubble.dart deleted file mode 100644 index 3cf3c99..0000000 --- a/lib/v9/pages/sort/functions/bubble.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///冒泡排序 -Future bubbleSort(List src, SortCallback callback ) async{ - //控制需要进行排序的次数。每一轮循环都会确定一个数字的最终位置。 - for (int i = 0; i < src.length; ++i) { - //遍历当前未排序的元素,通过相邻的元素比较并交换位置来完成排序。 - for (int j = 0; j < src.length - i - 1; ++j) { - //如果 _numbers[j] 大于 _numbers[j + 1],则交换它们的位置,确保较大的元素移到右边。 - if (src[j] > src[j + 1]) { - int temp = src[j]; - src[j] = src[j + 1]; - src[j + 1] = temp; - } - //实现一个延迟,以便在ui上展示排序的动画效果 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/cocktail.dart b/lib/v9/pages/sort/functions/cocktail.dart deleted file mode 100644 index 8c2d18c..0000000 --- a/lib/v9/pages/sort/functions/cocktail.dart +++ /dev/null @@ -1,52 +0,0 @@ -import '../functions.dart'; - -///鸡尾酒排序(双向冒泡排序) -Future cocktailSort(List src, SortCallback callback ) async { - bool swapped = true; // 表示是否进行了交换 - int start = 0; // 当前未排序部分的起始位置 - int end = src.length; // 当前未排序部分的结束位置 - - // 开始排序循环,只有当没有进行交换时才会退出循环 - while (swapped == true) { - swapped = false; - - // 从左往右遍历需要排序的部分 - for (int i = start; i < end - 1; ++i) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - - // 如果没有进行交换,则说明已经排好序,退出循环 - if (swapped == false) break; - // 重设为false,准备进行下一轮排序 - swapped = false; - // 将end设置为上一轮排序的最后一个元素的位置 - end = end - 1; - - // 从右往左遍历需要排序的部分 - for (int i = end - 1; i >= start; i--) { - // 对每两个相邻元素进行比较 - if (src[i] > src[i + 1]) { - // 如果前面的元素大于后面的元素,则交换它们的位置 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - swapped = true; // 进行了交换 - } - - // 实现动画效果,延迟一段时间后更新数组状态 - await callback(src); - } - // 将start向右移一位,准备下一轮排序 - start = start + 1; - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/comb.dart b/lib/v9/pages/sort/functions/comb.dart deleted file mode 100644 index 821f4a9..0000000 --- a/lib/v9/pages/sort/functions/comb.dart +++ /dev/null @@ -1,34 +0,0 @@ -import '../functions.dart'; - -///梳排序(Comb Sort) -Future combSort(List src, SortCallback callback) async{ - int gap = src.length; - - bool swapped = true; - - // 当间隔不为1或存在交换时执行循环 - while (gap != 1 || swapped == true) { - // 通过缩小间隔来逐步将元素归位 - gap = getNextGap(gap); - swapped = false; - for (int i = 0; i < src.length - gap; i++) { - // 如果当前元素大于间隔位置上的元素,则交换它们的位置 - if (src[i] > src[i + gap]) { - int temp = src[i]; - src[i] = src[i + gap]; - src[i + gap] = temp; - swapped = true; - } - - // 实现一个延迟,以便在 UI 上展示排序的动画效果。 - await callback(src); - } - } -} - -int getNextGap(int gap) { - // 根据当前间隔值计算下一个间隔值 - gap = (gap * 10) ~/ 13; - if (gap < 1) return 1; - return gap; -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/cycle.dart b/lib/v9/pages/sort/functions/cycle.dart deleted file mode 100644 index 4bef6eb..0000000 --- a/lib/v9/pages/sort/functions/cycle.dart +++ /dev/null @@ -1,54 +0,0 @@ -import '../functions.dart'; - -///循环排序 -Future cycleSort(List src, SortCallback callback) async { - int writes = 0; - for (int cycleStart = 0; cycleStart <= src.length - 2; cycleStart++) { - int item = src[cycleStart]; - int pos = cycleStart; - - // 在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos++; - } - - // 如果当前元素已经在正确位置上,则跳过此次迭代 - if (pos == cycleStart) { - continue; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (pos != cycleStart) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 循环将位于当前位置的元素放置到正确的位置上 - while (pos != cycleStart) { - pos = cycleStart; - // 继续在未排序部分中寻找比当前元素小的元素个数 - for (int i = cycleStart + 1; i < src.length; i++) { - if (src[i] < item) pos += 1; - } - - // 将当前元素放置到正确的位置上,并记录写操作次数 - while (item == src[pos]) { - pos += 1; - } - if (item != src[pos]) { - int temp = item; - item = src[pos]; - src[pos] = temp; - writes++; - } - - // 添加延迟操作以展示排序过程 - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/gnome.dart b/lib/v9/pages/sort/functions/gnome.dart deleted file mode 100644 index 5e08fc3..0000000 --- a/lib/v9/pages/sort/functions/gnome.dart +++ /dev/null @@ -1,22 +0,0 @@ -import '../functions.dart'; - -///地精排序 (侏儒排序) -Future gnomeSort(List src, SortCallback callback) async { - int index = 0; - while (index < src.length) { - // 当 index 小于数组长度时执行循环 - if (index == 0) index++; - if (src[index] >= src[index - 1]) { - // 如果当前元素大于等于前面的元素,则将 index 加1 - index++; - } else { - // 否则,交换这两个元素,并将 index 减1(使得元素可以沉到正确位置) - int temp = src[index]; - src[index] = src[index - 1]; - src[index - 1] = temp; - index--; - } - await callback(src); - } - return; -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/heap.dart b/lib/v9/pages/sort/functions/heap.dart deleted file mode 100644 index 9f5410b..0000000 --- a/lib/v9/pages/sort/functions/heap.dart +++ /dev/null @@ -1,38 +0,0 @@ -import '../functions.dart'; - -///堆排序 -Future heapSort(List src, SortCallback callback) async { - // 从最后一个非叶子节点开始,构建最大堆 - for (int i = src.length ~/ 2; i >= 0; i--) { - await heapify(src,callback, src.length, i); - } - - // 依次取出最大堆的根节点(最大值),并进行堆化 - for (int i = src.length - 1; i >= 0; i--) { - int temp = src[0]; - src[0] = src[i]; - src[i] = temp; - await heapify(src, callback,i, 0); - } -} - -Future heapify(List src, SortCallback callback, int n, int i) async{ - int largest = i; - int l = 2 * i + 1; // 左子节点索引 - int r = 2 * i + 2; // 右子节点索引 - - // 如果左子节点存在并且大于父节点,则更新最大值索引 - if (l < n && src[l] > src[largest]) largest = l; - - // 如果右子节点存在并且大于父节点或左子节点,则更新最大值索引 - if (r < n && src[r] > src[largest]) largest = r; - - // 如果最大值索引不等于当前节点索引,则交换节点值,并递归进行堆化 - if (largest != i) { - int temp = src[i]; - src[i] = src[largest]; - src[largest] = temp; - heapify(src,callback, n, largest); - } - await callback(src); -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/insertion.dart b/lib/v9/pages/sort/functions/insertion.dart deleted file mode 100644 index b1c7814..0000000 --- a/lib/v9/pages/sort/functions/insertion.dart +++ /dev/null @@ -1,19 +0,0 @@ -import '../functions.dart'; - -///插入排序 -Future insertionSort(List src, SortCallback callback) async { - for (int i = 1; i < src.length; i++) { - int temp = src[i]; // 将当前元素存储到临时变量 temp 中 - int j = i - 1; // j 表示已排序部分的最后一个元素的索引 - - // 在已排序部分从后往前查找,找到合适位置插入当前元素 - while (j >= 0 && temp < src[j]) { - src[j + 1] = src[j]; // 当前元素比已排序部分的元素小,将元素后移一位 - --j; // 向前遍历 - // 更新排序结果回调 - await callback(src); - } - src[j + 1] = temp; // 插入当前元素到已排序部分的正确位置 - await callback(src); - } -} diff --git a/lib/v9/pages/sort/functions/merage.dart b/lib/v9/pages/sort/functions/merage.dart deleted file mode 100644 index 12135b4..0000000 --- a/lib/v9/pages/sort/functions/merage.dart +++ /dev/null @@ -1,79 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future mergeSort(List src, SortCallback callback) async { - await _mergeSort(src,callback,0,src.length-1); -} - -///归并排序 -Future _mergeSort(List src, SortCallback callback,int leftIndex, int rightIndex) async { - // 定义一个名为 merge 的异步函数,用于合并两个有序子数组 - Future merge(int leftIndex, int middleIndex, int rightIndex) async { - // 计算左侧子数组和右侧子数组的大小 - int leftSize = middleIndex - leftIndex + 1; - int rightSize = rightIndex - middleIndex; - - // 创建左侧子数组和右侧子数组 - List leftList = List.generate(leftSize, (index) => 0); - List rightList = List.generate(rightSize, (index) => 0); - - // 将原始数组中的元素分别复制到左侧子数组和右侧子数组中 - for (int i = 0; i < leftSize; i++) { - leftList[i] = src[leftIndex + i]; - } - for (int j = 0; j < rightSize; j++) { - rightList[j] = src[middleIndex + j + 1]; - } - - // 初始化游标和索引 - int i = 0, j = 0; - int k = leftIndex; - - // 比较左侧子数组和右侧子数组的元素,并按顺序将较小的元素放入原始数组中 - while (i < leftSize && j < rightSize) { - if (leftList[i] <= rightList[j]) { - src[k] = leftList[i]; - i++; - } else { - src[k] = rightList[j]; - j++; - } - - await callback(src); - - k++; - } - - // 将左侧子数组或右侧子数组中剩余的元素放入原始数组中 - while (i < leftSize) { - src[k] = leftList[i]; - i++; - k++; - - await callback(src); - } - - while (j < rightSize) { - src[k] = rightList[j]; - j++; - k++; - - await callback(src); - } - } - - // 如果左索引小于右索引,则递归地对数组进行归并排序 - if (leftIndex < rightIndex) { - // 计算中间索引位置 - int middleIndex = (rightIndex + leftIndex) ~/ 2; - - // 分别对左侧子数组和右侧子数组进行归并排序 - await _mergeSort(src,callback,leftIndex, middleIndex); - await _mergeSort(src,callback,middleIndex + 1, rightIndex); - - await callback(src); - - // 合并两个有序子数组 - await merge(leftIndex, middleIndex, rightIndex); - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/oddEven.dart b/lib/v9/pages/sort/functions/oddEven.dart deleted file mode 100644 index bd6f548..0000000 --- a/lib/v9/pages/sort/functions/oddEven.dart +++ /dev/null @@ -1,37 +0,0 @@ -import '../functions.dart'; - -///奇偶排序(Odd-Even Sort) -Future oddEvenSort(List src, SortCallback callback) async { - bool isSorted = false; - - while (!isSorted) { - // 当 isSorted 为 false 时执行循环 - isSorted = true; // 先假设数组已经排好序 - - for (int i = 1; i <= src.length - 2; i = i + 2) { - // 对奇数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; // 若发生了交换,则说明数组仍未完全排序,将 isSorted 设为 false - await callback(src); - } - } - - for (int i = 0; i <= src.length - 2; i = i + 2) { - // 对偶数索引位置进行比较 - if (src[i] > src[i + 1]) { - // 如果当前元素大于后面的元素,则交换它们的值 - int temp = src[i]; - src[i] = src[i + 1]; - src[i + 1] = temp; - isSorted = false; - await callback(src); - } - } - } - - return; -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/pigeonHole.dart b/lib/v9/pages/sort/functions/pigeonHole.dart deleted file mode 100644 index 83bbce1..0000000 --- a/lib/v9/pages/sort/functions/pigeonHole.dart +++ /dev/null @@ -1,33 +0,0 @@ -import '../functions.dart'; - -///鸽巢排序 -Future pigeonHoleSort(List src, SortCallback callback ) async{ - int min = src[0]; - int max = src[0]; - int range, i, j, index; - - // 找到数组中的最大值和最小值 - for (int a = 0; a < src.length; a++) { - if (src[a] > max) max = src[a]; - if (src[a] < min) min = src[a]; - } - - // 计算鸽巢的个数 - range = max - min + 1; - List p = List.generate(range, (i) => 0); - - // 将数字分配到各个鸽巢中 - for (i = 0; i < src.length; i++) { - p[src[i] - min]++; - } - - index = 0; - - // 将鸽巢中的数字取出,重新放回到数组中 - for (j = 0; j < range; j++) { - while (p[j]-- > 0) { - src[index++] = j + min; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/quick.dart b/lib/v9/pages/sort/functions/quick.dart deleted file mode 100644 index 25b9685..0000000 --- a/lib/v9/pages/sort/functions/quick.dart +++ /dev/null @@ -1,65 +0,0 @@ -import '../functions.dart'; - -//快速排序 -Future quickSort(List src, SortCallback callback) async { - await _quickSort(src,callback,0,src.length-1); -} - -///快速排序 -Future _quickSort(List src, SortCallback callback,int leftIndex,int rightIndex) async { - // 定义一个名为 _partition 的异步函数,用于划分数组,并返回划分后的基准元素的索引位置 - Future _partition(int left, int right) async { - // 选择中间位置的元素作为基准元素 - int p = (left + (right - left) / 2).toInt(); - - // 交换基准元素和最右边的元素 - var temp = src[p]; - src[p] = src[right]; - src[right] = temp; - await callback(src); - - // 初始化游标 cursor - int cursor = left; - - // 遍历数组并根据基准元素将元素交换到左侧或右侧 - for (int i = left; i < right; i++) { - if (cf(src[i], src[right]) <= 0) { - // 如果当前元素小于等于基准元素,则交换它和游标位置的元素 - var temp = src[i]; - src[i] = src[cursor]; - src[cursor] = temp; - cursor++; - await callback(src); - } - } - - // 将基准元素放置在游标位置 - temp = src[right]; - src[right] = src[cursor]; - src[cursor] = temp; - - await callback(src); - - return cursor; // 返回基准元素的索引位置 - } - - // 如果左索引小于右索引,则递归地对数组进行快速排序 - if (leftIndex < rightIndex) { - int p = await _partition(leftIndex, rightIndex); - - await _quickSort(src,callback,leftIndex, p - 1); // 对基准元素左侧的子数组进行快速排序 - - await _quickSort(src,callback, p + 1, rightIndex); // 对基准元素右侧的子数组进行快速排序 - } -} - -// 比较函数,用于判断两个元素的大小关系 -cf(int a, int b) { - if (a < b) { - return -1; // 若 a 小于 b,则返回 -1 - } else if (a > b) { - return 1; // 若 a 大于 b,则返回 1 - } else { - return 0; // 若 a 等于 b,则返回 0 - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/selection.dart b/lib/v9/pages/sort/functions/selection.dart deleted file mode 100644 index 185dae2..0000000 --- a/lib/v9/pages/sort/functions/selection.dart +++ /dev/null @@ -1,18 +0,0 @@ -import '../functions.dart'; - -///选择排序 -Future selectionSort(List src, SortCallback callback ) async { - for (int i = 0; i < src.length; i++) { - for (int j = i + 1; j < src.length; j++) { - // 遍历未排序部分,内层循环控制变量 j - if (src[i] > src[j]) { - // 判断当前元素是否比后续元素小 - int temp = src[j]; - // 交换当前元素和后续较小的元素 - src[j] = src[i]; - src[i] = temp; - } - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/functions/shell.dart b/lib/v9/pages/sort/functions/shell.dart deleted file mode 100644 index 232f872..0000000 --- a/lib/v9/pages/sort/functions/shell.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../functions.dart'; - -///希尔排序 -Future shellSort(List src, SortCallback callback) async{ - //定义变量 gap 并初始化为数组长度的一半。每次循环完成后将 gap 减半直到等于 0。 - for (int gap = src.length ~/ 2; gap > 0; gap ~/= 2) { - //遍历每个子序列并进行插入排序。初始时从第一个子序列的第二个元素开始,即 i = gap,以 gap 为步长逐个遍历每个子序列。 - for (int i = gap; i < src.length; i += 1) { - //将当前遍历到的元素赋值给它 - int temp = src[i]; - //内部使用一个 for 循环来实现插入排序。 - //循环开始时定义变量 j 并将其初始化为当前遍历到的元素的下标。通过不断比较前后相隔 gap 的元素大小并交换位置,将当前元素插入到正确的位置。 - int j; - for (j = i; j >= gap && src[j - gap] > temp; j -= gap) { - src[j] = src[j - gap]; - } - src[j] = temp; - await callback(src); - } - } -} \ No newline at end of file diff --git a/lib/v9/pages/sort/provider/sort_config.dart b/lib/v9/pages/sort/provider/sort_config.dart deleted file mode 100644 index 1fc3790..0000000 --- a/lib/v9/pages/sort/provider/sort_config.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; - -class SortConfig { - final int count; - 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, - }) => - SortConfig( - count:count??this.count, - seed:seed??this.seed, - duration:duration??this.duration, - name:name??this.name, - colorIndex:colorIndex??this.colorIndex, - ); -} - diff --git a/lib/v9/pages/sort/provider/state.dart b/lib/v9/pages/sort/provider/state.dart deleted file mode 100644 index 1e79b05..0000000 --- a/lib/v9/pages/sort/provider/state.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; - -import '../functions.dart'; -import 'sort_config.dart'; - -enum SortStatus{ - none, // 未操作 - sorting, // 排序中 - sorted, // 排序完成 -} - -List 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(){ - reset(); - } - - SortStatus status = SortStatus.none; - - List data = []; - List stepData = []; - - SortConfig _config = SortConfig(); - SortConfig get config => _config; - Random random = Random(); - - set config(SortConfig config){ - _config = config; - reset(); - notifyListeners(); - } - - void selectName(String name){ - if(name==config.name) return; - 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; - notifyListeners(); - int count = config.count; - if(config.seed!=-1){ - random = Random(config.seed); - } - for (int i = 0; i < count; i++) { - //随机往数组中填值 - data.add(random.nextInt(1000)); - } - } - - void sort() async{ - status = SortStatus.sorting; - notifyListeners(); - Stopwatch stopwatch = Stopwatch()..start(); - SortFunction? sortFunction = sortFunctionMap[config.name]; - if(sortFunction!=null){ - await sortFunction(data,(arr) async { - await Future.delayed(config.duration); - notifyListeners(); - }); - } - status = SortStatus.sorted; - notifyListeners(); - stopwatch.stop(); - print("Sorting completed in ${stopwatch.elapsed.inMilliseconds} ms."); - } -} - -/// Provides the current [SortState] to descendant widgets in the tree. -class SortStateScope extends InheritedNotifier { - const SortStateScope({ - required super.notifier, - required super.child, - super.key, - }); - - static SortState of(BuildContext context) => - context.dependOnInheritedWidgetOfExactType()!.notifier!; -} \ No newline at end of file diff --git a/lib/v9/pages/sort/views/code_page/code_page.dart b/lib/v9/pages/sort/views/code_page/code_page.dart deleted file mode 100644 index 7d8d4c9..0000000 --- a/lib/v9/pages/sort/views/code_page/code_page.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class CodePage extends StatelessWidget { - const CodePage({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - leading: BackButton(), - titleTextStyle: TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - centerTitle: true, - title: Text(sortNameMap[state.config.name]!+'代码实现'), - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Text('代码'*1000), - )); - } -} diff --git a/lib/v9/pages/sort/views/player/data_painter.dart b/lib/v9/pages/sort/views/player/data_painter.dart deleted file mode 100644 index 392a9e8..0000000 --- a/lib/v9/pages/sort/views/player/data_painter.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; - - - -class DataPainter extends CustomPainter{ - - final List data; - final MaterialColor color; - - DataPainter( {required this.data,required this.color,}); - - @override - void paint(Canvas canvas, Size size) { - double itemWidth = size.width/data.length; - double height = size.height; - - Paint paint = Paint(); - paint.strokeWidth = itemWidth; - paint.strokeCap = StrokeCap.round; - - - for(int i=0;i 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()), - ), - ); - } -} diff --git a/lib/v9/pages/sort/views/settings/color_picker.dart b/lib/v9/pages/sort/views/settings/color_picker.dart deleted file mode 100644 index b0bb469..0000000 --- a/lib/v9/pages/sort/views/settings/color_picker.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorPicker extends StatelessWidget { - final List colors; - final ValueChanged 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(), - ); - } -} diff --git a/lib/v9/pages/sort/views/settings/sort_setting.dart b/lib/v9/pages/sort/views/settings/sort_setting.dart deleted file mode 100644 index 84f5f52..0000000 --- a/lib/v9/pages/sort/views/settings/sort_setting.dart +++ /dev/null @@ -1,170 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../provider/state.dart'; -import 'color_picker.dart'; -class SortSettings extends StatefulWidget { - - const SortSettings({super.key,}); - - @override - State createState() => _SortSettingsState(); -} - -class _SortSettingsState extends State { - 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, - automaticallyImplyLeading: false, - // 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('确定设置')) - ], - ), - ), - ); - } -} diff --git a/lib/v9/pages/sort/views/sort_page/sort_button.dart b/lib/v9/pages/sort/views/sort_page/sort_button.dart deleted file mode 100644 index 93df9d9..0000000 --- a/lib/v9/pages/sort/views/sort_page/sort_button.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -import '../../provider/state.dart'; - -class SortButton extends StatelessWidget { - const SortButton({super.key}); - - @override - Widget build(BuildContext context) { - SortState state = SortStateScope.of(context); - VoidCallback? action; - IconData icon; - String text = ''; - Color color; - switch (state.status) { - case SortStatus.none: - icon = Icons.not_started_outlined; - color = Colors.green; - action = state.sort; - text = '点击启动'; - break; - case SortStatus.sorting: - icon = Icons.stop_circle_outlined; - color = Colors.grey; - action = null; - text = '排序中...'; - break; - case SortStatus.sorted: - icon = CupertinoIcons.repeat; - color = Colors.black; - action = state.reset; - text = '点击重置'; - break; - } - - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: action, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - Icon( - icon, - color: color, - size: 18, - ), - const SizedBox(width: 4,), - Text(text,style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold,color: color),), - ], - ), - ), - ); - } -} diff --git a/lib/v9/pages/sort/views/sort_page/sort_page.dart b/lib/v9/pages/sort/views/sort_page/sort_page.dart deleted file mode 100644 index 7c344d6..0000000 --- a/lib/v9/pages/sort/views/sort_page/sort_page.dart +++ /dev/null @@ -1,166 +0,0 @@ - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import '../../../../app/navigation/router/app_router_delegate.dart'; -import '../../../../app/navigation/router/iroute_config.dart'; -import 'sort_button.dart'; - -import '../../functions.dart'; -import '../../provider/state.dart'; - -class SortNavigation extends StatelessWidget { - final Widget navigator; - const SortNavigation({super.key, required this.navigator}); - - @override - Widget build(BuildContext context) { - return Material( - child: Row( - children: [ - SizedBox( - width: 220, - child: SortRailPanel(), - ), - VerticalDivider( - width: 1, - ), - Expanded( - child: navigator, - ) - ], - ), - ); - } -} - -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('/app/sort/settings',style: RouteStyle.push); - }, - 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('/app/sort/player'); - }, - ), - ), - ], - ); - } -} - -class SortSelectorPanel extends StatelessWidget { - final String active; - final ValueChanged onSelected; - final List 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 createState() => _SortItemTileState(); -} - -class _SortItemTileState extends State { - @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), - ), - ), - ), - ), - ); - } -} diff --git a/lib/v9/pages/user/user_page.dart b/lib/v9/pages/user/user_page.dart deleted file mode 100644 index aba9710..0000000 --- a/lib/v9/pages/user/user_page.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class UserPage extends StatelessWidget { - const UserPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body:Center(child: Text('UserPage'))); - } -} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 0cacc75..b7a6d08 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,16 +7,12 @@ #include "generated_plugin_registrant.h" #include -#include #include void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) screen_retriever_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); - g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); - url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); g_autoptr(FlPluginRegistrar) window_manager_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); window_manager_plugin_register_with_registrar(window_manager_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 62f151f..913ac71 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST screen_retriever - url_launcher_linux window_manager ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index ea24344..b622947 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,11 +6,9 @@ import FlutterMacOS import Foundation import screen_retriever -import url_launcher_macos import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) - UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/packages/components/lib/components.dart b/packages/components/lib/components.dart new file mode 100644 index 0000000..8a7be1f --- /dev/null +++ b/packages/components/lib/components.dart @@ -0,0 +1,4 @@ +export 'toly_ui/toly_ui.dart'; +export 'windows/window_buttons.dart'; +export 'windows/drag_to_move_area.dart'; +export 'project/demo_shower.dart'; \ No newline at end of file diff --git a/packages/components/lib/project/demo_shower.dart b/packages/components/lib/project/demo_shower.dart new file mode 100644 index 0000000..01197c3 --- /dev/null +++ b/packages/components/lib/project/demo_shower.dart @@ -0,0 +1,150 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:go_router/go_router.dart'; +// import 'package:go_router/go_router.dart'; + +class DemoShower extends StatefulWidget { + final List demos; + final String srcCodeDir; + const DemoShower({super.key, required this.demos, required this.srcCodeDir}); + + @override + State createState() => _DemoShowerState(); +} + +class _DemoShowerState extends State { + final PageController _ctrl = PageController(); + int _index = 0; + + @override + Widget build(BuildContext context) { + return Material( + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + PageView( + controller: _ctrl, + children: widget.demos, + ), + Positioned( + bottom: 20, + child: Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + TolyIconButton( + onTap: () { + _index = (_index - 1) % widget.demos.length; + setState(() {}); + _ctrl.animateToPage(_index, + curve: Curves.easeIn, + duration: Duration(milliseconds: 200)); + }, + iconData: Icons.navigate_before, + size: 36, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Column( + children: [ + Text( + '第 ${_index + 1}/${widget.demos.length} 页', + style: TextStyle(fontSize: 16, color: Colors.grey), + ), + const SizedBox( + height: 4, + ), + GestureDetector( + onTap: () { + String index = (_index + 1).toString().padLeft(2, '0'); + String path = 'assets/${widget.srcCodeDir}/s$index.dart'; + context.push('/code?path=$path'); + }, + child: const MouseRegion( + cursor: SystemMouseCursors.click, + child: Text( + '查看源码', + style: TextStyle( + color: Colors.blue, + fontSize: 14, + decoration: TextDecoration.underline), + ), + ), + ) + ], + ), + ), + TolyIconButton( + onTap: () { + _index = (_index + 1) % widget.demos.length; + setState(() {}); + _ctrl.animateToPage(_index, + curve: Curves.easeIn, + duration: Duration(milliseconds: 200)); + }, + size: 36, + iconData: Icons.navigate_next, + ), + ], + )), + ], + ), + ); + } +} + +class TolyIconButton extends StatefulWidget { + final IconData iconData; + final VoidCallback onTap; + final double size; + const TolyIconButton({ + super.key, + required this.iconData, + required this.size, + required this.onTap, + }); + + @override + State createState() => _TolyIconButtonState(); +} + +class _TolyIconButtonState extends State { + bool _hover = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: widget.onTap, + child: MouseRegion( + onEnter: _onEnter, + onExit: _onExit, + cursor: SystemMouseCursors.click, + child: Container( + width: widget.size, + height: widget.size, + decoration: BoxDecoration( + color: _hover + ? Colors.grey.withOpacity(0.6) + : Colors.grey.withOpacity(0.5), + shape: BoxShape.circle), + child: Icon( + widget.iconData, + size: 26, + color: Colors.white, + ), + ), + ), + ); + } + + void _onEnter(PointerEnterEvent event) { + setState(() { + _hover = true; + }); + } + + void _onExit(PointerExitEvent event) { + setState(() { + _hover = false; + }); + } +} diff --git a/lib/components/toly_ui/button/hover_icon_button.dart b/packages/components/lib/toly_ui/button/hover_icon_button.dart similarity index 100% rename from lib/components/toly_ui/button/hover_icon_button.dart rename to packages/components/lib/toly_ui/button/hover_icon_button.dart diff --git a/packages/components/lib/toly_ui/code_view/code/code.dart b/packages/components/lib/toly_ui/code_view/code/code.dart new file mode 100644 index 0000000..93359fb --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code/code.dart @@ -0,0 +1,5 @@ +export 'code_widget.dart'; +export 'high_light_code.dart'; +export 'highlighter_style.dart'; +export 'language/language.dart'; +export 'language/dart_languge.dart'; \ No newline at end of file diff --git a/packages/components/lib/toly_ui/code_view/code/code_widget.dart b/packages/components/lib/toly_ui/code_view/code/code_widget.dart new file mode 100644 index 0000000..019db6f --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code/code_widget.dart @@ -0,0 +1,50 @@ + +/// create by 张风捷特烈 on 2020-04-15 +/// contact me by email 1981462002@qq.com +/// 说明: +import 'package:flutter/material.dart'; + +import 'high_light_code.dart'; +import 'highlighter_style.dart'; +import 'language/dart_languge.dart'; + +class CodeWidget extends StatelessWidget { + CodeWidget({Key? key, required this.code,required this.style, this.fontSize = 13,this.fontFamily}) + : super(key: key); + + final String code; + final HighlighterStyle style; + final double fontSize; + final String? fontFamily; + + @override + Widget build(BuildContext context) { + Widget body; + Widget _codeWidget; + try { + _codeWidget = RichText( + text: TextSpan( + style: TextStyle(fontSize: fontSize,fontFamily: fontFamily), + children: [ + CodeHighlighter( + style: style, + language: const DartLanguage() + ).format(code)], + ), + ); + } catch (err) { + print(err); + _codeWidget = Text(code); + } + body = SingleChildScrollView( + child: Container( + child: _codeWidget, + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: style.backgroundColor ?? const Color(0xffF6F8FA), + borderRadius: const BorderRadius.all(Radius.circular(5.0))), + ), + ); + return body; + } +} \ No newline at end of file diff --git a/packages/components/lib/toly_ui/code_view/code/high_light_code.dart b/packages/components/lib/toly_ui/code_view/code/high_light_code.dart new file mode 100644 index 0000000..d83a00e --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code/high_light_code.dart @@ -0,0 +1,275 @@ +/// create by 张风捷特烈 on 2020-04-15 +/// contact me by email 1981462002@qq.com +/// 说明: + +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +import 'package:string_scanner/string_scanner.dart'; + +import 'highlighter_style.dart'; +import 'language/dart_languge.dart'; +import 'language/language.dart'; + +/// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle(); +/// DartSyntaxHighlighter(style).format(source) + +abstract class Highlighter { + // ignore: one_member_abstracts + Language language; + + + Highlighter({required this.language}); + + TextSpan format(String src); +} + +//暗黑模式下的高亮样式 +class CodeHighlighter extends Highlighter { + CodeHighlighter( + {Language language = const DartLanguage(), HighlighterStyle? style}):super(language: language) { + _spans = <_HighlightSpan>[]; + _style = style ?? HighlighterStyle.fromColors(HighlighterStyle.lightColor); + } + + late HighlighterStyle _style; + + String _src=''; + late StringScanner _scanner; + + List<_HighlightSpan> _spans=[]; + + @override + TextSpan format(String src) { + _src = src; + _scanner = StringScanner(_src); + + if (_generateSpans()) { + // Successfully parsed the code + final List formattedText = []; + int currentPosition = 0; + + for (_HighlightSpan span in _spans) { + if (currentPosition != span.start) { + formattedText + .add(TextSpan(text: _src.substring(currentPosition, span.start))); + } + + formattedText.add(TextSpan( + style: span.textStyle(_style), text: span.textForSpan(_src))); + + currentPosition = span.end; + } + + if (currentPosition != _src.length) { + formattedText + .add(TextSpan(text: _src.substring(currentPosition, _src.length))); + } + + return TextSpan(style: _style.baseStyle, children: formattedText); + } else { + // Parsing failed, return with only basic formatting + return TextSpan(style: _style.baseStyle, text: src); + } + } + + bool _generateSpans() { + int lastLoopPosition = _scanner.position; + + while (!_scanner.isDone) { + // Skip White space + _scanner.scan(RegExp(r'\s+')); + + // Block comments + if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) { + _spans.add(_HighlightSpan(_HighlightType.comment, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Line comments + if (_scanner.scan(RegExp(r'//'))) { + final int startComment = _scanner.lastMatch?.start??0; + bool eof = false; + int endComment; + if (_scanner.scan(RegExp(r'(.*\r\n)|(.*\n)'))) { + int? end = _scanner.lastMatch?.end; + endComment = end==null?0:end - 1; + } else { + eof = true; + endComment = _src.length; + } + + _spans.add(_HighlightSpan(_HighlightType.comment, startComment, endComment)); + + if (eof) break; + continue; + } + + // Raw r"String" + if (_scanner.scan(RegExp(r'r".*"'))) { + _spans.add(_HighlightSpan(_HighlightType.string, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Raw r'String' + if (_scanner.scan(RegExp(r"r'.*'"))) { + _spans.add(_HighlightSpan(_HighlightType.string, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Multiline """String""" + if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) { + _spans.add(_HighlightSpan(_HighlightType.string, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Multiline '''String''' + if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) { + _spans.add(_HighlightSpan(_HighlightType.string, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // "String" + if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) { + _spans.add(_HighlightSpan(_HighlightType.string, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // 'String' + if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) { + _spans.add(_HighlightSpan(_HighlightType.string, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Double + if (_scanner.scan(RegExp(r'\d+\.\d+'))) { + _spans.add(_HighlightSpan(_HighlightType.number, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Integer + if (_scanner.scan(RegExp(r'\d+'))) { + _spans.add(_HighlightSpan(_HighlightType.number, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Punctuation + if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) { + _spans.add(_HighlightSpan(_HighlightType.punctuation, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Meta data + if (_scanner.scan(RegExp(r'@\w+'))) { + _spans.add(_HighlightSpan(_HighlightType.keyword, + _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + continue; + } + + // Words + if (_scanner.scan(RegExp(r'\w+'))) { + _HighlightType? type; + String word = _scanner.lastMatch?[0]??''; + + if (word.startsWith('_')) word = word.substring(1); + + if (language.containsKeywords(word)) { + type = _HighlightType.keyword; + } else if (language.containsInTypes(word)) { + type = _HighlightType.keyword; + } else if (_firstLetterIsUpperCase(word)) { + type = _HighlightType.klass; + } else if (word.length >= 2 && + word.startsWith('k') && + _firstLetterIsUpperCase(word.substring(1))) { + type = _HighlightType.constant; + } + if (type != null) { + _spans.add(_HighlightSpan( + type, _scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0)); + } + } + // Check if this loop did anything + if (lastLoopPosition == _scanner.position) { + // Failed to parse this file, abort gracefully + return false; + } + lastLoopPosition = _scanner.position; + } + + _simplify(); + return true; + } + + void _simplify() { + for (int i = _spans.length - 2; i >= 0; i -= 1) { + if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) { + _spans[i] = _HighlightSpan(_spans[i].type, _spans[i].start, _spans[i + 1].end); + _spans.removeAt(i + 1); + } + } + } + + bool _firstLetterIsUpperCase(String str) { + if (str.isNotEmpty) { + final String first = str.substring(0, 1); + return first == first.toUpperCase(); + } + return false; + } +} + +enum _HighlightType { + number, + comment, + keyword, + string, + punctuation, + klass, + constant +} + +class _HighlightSpan { + _HighlightSpan(this.type, this.start, this.end); + + final _HighlightType type; + final int start; + final int end; + + String textForSpan(String src) { + return src.substring(start, end); + } + + TextStyle? textStyle(HighlighterStyle? style) { + if (type == _HighlightType.number) { + return style?.numberStyle; + } else if (type == _HighlightType.comment) { + return style?.commentStyle; + } else if (type == _HighlightType.keyword) { + return style?.keywordStyle; + } else if (type == _HighlightType.string) { + return style?.stringStyle; + } else if (type == _HighlightType.punctuation) { + return style?.punctuationStyle; + } else if (type == _HighlightType.klass) { + return style?.classStyle; + } else if (type == _HighlightType.constant) { + return style?.constantStyle; + } else { + return style?.baseStyle; + } + } +} diff --git a/packages/components/lib/toly_ui/code_view/code/highlighter_style.dart b/packages/components/lib/toly_ui/code_view/code/highlighter_style.dart new file mode 100644 index 0000000..ef08b3d --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code/highlighter_style.dart @@ -0,0 +1,139 @@ +/// create by 张风捷特烈 on 2020-04-15 +/// contact me by email 1981462002@qq.com +/// 说明: + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020-04-11 +/// contact me by email 1981462002@qq.com +/// 说明: + +class HighlighterStyle { + //句法高亮样式 + const HighlighterStyle( + { //构造函数 + this.baseStyle, //基础样式 + this.numberStyle, //数字的样式 + this.commentStyle, //注释样式 + this.keywordStyle, //关键字样式 + this.stringStyle, //字符串样式 + this.punctuationStyle, //标点符号样式 + this.classStyle, //类名 + this.backgroundColor, + this.constantStyle}); + + static List get lightColor => [ + 0xFF000000, //基础 + 0xFF00b0e8, //数字 + 0xFF9E9E9E, //注释 + 0xFF9C27B0, //关键 + 0xFF43A047, //字符串 + 0xFF000000, //标点符号 + 0xFF3D62F5, //类名 + 0xFF795548, //常量 + 0xffF6F8FA, //背景 + ]; + + static List get darkColor => [ + 0xFFFFFFFF, //基础 + 0xFFDF935F, //数字 + 0xFF9E9E9E, //注释 + 0xFF80CBC4, //关键字 + 0xFFB9CA4A, //字符串 + 0xFFFFFFFF, //标点符号 + 0xFF7AA6DA, //类名 + 0xFF795548, //常量 + 0xFF1D1F21, //背景 + ]; + + static List get gitHub => + [ + 0xFF333333, //基础 + 0xFF008081, //数字 + 0xFF9D9D8D, //注释 + 0xFF009999, //关键字 + 0xFFDD1045, //字符串 + 0xFF333333, //标点符号 + 0xFF6F42C1, //类名 + 0xFF795548, //常量 + 0xFFF8F8F8, //背景 + ]; + + static List get zenburn => [ + 0xFFDCDCDC, //普通字 + 0xFF87C5C8, //数字 + 0xFF8F8F8F, //注释 + 0xFFE4CEAB, //关键字 + 0xFFCC9493, //字符串 + 0xFFDCDCDC, //标点符号 + 0xFFEFEF90, //类名 + 0xFFEF5350, //常量 + 0xFF3F3F3F, //背景 + ]; + + static List get mf =>[ + 0xFF707D95, //基础 + 0xFF6897BB, //数字 + 0xFF629755, //注释 + 0xFFCC7832, //关键 + 0xFFF14E9F, //字符串 + 0xFFFFBB33, //标点符号 + 0xFF66CCFF, //类名 + 0xFF9876AA, //常量 + 0xFF2B2B2B //背景 + ]; + + static List get solarized =>[ + 0xFF657B83, // 普通字 + 0xFFD33682, // 数字 + 0xFF93A1A1, // 注释 + 0xFF859900, // 关键字 + 0xFF2AA198, // 字符串 + 0xFF859900, // 标点符号 + 0xFF268BD2, // 类名 + 0xFF268BD2, //常量 + 0xFFDDD6C1, // 背景 + ]; + + factory HighlighterStyle.fromColors(List colors) => HighlighterStyle( + baseStyle: TextStyle( + color: Color(colors[0]), + ), + numberStyle: TextStyle( + color: Color(colors[1]), + ), + commentStyle: TextStyle( + color: Color( + colors[2], + ), + fontStyle: FontStyle.italic), + keywordStyle: TextStyle( + fontWeight: FontWeight.bold, + color: Color( + colors[3], + ), + ), + stringStyle: TextStyle( + color: Color(colors[4]), + ), + punctuationStyle: TextStyle( + color: Color(colors[5]), + ), + classStyle: TextStyle( + color: Color(colors[6]), + ), + constantStyle: TextStyle( + color: Color(colors[7]), + ), + backgroundColor: Color(colors[8]), + ); + final TextStyle? baseStyle; + final TextStyle? numberStyle; + final TextStyle? commentStyle; + final TextStyle? keywordStyle; + final TextStyle? stringStyle; + final TextStyle? punctuationStyle; + final TextStyle? classStyle; + final TextStyle? constantStyle; + final Color? backgroundColor; +} \ No newline at end of file diff --git a/packages/components/lib/toly_ui/code_view/code/language/dart_languge.dart b/packages/components/lib/toly_ui/code_view/code/language/dart_languge.dart new file mode 100644 index 0000000..1c82d8e --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code/language/dart_languge.dart @@ -0,0 +1,42 @@ + +import 'language.dart'; + +/// create by 张风捷特烈 on 2021/1/21 +/// contact me by email 1981462002@qq.com +/// 说明: + +class DartLanguage extends Language{ + + const DartLanguage() : super('Dart'); + + static const List _kDartKeywords = [ + 'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch', + 'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else', + 'enum', 'export', 'external', 'extends', 'factory', 'false', 'final', + 'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library', + 'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static', + 'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var', + 'void', 'while', 'with', 'yield' + ]; + + static const List _kDartInTypes = [ + 'int', 'double', 'num', 'bool' + ]; + + @override + List get keywords => _kDartKeywords; + + @override + List get inTypes => [ + 'int', 'double', 'num', 'bool' + ]; + + @override + bool containsInTypes(String word) =>_kDartKeywords.contains(word); + + @override + bool containsKeywords(String word)=>_kDartInTypes.contains(word); + + + +} \ No newline at end of file diff --git a/packages/components/lib/toly_ui/code_view/code/language/language.dart b/packages/components/lib/toly_ui/code_view/code/language/language.dart new file mode 100644 index 0000000..c2ea52d --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code/language/language.dart @@ -0,0 +1,17 @@ +/// create by 张风捷特烈 on 2021/1/21 +/// contact me by email 1981462002@qq.com +/// 说明: + +abstract class Language { + final String name; + + const Language(this.name); + + bool containsKeywords(String word); + + bool containsInTypes(String word); + + List get keywords; + + List get inTypes; +} diff --git a/packages/components/lib/toly_ui/code_view/code_view.dart b/packages/components/lib/toly_ui/code_view/code_view.dart new file mode 100644 index 0000000..ebede29 --- /dev/null +++ b/packages/components/lib/toly_ui/code_view/code_view.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'code/code_widget.dart'; +import 'code/highlighter_style.dart'; + +class CodeView extends StatefulWidget { + final String path; + const CodeView({super.key, required this.path}); + + @override + State createState() => _CodeViewState(); +} + +class _CodeViewState extends State { + + String? content; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _loadContent(); + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Material( + child: CodeWidget(code:'${content}', style: HighlighterStyle.fromColors(HighlighterStyle.lightColor),), + ), + ), + ); + } + + void _loadContent() async{ + content = await rootBundle.loadString(widget.path); + setState(() { + + }); + } +} diff --git a/lib/components/toly_ui/decoration/title.dart b/packages/components/lib/toly_ui/decoration/title.dart similarity index 100% rename from lib/components/toly_ui/decoration/title.dart rename to packages/components/lib/toly_ui/decoration/title.dart diff --git a/lib/components/toly_ui/navigation/menu_meta.dart b/packages/components/lib/toly_ui/navigation/menu_meta.dart similarity index 100% rename from lib/components/toly_ui/navigation/menu_meta.dart rename to packages/components/lib/toly_ui/navigation/menu_meta.dart diff --git a/lib/components/toly_ui/navigation/toly_breadcrumb.dart b/packages/components/lib/toly_ui/navigation/toly_breadcrumb.dart similarity index 92% rename from lib/components/toly_ui/navigation/toly_breadcrumb.dart rename to packages/components/lib/toly_ui/navigation/toly_breadcrumb.dart index ed47533..6d56247 100644 --- a/lib/components/toly_ui/navigation/toly_breadcrumb.dart +++ b/packages/components/lib/toly_ui/navigation/toly_breadcrumb.dart @@ -3,9 +3,10 @@ import 'package:flutter/src/gestures/events.dart'; class TolyBreadcrumb extends StatelessWidget { final List items; + final double fontSize; final ValueChanged? onTapItem; - const TolyBreadcrumb({super.key, required this.items, this.onTapItem}); + const TolyBreadcrumb({super.key, required this.items, this.onTapItem, this.fontSize=14}); @override Widget build(BuildContext context) { @@ -13,6 +14,7 @@ class TolyBreadcrumb extends StatelessWidget { for (int i = 0; i < items.length; i++) { children.add(TolyBreadcrumbItem( + fontSize: fontSize, item: items[i], onTapItem: onTapItem, )); if (i != items.length - 1) { @@ -34,8 +36,10 @@ class TolyBreadcrumb extends StatelessWidget { class TolyBreadcrumbItem extends StatefulWidget { final BreadcrumbItem item; + final double fontSize; + final ValueChanged? onTapItem; - const TolyBreadcrumbItem({super.key, required this.item, required this.onTapItem}); + const TolyBreadcrumbItem({super.key, required this.item, required this.onTapItem, required this.fontSize}); @override State createState() => _TolyBreadcrumbItemState(); @@ -57,6 +61,7 @@ class _TolyBreadcrumbItemState extends State { } TextStyle style = TextStyle( + fontSize: widget.fontSize, fontWeight: hasTarget ? FontWeight.bold : null, color: color ); diff --git a/lib/components/toly_ui/navigation/toly_navigation_rail.dart b/packages/components/lib/toly_ui/navigation/toly_navigation_rail.dart similarity index 100% rename from lib/components/toly_ui/navigation/toly_navigation_rail.dart rename to packages/components/lib/toly_ui/navigation/toly_navigation_rail.dart diff --git a/lib/components/toly_ui/popable/drop_selectable_widget.dart b/packages/components/lib/toly_ui/popable/drop_selectable_widget.dart similarity index 100% rename from lib/components/toly_ui/popable/drop_selectable_widget.dart rename to packages/components/lib/toly_ui/popable/drop_selectable_widget.dart diff --git a/lib/components/toly_ui/popable/pop_menu.dart b/packages/components/lib/toly_ui/popable/pop_menu.dart similarity index 100% rename from lib/components/toly_ui/popable/pop_menu.dart rename to packages/components/lib/toly_ui/popable/pop_menu.dart diff --git a/lib/components/toly_ui/popable/popover.dart b/packages/components/lib/toly_ui/popable/popover.dart similarity index 100% rename from lib/components/toly_ui/popable/popover.dart rename to packages/components/lib/toly_ui/popable/popover.dart diff --git a/lib/components/toly_ui/popable/toly_pop_menu.dart b/packages/components/lib/toly_ui/popable/toly_pop_menu.dart similarity index 100% rename from lib/components/toly_ui/popable/toly_pop_menu.dart rename to packages/components/lib/toly_ui/popable/toly_pop_menu.dart diff --git a/lib/components/toly_ui/toly_ui.dart b/packages/components/lib/toly_ui/toly_ui.dart similarity index 75% rename from lib/components/toly_ui/toly_ui.dart rename to packages/components/lib/toly_ui/toly_ui.dart index 34d6178..c479cc1 100644 --- a/lib/components/toly_ui/toly_ui.dart +++ b/packages/components/lib/toly_ui/toly_ui.dart @@ -4,4 +4,5 @@ export 'navigation/toly_breadcrumb.dart'; export 'navigation/toly_navigation_rail.dart'; export 'popable/drop_selectable_widget.dart'; export 'popable/popover.dart'; -export 'popable/pop_menu.dart'; \ No newline at end of file +export 'popable/pop_menu.dart'; +export 'code_view/code_view.dart'; \ No newline at end of file diff --git a/lib/components/windows/drag_to_move_area.dart b/packages/components/lib/windows/drag_to_move_area.dart similarity index 100% rename from lib/components/windows/drag_to_move_area.dart rename to packages/components/lib/windows/drag_to_move_area.dart diff --git a/lib/components/windows/window_buttons.dart b/packages/components/lib/windows/window_buttons.dart similarity index 100% rename from lib/components/windows/window_buttons.dart rename to packages/components/lib/windows/window_buttons.dart diff --git a/packages/idraw/lib/components/coordinate_pro.dart b/packages/idraw/lib/components/coordinate_pro.dart index 6c334f2..d59eafe 100644 --- a/packages/idraw/lib/components/coordinate_pro.dart +++ b/packages/idraw/lib/components/coordinate_pro.dart @@ -30,8 +30,6 @@ class Coordinate { canvas.restore(); } - - void _drawAxis(Canvas canvas, Size size) { _gridPaint ..color = Colors.blue @@ -162,3 +160,4 @@ class Coordinate { canvas.restore(); } } + diff --git a/packages/idraw/lib/components/demo_shower.dart b/packages/idraw/lib/components/demo_shower.dart deleted file mode 100644 index 862e008..0000000 --- a/packages/idraw/lib/components/demo_shower.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class DemoShower extends StatefulWidget { - final List demos; - const DemoShower({super.key, required this.demos}); - - @override - State createState() => _DemoShowerState(); -} - -class _DemoShowerState extends State { - PageController _ctrl = PageController(); - int _index = 0; - - @override - Widget build(BuildContext context) { - return Material( - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - PageView( - controller: _ctrl, - children: widget.demos, - ), - - Positioned( - bottom: 20, - child: Wrap( - crossAxisAlignment: WrapCrossAlignment.center, - children: [ - TolyIconButton( - onTap: (){ - _index= (_index-1)%widget.demos.length; - setState(() { - - }); - _ctrl.animateToPage(_index,curve: Curves.easeIn,duration: Duration(milliseconds: 200)); - }, - iconData: Icons.navigate_before, - size: 36, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Text('第 ${_index+1}/${widget.demos.length} 页',style: TextStyle(fontSize: 16,color: Colors.grey),), - ), - - TolyIconButton( - onTap: (){ - _index= (_index+1)%widget.demos.length; - setState(() { - - }); - _ctrl.animateToPage(_index,curve: Curves.easeIn,duration: Duration(milliseconds: 200)); - }, - size: 36, - iconData: Icons.navigate_next, - ), - - ], - )), - - ], - ), - ); - } -} - - -class TolyIconButton extends StatefulWidget { - final IconData iconData; - final VoidCallback onTap; - final double size; - const TolyIconButton({ - super.key, - required this.iconData, - required this.size, required this.onTap, - }); - - @override - State createState() => _TolyIconButtonState(); -} - -class _TolyIconButtonState extends State { - bool _hover = false; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onTap, - child: MouseRegion( - onEnter: _onEnter, - onExit: _onExit, - cursor: SystemMouseCursors.click, - child: Container( - width: widget.size, - height: widget.size, - decoration: BoxDecoration( - color: _hover?Colors.grey.withOpacity(0.6):Colors.grey.withOpacity(0.5), shape: BoxShape.circle), - child: Icon( - widget.iconData, - size: 26, - color: Colors.white, - ), - ), - ), - ); - } - - void _onEnter(PointerEnterEvent event) { - setState(() { - _hover = true; - }); - } - - void _onExit(PointerExitEvent event) { - setState(() { - _hover = false; - }); - } -} diff --git a/packages/idraw/lib/p01/p01_page.dart b/packages/idraw/lib/p01/p01_page.dart index 0a87145..81cbc25 100644 --- a/packages/idraw/lib/p01/p01_page.dart +++ b/packages/idraw/lib/p01/p01_page.dart @@ -1,8 +1,7 @@ +import 'package:components/components.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/src/gestures/events.dart'; -import 'package:idraw/components/demo_shower.dart'; -import 's01_page.dart' as s1; -import 's02_page.dart' as s2; +import 's01.dart' as s1; +import 's02.dart' as s2; class P01Page extends StatelessWidget { const P01Page({super.key}); @@ -10,6 +9,7 @@ class P01Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p01', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p01/s01.dart b/packages/idraw/lib/p01/s01.dart new file mode 100644 index 0000000..570fe0f --- /dev/null +++ b/packages/idraw/lib/p01/s01.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + // 创建画笔 + final Paint paint = Paint(); + // 绘制圆 + canvas.drawCircle(Offset(100, 100), 10, paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} \ No newline at end of file diff --git a/packages/idraw/lib/p01/s02.dart b/packages/idraw/lib/p01/s02.dart new file mode 100644 index 0000000..f61fc01 --- /dev/null +++ b/packages/idraw/lib/p01/s02.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +class Paper extends StatelessWidget { + const Paper({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: CustomPaint( // 使用CustomPaint + painter: PaperPainter(), + ), + ); + } +} + +class PaperPainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + // 创建画笔 + final Paint paint = Paint(); + paint + ..color = Colors.blue //颜色 + ..strokeWidth = 4 //线宽 + ..style = PaintingStyle.stroke; //模式--线型 + + //绘制线 + canvas.drawLine(Offset(0, 0), Offset(100, 100), paint); + + Path path = Path(); + path.moveTo(100, 100); + path.lineTo(200, 0); + canvas.drawPath(path, paint..color = Colors.red); + } + + void drawLine(Canvas canvas) {} + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} \ No newline at end of file diff --git a/packages/idraw/lib/p02/p02_page.dart b/packages/idraw/lib/p02/p02_page.dart index 08903ba..34703d5 100644 --- a/packages/idraw/lib/p02/p02_page.dart +++ b/packages/idraw/lib/p02/p02_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -21,6 +21,7 @@ class P02Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p02', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p03/p03_page.dart b/packages/idraw/lib/p03/p03_page.dart index 83bf582..5e1676a 100644 --- a/packages/idraw/lib/p03/p03_page.dart +++ b/packages/idraw/lib/p03/p03_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -21,6 +21,7 @@ class P03Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p03', demos: [ s1.Paper(), s2.Paper(), @@ -39,3 +40,19 @@ class P03Page extends StatelessWidget { ); } } + + + + + + + + + + + + + + + + diff --git a/packages/idraw/lib/p04/p04_page.dart b/packages/idraw/lib/p04/p04_page.dart index cd8fb6e..d93009a 100644 --- a/packages/idraw/lib/p04/p04_page.dart +++ b/packages/idraw/lib/p04/p04_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -16,6 +16,7 @@ class P04Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p04', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p05/p05_page.dart b/packages/idraw/lib/p05/p05_page.dart index e11f734..3250d1c 100644 --- a/packages/idraw/lib/p05/p05_page.dart +++ b/packages/idraw/lib/p05/p05_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -20,6 +20,7 @@ class P05Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p05', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p06/p06_page.dart b/packages/idraw/lib/p06/p06_page.dart index 67738e0..2bfa6fd 100644 --- a/packages/idraw/lib/p06/p06_page.dart +++ b/packages/idraw/lib/p06/p06_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -14,6 +14,7 @@ class P06Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p06', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p07/p07_page.dart b/packages/idraw/lib/p07/p07_page.dart index 87c7ad1..33d13e2 100644 --- a/packages/idraw/lib/p07/p07_page.dart +++ b/packages/idraw/lib/p07/p07_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -14,6 +14,7 @@ class P07Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p07', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p08/p08_page.dart b/packages/idraw/lib/p08/p08_page.dart index a370abd..b93aaab 100644 --- a/packages/idraw/lib/p08/p08_page.dart +++ b/packages/idraw/lib/p08/p08_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -18,6 +18,8 @@ class P08Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p08', + demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p09/p09_page.dart b/packages/idraw/lib/p09/p09_page.dart index 2e55309..99dbc4b 100644 --- a/packages/idraw/lib/p09/p09_page.dart +++ b/packages/idraw/lib/p09/p09_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -11,6 +11,8 @@ class P09Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p09', + demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p10/p10_page.dart b/packages/idraw/lib/p10/p10_page.dart index 683a030..be71746 100644 --- a/packages/idraw/lib/p10/p10_page.dart +++ b/packages/idraw/lib/p10/p10_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -13,6 +13,8 @@ class P10Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p10', + demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p11/p11_page.dart b/packages/idraw/lib/p11/p11_page.dart index ab703a2..247c36a 100644 --- a/packages/idraw/lib/p11/p11_page.dart +++ b/packages/idraw/lib/p11/p11_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:idraw/components/demo_shower.dart'; +import 'package:components/components.dart'; import 's01.dart' as s1; import 's02.dart' as s2; import 's03.dart' as s3; @@ -12,6 +12,7 @@ class P11Page extends StatelessWidget { @override Widget build(BuildContext context) { return const DemoShower( + srcCodeDir: 'draw/p11', demos: [ s1.Paper(), s2.Paper(), diff --git a/packages/idraw/lib/p11/s02.dart b/packages/idraw/lib/p11/s02.dart index 5ce7adf..54113ed 100644 --- a/packages/idraw/lib/p11/s02.dart +++ b/packages/idraw/lib/p11/s02.dart @@ -80,7 +80,7 @@ class CurveBox extends StatefulWidget { final Color color; final Curve curve; - CurveBox({Key? key, this.color = Colors.lightBlue, this.curve = Curves.linear}) + const CurveBox({Key? key, this.color = Colors.lightBlue, this.curve = Curves.linear}) : super(key: key); @override diff --git a/packages/idraw/lib/p11/s04.dart b/packages/idraw/lib/p11/s04.dart index 5081600..96aae54 100644 --- a/packages/idraw/lib/p11/s04.dart +++ b/packages/idraw/lib/p11/s04.dart @@ -34,6 +34,12 @@ class _PaperState extends State with SingleTickerProviderStateMixin { // _controller.repeat(reverse: true); } + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Center( diff --git a/pubspec.lock b/pubspec.lock index d1c15f3..af03a45 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,22 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - adaptive_breakpoints: - dependency: transitive - description: - name: adaptive_breakpoints - sha256: "3aa6ef09074fe7824dfdc9a6d9f955c8a3bae0fb71c495cbd72f471a87699b4f" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.6" - adaptive_navigation: - dependency: "direct main" - description: - name: adaptive_navigation - sha256: "271d3e54147ce37b389c3d7d19777b4340e4ccd440d0349457c8b8db197b1c41" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.0.9" archive: dependency: transitive description: @@ -65,6 +49,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.17.2" + components: + dependency: "direct main" + description: + path: "packages/components" + relative: true + source: path + version: "0.0.1" convert: dependency: transitive description: @@ -89,14 +80,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.5" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.5" fake_async: dependency: transitive description: @@ -110,14 +93,6 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_colorpicker: - dependency: "direct main" - description: - name: flutter_colorpicker - sha256: "458a6ed8ea480eb16ff892aedb4b7092b2804affd7e046591fb03127e8d8ef8b" - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.3" flutter_lints: dependency: "direct dev" description: @@ -207,14 +182,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.9.1" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.0" path: dependency: transitive description: @@ -223,14 +190,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.8.3" - path_to_regexp: - dependency: "direct main" - description: - name: path_to_regexp - sha256: "169d78fbd55e61ea8873bcca545979f559d22238f66facdd7ef30870c7f53327" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.4.0" petitparser: dependency: transitive description: @@ -239,14 +198,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "5.4.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.6" pointycastle: dependency: transitive description: @@ -255,22 +206,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "3.7.3" - provider: - dependency: "direct main" - description: - name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.0.5" - quiver: - dependency: "direct main" - description: - name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.2.1" screen_retriever: dependency: transitive description: @@ -338,7 +273,7 @@ packages: path: "E:\\Projects\\Flutter\\packages\\toly_menu" relative: false source: path - version: "0.0.1" + version: "0.0.2" typed_data: dependency: transitive description: @@ -347,78 +282,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.3.2" - url_launcher: - dependency: "direct main" - description: - name: url_launcher - sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.1.14" - url_launcher_android: - dependency: transitive - description: - name: url_launcher_android - sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.1.0" - url_launcher_ios: - dependency: transitive - description: - name: url_launcher_ios - sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" - url: "https://pub.flutter-io.cn" - source: hosted - version: "6.1.5" - url_launcher_linux: - dependency: transitive - description: - name: url_launcher_linux - sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.6" - url_launcher_macos: - dependency: transitive - description: - name: url_launcher_macos - sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.7" - url_launcher_platform_interface: - dependency: transitive - description: - name: url_launcher_platform_interface - sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.5" - url_launcher_web: - dependency: transitive - description: - name: url_launcher_web - sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5" - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.20" - url_launcher_windows: - dependency: transitive - description: - name: url_launcher_windows - sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.8" - url_strategy: - dependency: "direct main" - description: - name: url_strategy - sha256: "42b68b42a9864c4d710401add17ad06e28f1c1d5500c93b98c431f6b0ea4ab87" - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.2.0" vector_math: dependency: transitive description: @@ -453,4 +316,4 @@ packages: version: "6.3.0" sdks: dart: ">=3.1.1 <4.0.0" - flutter: ">=3.13.0" + flutter: ">=3.7.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8b73a4f..08b31c1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,23 +30,16 @@ environment: dependencies: flutter: sdk: flutter - flutter_colorpicker: ^1.0.3 window_manager: ^0.3.7 - adaptive_navigation: ^0.0.4 - go_router: ^12.1.1 - provider: 6.0.5 - url_launcher: ^6.0.7 - equatable: ^2.0.5 - url_strategy: ^0.2.0 - quiver: ^3.1.0 - path_to_regexp: ^0.4.0 - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + go_router: ^12.1.1 toly_menu: path: E:\Projects\Flutter\packages\toly_menu +# toly_menu: ^0.0.2 idraw: path: packages/idraw + components: + path: packages/components dev_dependencies: flutter_test: @@ -64,6 +57,10 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: + fonts: + - family: FxIcon + fonts: + - asset: assets/iconfont/fx_icon.ttf # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in @@ -73,6 +70,17 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - assets/images/ + - assets/draw/p01/ + - assets/draw/p02/ + - assets/draw/p03/ + - assets/draw/p04/ + - assets/draw/p05/ + - assets/draw/p06/ + - assets/draw/p07/ + - assets/draw/p08/ + - assets/draw/p09/ + - assets/draw/p10/ + - assets/draw/p11/ # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg @@ -100,4 +108,4 @@ flutter: # weight: 700 # # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + # see https://flutter.dev/custom-fonts/#from-packages \ No newline at end of file diff --git a/test/parser/menu.dart b/test/parser/menu.dart index 9db4b6a..2513c19 100644 --- a/test/parser/menu.dart +++ b/test/parser/menu.dart @@ -1,10 +1,56 @@ + import 'package:iroute/navigation/router/menus/menu_tree.dart'; import 'package:toly_menu/toly_menu.dart'; + + void main() { - Map data = dashboard; - MenuNode node = parser(data, 0, ''); + + MenuNode node = parser(root, -1, ''); print(node); + List result = findNodes(node,Uri.parse('/dashboard/view'),0,'/',[]); + print(result); +} + +MenuNode? queryMenuNodeByPath(MenuNode node, String path) { + if(node.path==path){ + return node; + } + if(node.children.isNotEmpty){ + for(int i=0;i findNodes( + MenuNode node, + Uri uri, + int deep, + String prefix, + List result, + ) { + List parts = uri.pathSegments; + if (deep > parts.length - 1) { + return result; + } + String target = parts[deep]; + if (node.children.isNotEmpty) { + target = prefix + target; + List nodes = node.children.where((e) => e.path == target).toList(); + bool match = nodes.isNotEmpty; + if (match) { + MenuNode matched = nodes.first; + result.add(matched); + String nextPrefix = '${matched.path}/'; + findNodes(matched, uri, ++deep, nextPrefix, result); + } + } + return result; } MenuNode parser(Map data, int deep, String prefix) { diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index fe7ec1c..d6b86fa 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,14 +7,11 @@ #include "generated_plugin_registrant.h" #include -#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); - UrlLauncherWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowManagerPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("WindowManagerPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index fb2dea6..bfa52f4 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST screen_retriever - url_launcher_windows window_manager )