Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.55 KB | None | 0 0
  1. import 'package:flutter/material.dart';
  2. import 'dart:math' as math;
  3.  
  4. import 'package:flutter/semantics.dart';
  5.  
  6. class OutlineLabelBox extends CustomPainter {
  7. final String labelText;
  8. final TextStyle labelStyle;
  9. final double labelPadding;
  10. final Color strokeColor;
  11. final double strokeWidth;
  12.  
  13. OutlineLabelBox(
  14. {this.labelText,
  15. this.labelStyle,
  16. this.labelPadding = 12.0,
  17. this.strokeColor = Colors.black,
  18. this.strokeWidth = 1.0});
  19.  
  20. @override
  21. void paint(Canvas canvas, Size size) {
  22. final TextPainter tp = TextPainter(
  23. text: TextSpan(
  24. text: this.labelText,
  25. style: this
  26. .labelStyle
  27. .merge(TextStyle(textBaseline: TextBaseline.ideographic))),
  28. textDirection: TextDirection.ltr,
  29. textAlign: TextAlign.start)
  30. ..layout();
  31. final RRect outer = RRect.fromRectAndCorners(
  32. Offset.zero & size,
  33. );
  34. final RRect center = outer.deflate(1 / 2.0);
  35. final Path path = _gapBorderPath(
  36. canvas,
  37. center,
  38. (size.width - tp.width) / 2.0 - labelPadding,
  39. tp.width + (labelPadding * 2));
  40.  
  41. canvas.drawPath(
  42. path,
  43. Paint()
  44. ..color = this.strokeColor
  45. ..strokeWidth = this.strokeWidth
  46. ..style = PaintingStyle.stroke);
  47.  
  48. tp.paint(canvas, Offset((size.width - tp.width) / 2.0, -(tp.height) / 2));
  49. }
  50.  
  51. Path _gapBorderPath(
  52. Canvas canvas, RRect center, double start, double extent) {
  53. final Rect tlCorner = Rect.fromLTWH(
  54. center.left,
  55. center.top,
  56. center.tlRadiusX * 2.0,
  57. center.tlRadiusY * 2.0,
  58. );
  59. final Rect trCorner = Rect.fromLTWH(
  60. center.right - center.trRadiusX * 2.0,
  61. center.top,
  62. center.trRadiusX * 2.0,
  63. center.trRadiusY * 2.0,
  64. );
  65. final Rect brCorner = Rect.fromLTWH(
  66. center.right - center.brRadiusX * 2.0,
  67. center.bottom - center.brRadiusY * 2.0,
  68. center.brRadiusX * 2.0,
  69. center.brRadiusY * 2.0,
  70. );
  71. final Rect blCorner = Rect.fromLTWH(
  72. center.left,
  73. center.bottom - center.brRadiusY * 2.0,
  74. center.blRadiusX * 2.0,
  75. center.blRadiusY * 2.0,
  76. );
  77.  
  78. const double cornerArcSweep = math.pi / 2.0;
  79. final double tlCornerArcSweep = start < center.tlRadiusX
  80. ? math.asin((start / center.tlRadiusX).clamp(-1.0, 1.0))
  81. : math.pi / 2.0;
  82.  
  83. final Path path = Path()
  84. ..addArc(tlCorner, math.pi, tlCornerArcSweep)
  85. ..moveTo(center.left + center.tlRadiusX, center.top);
  86.  
  87. if (start > center.tlRadiusX) path.lineTo(center.left + start, center.top);
  88.  
  89. const double trCornerArcStart = (3 * math.pi) / 2.0;
  90. const double trCornerArcSweep = cornerArcSweep;
  91. if (start + extent < center.width - center.trRadiusX) {
  92. path
  93. ..relativeMoveTo(extent, 0.0)
  94. ..lineTo(center.right - center.trRadiusX, center.top)
  95. ..addArc(trCorner, trCornerArcStart, trCornerArcSweep);
  96. } else if (start + extent < center.width) {
  97. final double dx = center.width - (start + extent);
  98. final double sweep = math.acos(dx / center.trRadiusX);
  99. path.addArc(trCorner, trCornerArcStart + sweep, trCornerArcSweep - sweep);
  100. }
  101.  
  102. return path
  103. ..moveTo(center.right, center.top + center.trRadiusY)
  104. ..lineTo(center.right, center.bottom - center.brRadiusY)
  105. ..addArc(brCorner, 0.0, cornerArcSweep)
  106. ..lineTo(center.left + center.blRadiusX, center.bottom)
  107. ..addArc(blCorner, math.pi / 2.0, cornerArcSweep)
  108. ..lineTo(center.left, center.top + center.trRadiusY);
  109. }
  110.  
  111. double lerpDouble(num a, num b, double t) {
  112. if (a == null && b == null) return null;
  113. a ??= 0.0;
  114. b ??= 0.0;
  115. return a + (b - a) * t;
  116. }
  117.  
  118. @override
  119. SemanticsBuilderCallback get semanticsBuilder {
  120. return (Size size) {
  121. var rect = Offset.zero & size;
  122. var width = size.shortestSide * 0.4;
  123. rect = const Alignment(0.8, -0.9).inscribe(Size(width, width), rect);
  124. return [
  125. CustomPainterSemantics(
  126. rect: rect,
  127. properties: SemanticsProperties(
  128. label: this.labelText,
  129. textDirection: TextDirection.ltr,
  130. ),
  131. ),
  132. ];
  133. };
  134. }
  135.  
  136. // Since this Sky painter has no fields, it always paints
  137. // the same thing and semantics information is the same.
  138. // Therefore we return false here. If we had fields (set
  139. // from the constructor) then we would return true if any
  140. // of them differed from the same fields on the oldDelegate.
  141. @override
  142. bool shouldRepaint(OutlineLabelBox oldDelegate) => false;
  143. @override
  144. bool shouldRebuildSemantics(OutlineLabelBox oldDelegate) => false;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement