- Created generated_plugin_registrant.cc and generated_plugin_registrant.h to manage plugin registration. - Added generated_plugins.cmake for plugin configuration in CMake. - Implemented CMakeLists.txt for the Windows runner, defining build settings and dependencies. - Created Runner.rc for application resources including versioning and icons. - Developed flutter_window.cpp and flutter_window.h to manage the Flutter window lifecycle. - Implemented main.cpp as the entry point for the Windows application. - Added resource.h for resource definitions. - Included app icon in resources. - Created runner.exe.manifest for application settings. - Developed utils.cpp and utils.h for console management and command line argument handling. - Implemented win32_window.cpp and win32_window.h for high DPI-aware window management.
202 lines
5.8 KiB
Dart
202 lines
5.8 KiB
Dart
// ignore_for_file: empty_catches
|
|
|
|
import 'dart:ui';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
bool _isEmpty(double? d) {
|
|
return d == null || d == 0.0;
|
|
}
|
|
|
|
class MyDottedLineCorner {
|
|
final double leftTopCorner;
|
|
final double rightTopCorner;
|
|
final double rightBottomCorner;
|
|
final double leftBottomCorner;
|
|
|
|
const MyDottedLineCorner({
|
|
this.leftTopCorner = 0,
|
|
this.rightTopCorner = 0,
|
|
this.rightBottomCorner = 0,
|
|
this.leftBottomCorner = 0,
|
|
});
|
|
|
|
MyDottedLineCorner.all(double radius)
|
|
: leftTopCorner = radius,
|
|
rightTopCorner = radius,
|
|
rightBottomCorner = radius,
|
|
leftBottomCorner = radius;
|
|
}
|
|
|
|
class MyDottedLine extends StatefulWidget {
|
|
final Color color;
|
|
|
|
final double? height;
|
|
|
|
final double? width;
|
|
|
|
final double strokeWidth;
|
|
|
|
final double dottedLength;
|
|
|
|
final double space;
|
|
|
|
final MyDottedLineCorner? corner;
|
|
|
|
final Widget? child;
|
|
|
|
MyDottedLine({
|
|
super.key,
|
|
this.color = Colors.black,
|
|
this.height,
|
|
this.width,
|
|
this.dottedLength = 5.0,
|
|
this.space = 3.0,
|
|
this.strokeWidth = 1.0,
|
|
this.corner,
|
|
this.child,
|
|
}) {
|
|
assert(width != null || height != null || child != null);
|
|
}
|
|
|
|
@override
|
|
_MyDottedLineState createState() => _MyDottedLineState();
|
|
}
|
|
|
|
class _MyDottedLineState extends State<MyDottedLine> {
|
|
double? childWidth;
|
|
double? childHeight;
|
|
GlobalKey childKey = GlobalKey();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (_isEmpty(widget.width) && _isEmpty(widget.height) && widget.child == null) {
|
|
return Container();
|
|
}
|
|
|
|
if (widget.child != null) {
|
|
tryToGetChildSize();
|
|
List<Widget> children = [];
|
|
children.add(Container(
|
|
clipBehavior: widget.corner == null ? Clip.none : Clip.antiAlias,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(widget.corner != null ? widget.corner!.leftTopCorner : 0.0),
|
|
topRight: Radius.circular(widget.corner != null ? widget.corner!.rightTopCorner : 0.0),
|
|
bottomLeft: Radius.circular(widget.corner != null ? widget.corner!.leftBottomCorner : 0.0),
|
|
bottomRight: Radius.circular(widget.corner != null ? widget.corner!.rightBottomCorner : 0.0),
|
|
),
|
|
),
|
|
key: childKey,
|
|
child: widget.child,
|
|
));
|
|
if (childWidth != null && childHeight != null) {
|
|
children.add(dashPath(width: childWidth, height: childHeight));
|
|
}
|
|
return Stack(
|
|
children: children,
|
|
);
|
|
} else {
|
|
return dashPath(width: widget.width, height: widget.height);
|
|
}
|
|
}
|
|
|
|
void tryToGetChildSize() {
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
try {
|
|
RenderBox box = childKey.currentContext!.findRenderObject() as RenderBox;
|
|
double tempWidth = box.size.width;
|
|
double tempHeight = box.size.height;
|
|
bool needUpdate = tempWidth != childWidth || tempHeight != childHeight;
|
|
if (needUpdate) {
|
|
setState(() {
|
|
childWidth = tempWidth;
|
|
childHeight = tempHeight;
|
|
});
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
}
|
|
|
|
CustomPaint dashPath({double? width, double? height}) {
|
|
return CustomPaint(
|
|
size: Size(_isEmpty(width) ? widget.strokeWidth : width!, _isEmpty(height) ? widget.strokeWidth : height!),
|
|
foregroundPainter: _DottedLinePainter()
|
|
..color = widget.color
|
|
..dottedLength = widget.dottedLength
|
|
..space = widget.space
|
|
..strokeWidth = widget.strokeWidth
|
|
..corner = widget.corner
|
|
..isShape = !_isEmpty(height) && !_isEmpty(width),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _DottedLinePainter extends CustomPainter {
|
|
late Color color;
|
|
double? dottedLength;
|
|
double? space;
|
|
late double strokeWidth;
|
|
late bool isShape;
|
|
MyDottedLineCorner? corner;
|
|
Radius topLeft = Radius.zero;
|
|
Radius topRight = Radius.zero;
|
|
Radius bottomRight = Radius.zero;
|
|
Radius bottomLeft = Radius.zero;
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
var isHorizontal = size.width > size.height;
|
|
final Paint paint = Paint()
|
|
..isAntiAlias = true
|
|
..filterQuality = FilterQuality.high
|
|
..color = color
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = strokeWidth;
|
|
|
|
if (!isShape) {
|
|
double length = isHorizontal ? size.width : size.height;
|
|
double count = (length) / (dottedLength! + space!);
|
|
if (count < 2.0) return;
|
|
var startOffset = Offset(0, 0);
|
|
for (int i = 0; i < count.toInt(); i++) {
|
|
canvas.drawLine(startOffset, startOffset.translate((isHorizontal ? dottedLength! : 0), (isHorizontal ? 0 : dottedLength!)), paint);
|
|
startOffset = startOffset.translate((isHorizontal ? (dottedLength! + space!) : 0), (isHorizontal ? 0 : (dottedLength! + space!)));
|
|
}
|
|
} else {
|
|
Path path = Path();
|
|
path.addRRect(RRect.fromLTRBAndCorners(
|
|
0,
|
|
0,
|
|
size.width,
|
|
size.height,
|
|
topLeft: Radius.circular(corner != null ? corner!.leftTopCorner : 0.0),
|
|
topRight: Radius.circular(corner != null ? corner!.rightTopCorner : 0.0),
|
|
bottomLeft: Radius.circular(corner != null ? corner!.leftBottomCorner : 0.0),
|
|
bottomRight: Radius.circular(corner != null ? corner!.rightBottomCorner : 0.0),
|
|
));
|
|
|
|
Path draw = buildDashPath(path, dottedLength, space);
|
|
canvas.drawPath(draw, paint);
|
|
}
|
|
}
|
|
|
|
Path buildDashPath(Path path, double? dottedLength, double? space) {
|
|
final Path r = Path();
|
|
for (PathMetric metric in path.computeMetrics()) {
|
|
double start = 0.0;
|
|
while (start < metric.length) {
|
|
double end = start + dottedLength!;
|
|
r.addPath(metric.extractPath(start, end), Offset.zero);
|
|
start = end + space!;
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(_DottedLinePainter oldDelegate) {
|
|
return true;
|
|
}
|
|
}
|