mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
103 lines
2.7 KiB
Dart
103 lines
2.7 KiB
Dart
import 'dart:math';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
class DisabledIcon<T extends Widget> extends SingleChildRenderObjectWidget {
|
|
final Color? color;
|
|
final double lineLengthScale;
|
|
final StrokeCap strokeCap;
|
|
|
|
const DisabledIcon({
|
|
super.key,
|
|
required T child,
|
|
this.color,
|
|
double? lineLengthScale,
|
|
StrokeCap? strokeCap,
|
|
}) : lineLengthScale = lineLengthScale ?? 0.9,
|
|
strokeCap = strokeCap ?? StrokeCap.butt,
|
|
super(child: child);
|
|
|
|
@override
|
|
RenderObject createRenderObject(BuildContext context) {
|
|
return RenderMaskedIcon(
|
|
color ??
|
|
(child is Icon
|
|
? (child as Icon).color ?? IconTheme.of(context).color!
|
|
: IconTheme.of(context).color!),
|
|
lineLengthScale,
|
|
strokeCap,
|
|
);
|
|
}
|
|
|
|
T enable() => child as T;
|
|
}
|
|
|
|
class RenderMaskedIcon extends RenderProxyBox {
|
|
final Color color;
|
|
final double lineLengthScale;
|
|
final StrokeCap strokeCap;
|
|
|
|
RenderMaskedIcon(this.color, this.lineLengthScale, this.strokeCap);
|
|
|
|
@override
|
|
void paint(PaintingContext context, Offset offset) {
|
|
final strokeWidth = size.width / 12;
|
|
|
|
final canvas = context.canvas;
|
|
var rect = offset & size;
|
|
|
|
final sqrt2Width = strokeWidth * sqrt2; // rotate pi / 4
|
|
|
|
// final path = Path.combine(
|
|
// PathOperation.difference,
|
|
// Path()..addRect(rect),
|
|
// Path()..moveTo(rect.left, rect.top)
|
|
// ..relativeLineTo(sqrt2Width, 0)
|
|
// ..lineTo(rect.right, rect.bottom - sqrt2Width)
|
|
// ..lineTo(rect.right, rect.bottom)
|
|
// ..close(),
|
|
// );
|
|
|
|
final path = Path.combine(
|
|
PathOperation.union,
|
|
Path() // bottom
|
|
..moveTo(rect.left, rect.bottom)
|
|
..lineTo(rect.left, rect.top + sqrt2Width)
|
|
..lineTo(rect.right - sqrt2Width, rect.bottom)
|
|
..close(),
|
|
Path() // top
|
|
..moveTo(rect.right, rect.top)
|
|
..lineTo(rect.right, rect.bottom - sqrt2Width)
|
|
..lineTo(rect.left + sqrt2Width, rect.top),
|
|
);
|
|
|
|
canvas
|
|
..save()
|
|
..clipPath(path, doAntiAlias: false);
|
|
super.paint(context, offset);
|
|
|
|
context.canvas.restore();
|
|
|
|
final linePaint = Paint()
|
|
..color = color
|
|
..strokeWidth = strokeWidth
|
|
..strokeCap = strokeCap;
|
|
|
|
final strokeOffset = strokeWidth * sqrt1_2 / 2;
|
|
rect = rect
|
|
.translate(-strokeOffset, strokeOffset)
|
|
.deflate(size.width * lineLengthScale);
|
|
canvas.drawLine(
|
|
rect.topLeft,
|
|
rect.bottomRight,
|
|
linePaint,
|
|
);
|
|
}
|
|
}
|
|
|
|
extension DisabledIconExt on Icon {
|
|
DisabledIcon<Icon> disable([double? lineLengthScale]) =>
|
|
DisabledIcon(lineLengthScale: lineLengthScale, child: this);
|
|
}
|