Vaibhav Surve a5dd5e19fc Add Windows runner implementation for Flutter application
- Created CMakeLists.txt for Flutter and runner components.
- Implemented resource script (Runner.rc) for application metadata.
- Developed main entry point (main.cpp) for the Windows application.
- Added FlutterWindow class to manage the Flutter view within a Win32 window.
- Implemented utility functions for console management and command line argument parsing.
- Established Win32Window class for high DPI-aware window handling.
- Included application icon and manifest for proper Windows integration.
- Set up build configurations and dependencies for the Flutter application on Windows.
2025-04-23 09:55:31 +05:30

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;
}
}