David PHAM-VAN

Add GridPaper widget

@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 4
5 - A borderRadius can only be given for a uniform Border 5 - A borderRadius can only be given for a uniform Border
6 - Add LayoutWidgetBuilder 6 - Add LayoutWidgetBuilder
  7 +- Add GridPaper widget
7 8
8 ## 1.13.0 9 ## 1.13.0
9 10
@@ -37,6 +37,7 @@ export 'widgets/flex.dart'; @@ -37,6 +37,7 @@ export 'widgets/flex.dart';
37 export 'widgets/font.dart'; 37 export 'widgets/font.dart';
38 export 'widgets/forms.dart'; 38 export 'widgets/forms.dart';
39 export 'widgets/geometry.dart'; 39 export 'widgets/geometry.dart';
  40 +export 'widgets/grid_paper.dart';
40 export 'widgets/grid_view.dart'; 41 export 'widgets/grid_view.dart';
41 export 'widgets/icon.dart'; 42 export 'widgets/icon.dart';
42 export 'widgets/image.dart'; 43 export 'widgets/image.dart';
  1 +/*
  2 + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +import '../pdf.dart';
  18 +import 'box_border.dart';
  19 +import 'geometry.dart';
  20 +
  21 +import 'widget.dart';
  22 +
  23 +/// A widget that draws a rectilinear grid of lines.
  24 +/// The grid is drawn over the [child] widget.
  25 +class GridPaper extends SingleChildWidget {
  26 + /// Creates a widget that draws a rectilinear grid lines.
  27 + GridPaper({
  28 + PdfColor color = lineColor,
  29 + double interval = 100,
  30 + int divisions = 5,
  31 + int subdivisions = 2,
  32 + Widget child,
  33 + }) : assert(divisions > 0,
  34 + 'The "divisions" property must be greater than zero. If there were no divisions, the grid paper would not paint anything.'),
  35 + assert(subdivisions > 0,
  36 + 'The "subdivisions" property must be greater than zero. If there were no subdivisions, the grid paper would not paint anything.'),
  37 + horizontalColor = color,
  38 + verticalColor = color,
  39 + horizontalInterval = interval,
  40 + verticalInterval = interval,
  41 + horizontalDivisions = divisions,
  42 + verticalDivisions = divisions,
  43 + horizontalSubdivisions = subdivisions,
  44 + verticalSubdivisions = subdivisions,
  45 + margin = EdgeInsets.zero,
  46 + horizontalOffset = 0,
  47 + verticalOffset = 0,
  48 + border = const Border(),
  49 + scale = 1,
  50 + opacity = 0.5,
  51 + super(child: child);
  52 +
  53 + GridPaper.millimeter({
  54 + PdfColor color = lineColor,
  55 + Widget child,
  56 + }) : horizontalColor = color,
  57 + verticalColor = color,
  58 + horizontalInterval = 5 * PdfPageFormat.cm,
  59 + verticalInterval = 5 * PdfPageFormat.cm,
  60 + horizontalDivisions = 5,
  61 + verticalDivisions = 5,
  62 + horizontalSubdivisions = 10,
  63 + verticalSubdivisions = 10,
  64 + margin = EdgeInsets.zero,
  65 + horizontalOffset = 0,
  66 + verticalOffset = 0,
  67 + border = const Border(),
  68 + scale = 1,
  69 + opacity = 0.5,
  70 + super(child: child);
  71 +
  72 + GridPaper.seyes({
  73 + this.margin = const EdgeInsets.only(
  74 + top: 20 * PdfPageFormat.mm,
  75 + bottom: 10 * PdfPageFormat.mm,
  76 + left: 36 * PdfPageFormat.mm,
  77 + right: 0,
  78 + ),
  79 + Widget child,
  80 + }) : horizontalColor = const PdfColor.fromInt(0xffc8c8de),
  81 + verticalColor = const PdfColor.fromInt(0xffc8c8de),
  82 + horizontalInterval = 8 * PdfPageFormat.mm,
  83 + verticalInterval = 8 * PdfPageFormat.mm,
  84 + horizontalDivisions = 1,
  85 + verticalDivisions = 4,
  86 + horizontalSubdivisions = 1,
  87 + verticalSubdivisions = 1,
  88 + horizontalOffset = 0,
  89 + verticalOffset = 1,
  90 + border = const Border(
  91 + left: BorderSide(
  92 + color: PdfColor.fromInt(0xfff6bbcf),
  93 + )),
  94 + scale = 1,
  95 + opacity = 1,
  96 + super(child: child);
  97 +
  98 + GridPaper.collegeRuled({
  99 + this.margin = const EdgeInsets.only(
  100 + top: 1 * PdfPageFormat.inch,
  101 + bottom: 0.6 * PdfPageFormat.inch,
  102 + left: 1.25 * PdfPageFormat.inch,
  103 + right: 0,
  104 + ),
  105 + Widget child,
  106 + }) : horizontalColor = lineColor,
  107 + verticalColor = lineColor,
  108 + horizontalInterval = double.infinity,
  109 + verticalInterval = 9 / 32 * PdfPageFormat.inch,
  110 + horizontalDivisions = 1,
  111 + verticalDivisions = 1,
  112 + horizontalSubdivisions = 1,
  113 + verticalSubdivisions = 1,
  114 + horizontalOffset = 0,
  115 + verticalOffset = 1,
  116 + border = const Border(
  117 + left: BorderSide(
  118 + color: PdfColors.red,
  119 + )),
  120 + scale = 1,
  121 + opacity = 1,
  122 + super(child: child);
  123 +
  124 + GridPaper.quad({
  125 + PdfColor color = lineColor,
  126 + Widget child,
  127 + }) : horizontalColor = color,
  128 + verticalColor = color,
  129 + horizontalInterval = PdfPageFormat.inch,
  130 + verticalInterval = PdfPageFormat.inch,
  131 + horizontalDivisions = 4,
  132 + verticalDivisions = 4,
  133 + horizontalSubdivisions = 1,
  134 + verticalSubdivisions = 1,
  135 + margin = EdgeInsets.zero,
  136 + horizontalOffset = 0,
  137 + verticalOffset = 0,
  138 + border = const Border(),
  139 + scale = 1,
  140 + opacity = 0.5,
  141 + super(child: child);
  142 +
  143 + GridPaper.engineering({
  144 + PdfColor color = lineColor,
  145 + Widget child,
  146 + }) : horizontalColor = color,
  147 + verticalColor = color,
  148 + horizontalInterval = PdfPageFormat.inch,
  149 + verticalInterval = PdfPageFormat.inch,
  150 + horizontalDivisions = 5,
  151 + verticalDivisions = 5,
  152 + horizontalSubdivisions = 2,
  153 + verticalSubdivisions = 2,
  154 + margin = EdgeInsets.zero,
  155 + horizontalOffset = 0,
  156 + verticalOffset = 0,
  157 + border = const Border(),
  158 + scale = 1,
  159 + opacity = 0.5,
  160 + super(child: child);
  161 +
  162 + static const lineColor = PdfColor.fromInt(0xffc3e8f3);
  163 +
  164 + /// The color to draw the horizontal lines in the grid.
  165 + final PdfColor horizontalColor;
  166 +
  167 + /// The color to draw the vertical lines in the grid.
  168 + final PdfColor verticalColor;
  169 +
  170 + /// The distance between the primary horizontal lines in the grid, in logical pixels.
  171 + final double horizontalInterval;
  172 +
  173 + /// The distance between the primary vertical lines in the grid, in logical pixels.
  174 + final double verticalInterval;
  175 +
  176 + /// The number of major horizontal divisions within each primary grid cell.
  177 + final int horizontalDivisions;
  178 +
  179 + /// The number of major vertical divisions within each primary grid cell.
  180 + final int verticalDivisions;
  181 +
  182 + /// The number of minor horizontal divisions within each major division, including the
  183 + /// major division itself.
  184 + final int horizontalSubdivisions;
  185 +
  186 + /// The number of minor vertical divisions within each major division, including the
  187 + /// major division itself.
  188 + final int verticalSubdivisions;
  189 +
  190 + /// The margin to apply to the horizontal and vertical lines
  191 + final EdgeInsets margin;
  192 +
  193 + final int horizontalOffset;
  194 +
  195 + final int verticalOffset;
  196 +
  197 + final BoxBorder border;
  198 +
  199 + final double scale;
  200 +
  201 + final double opacity;
  202 +
  203 + @override
  204 + void layout(Context context, BoxConstraints constraints,
  205 + {bool parentUsesSize = false}) {
  206 + box = PdfRect.fromPoints(PdfPoint.zero, constraints.biggest);
  207 + if (child != null) {
  208 + if (constraints.hasBoundedWidth && constraints.hasBoundedHeight) {
  209 + final childConstraints = BoxConstraints(
  210 + maxWidth: constraints.maxWidth - margin.horizontal,
  211 + maxHeight: constraints.maxHeight - margin.vertical,
  212 + );
  213 + child.layout(context, childConstraints, parentUsesSize: false);
  214 + } else {
  215 + child.layout(context, constraints, parentUsesSize: false);
  216 + }
  217 +
  218 + assert(child.box != null);
  219 + child.box = PdfRect.fromPoints(
  220 + PdfPoint(margin.left, box.top - margin.top - child.box.height),
  221 + child.box.size);
  222 + }
  223 + }
  224 +
  225 + @override
  226 + void paint(Context context) {
  227 + super.paint(context);
  228 + paintChild(context);
  229 +
  230 + context.canvas.saveContext();
  231 + context.canvas.setGraphicState(PdfGraphicState(opacity: 0.5));
  232 + context.canvas.setStrokeColor(horizontalColor);
  233 + final l = scale;
  234 + final m = l / 2;
  235 + final s = m / 2;
  236 +
  237 + final allHorizontalDivisions =
  238 + (horizontalDivisions * horizontalSubdivisions).toDouble();
  239 + var n = horizontalOffset;
  240 + for (var x = box.left + margin.left;
  241 + x <= box.right - margin.right;
  242 + x += horizontalInterval / allHorizontalDivisions) {
  243 + context.canvas
  244 + ..setLineWidth((n % (horizontalSubdivisions * horizontalDivisions) == 0)
  245 + ? l
  246 + : (n % horizontalSubdivisions == 0)
  247 + ? m
  248 + : s)
  249 + ..drawLine(x, box.top, x, box.bottom)
  250 + ..strokePath();
  251 + n++;
  252 + }
  253 +
  254 + context.canvas.setStrokeColor(verticalColor);
  255 + final allVerticalDivisions =
  256 + (verticalDivisions * verticalSubdivisions).toDouble();
  257 + n = verticalOffset;
  258 + for (var y = box.top - margin.top;
  259 + y >= box.bottom + margin.bottom;
  260 + y -= verticalInterval / allVerticalDivisions) {
  261 + context.canvas
  262 + ..setLineWidth((n % (verticalSubdivisions * verticalDivisions) == 0)
  263 + ? l
  264 + : (n % verticalSubdivisions == 0)
  265 + ? m
  266 + : s)
  267 + ..drawLine(box.left, y, box.right, y)
  268 + ..strokePath();
  269 + n++;
  270 + }
  271 +
  272 + if (border.left.style != BorderStyle.none) {
  273 + context.canvas
  274 + ..setStrokeColor(border.left.color)
  275 + ..setLineWidth(border.left.width)
  276 + ..drawLine(
  277 + box.left + margin.left, box.top, box.left + margin.left, box.bottom)
  278 + ..strokePath();
  279 + }
  280 + if (border.right.style != BorderStyle.none) {
  281 + context.canvas
  282 + ..setStrokeColor(border.right.color)
  283 + ..setLineWidth(border.right.width)
  284 + ..drawLine(box.right - margin.right, box.top, box.right - margin.right,
  285 + box.bottom)
  286 + ..strokePath();
  287 + }
  288 + if (border.top.style != BorderStyle.none) {
  289 + context.canvas
  290 + ..setStrokeColor(border.top.color)
  291 + ..setLineWidth(border.top.width)
  292 + ..drawLine(
  293 + box.left, box.top - margin.top, box.right, box.top - margin.top)
  294 + ..strokePath();
  295 + }
  296 + if (border.bottom.style != BorderStyle.none) {
  297 + context.canvas
  298 + ..setStrokeColor(border.bottom.color)
  299 + ..setLineWidth(border.bottom.width)
  300 + ..drawLine(box.left, box.bottom + margin.bottom, box.right,
  301 + box.bottom + margin.bottom)
  302 + ..strokePath();
  303 + }
  304 + }
  305 +}