Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'package:flutter/material.dart';
- import 'dart:math' as math;
- import 'package:flutter/semantics.dart';
- class OutlineLabelBox extends CustomPainter {
- final String labelText;
- final TextStyle labelStyle;
- final double labelPadding;
- final Color strokeColor;
- final double strokeWidth;
- OutlineLabelBox(
- {this.labelText,
- this.labelStyle,
- this.labelPadding = 12.0,
- this.strokeColor = Colors.black,
- this.strokeWidth = 1.0});
- @override
- void paint(Canvas canvas, Size size) {
- final TextPainter tp = TextPainter(
- text: TextSpan(
- text: this.labelText,
- style: this
- .labelStyle
- .merge(TextStyle(textBaseline: TextBaseline.ideographic))),
- textDirection: TextDirection.ltr,
- textAlign: TextAlign.start)
- ..layout();
- final RRect outer = RRect.fromRectAndCorners(
- Offset.zero & size,
- );
- final RRect center = outer.deflate(1 / 2.0);
- final Path path = _gapBorderPath(
- canvas,
- center,
- (size.width - tp.width) / 2.0 - labelPadding,
- tp.width + (labelPadding * 2));
- canvas.drawPath(
- path,
- Paint()
- ..color = this.strokeColor
- ..strokeWidth = this.strokeWidth
- ..style = PaintingStyle.stroke);
- tp.paint(canvas, Offset((size.width - tp.width) / 2.0, -(tp.height) / 2));
- }
- Path _gapBorderPath(
- Canvas canvas, RRect center, double start, double extent) {
- final Rect tlCorner = Rect.fromLTWH(
- center.left,
- center.top,
- center.tlRadiusX * 2.0,
- center.tlRadiusY * 2.0,
- );
- final Rect trCorner = Rect.fromLTWH(
- center.right - center.trRadiusX * 2.0,
- center.top,
- center.trRadiusX * 2.0,
- center.trRadiusY * 2.0,
- );
- final Rect brCorner = Rect.fromLTWH(
- center.right - center.brRadiusX * 2.0,
- center.bottom - center.brRadiusY * 2.0,
- center.brRadiusX * 2.0,
- center.brRadiusY * 2.0,
- );
- final Rect blCorner = Rect.fromLTWH(
- center.left,
- center.bottom - center.brRadiusY * 2.0,
- center.blRadiusX * 2.0,
- center.blRadiusY * 2.0,
- );
- const double cornerArcSweep = math.pi / 2.0;
- final double tlCornerArcSweep = start < center.tlRadiusX
- ? math.asin((start / center.tlRadiusX).clamp(-1.0, 1.0))
- : math.pi / 2.0;
- final Path path = Path()
- ..addArc(tlCorner, math.pi, tlCornerArcSweep)
- ..moveTo(center.left + center.tlRadiusX, center.top);
- if (start > center.tlRadiusX) path.lineTo(center.left + start, center.top);
- const double trCornerArcStart = (3 * math.pi) / 2.0;
- const double trCornerArcSweep = cornerArcSweep;
- if (start + extent < center.width - center.trRadiusX) {
- path
- ..relativeMoveTo(extent, 0.0)
- ..lineTo(center.right - center.trRadiusX, center.top)
- ..addArc(trCorner, trCornerArcStart, trCornerArcSweep);
- } else if (start + extent < center.width) {
- final double dx = center.width - (start + extent);
- final double sweep = math.acos(dx / center.trRadiusX);
- path.addArc(trCorner, trCornerArcStart + sweep, trCornerArcSweep - sweep);
- }
- return path
- ..moveTo(center.right, center.top + center.trRadiusY)
- ..lineTo(center.right, center.bottom - center.brRadiusY)
- ..addArc(brCorner, 0.0, cornerArcSweep)
- ..lineTo(center.left + center.blRadiusX, center.bottom)
- ..addArc(blCorner, math.pi / 2.0, cornerArcSweep)
- ..lineTo(center.left, center.top + center.trRadiusY);
- }
- double lerpDouble(num a, num b, double t) {
- if (a == null && b == null) return null;
- a ??= 0.0;
- b ??= 0.0;
- return a + (b - a) * t;
- }
- @override
- SemanticsBuilderCallback get semanticsBuilder {
- return (Size size) {
- var rect = Offset.zero & size;
- var width = size.shortestSide * 0.4;
- rect = const Alignment(0.8, -0.9).inscribe(Size(width, width), rect);
- return [
- CustomPainterSemantics(
- rect: rect,
- properties: SemanticsProperties(
- label: this.labelText,
- textDirection: TextDirection.ltr,
- ),
- ),
- ];
- };
- }
- // Since this Sky painter has no fields, it always paints
- // the same thing and semantics information is the same.
- // Therefore we return false here. If we had fields (set
- // from the constructor) then we would return true if any
- // of them differed from the same fields on the oldDelegate.
- @override
- bool shouldRepaint(OutlineLabelBox oldDelegate) => false;
- @override
- bool shouldRebuildSemantics(OutlineLabelBox oldDelegate) => false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement