David PHAM-VAN

Add Transform.rotateBox constructor

@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 4
5 * Add better debugPaint on Align Widget 5 * Add better debugPaint on Align Widget
6 * Fix Transform placement when Alignment and Origin are Null 6 * Fix Transform placement when Alignment and Origin are Null
  7 +* Add Transform.rotateBox constructor
7 8
8 ## 1.3.15 9 ## 1.3.15
9 10
@@ -128,6 +128,7 @@ class Transform extends SingleChildWidget { @@ -128,6 +128,7 @@ class Transform extends SingleChildWidget {
128 this.alignment, 128 this.alignment,
129 Widget child, 129 Widget child,
130 }) : assert(transform != null), 130 }) : assert(transform != null),
  131 + _relayout = false,
131 super(child: child); 132 super(child: child);
132 133
133 /// Creates a widget that transforms its child using a rotation around the 134 /// Creates a widget that transforms its child using a rotation around the
@@ -138,6 +139,18 @@ class Transform extends SingleChildWidget { @@ -138,6 +139,18 @@ class Transform extends SingleChildWidget {
138 this.alignment = Alignment.center, 139 this.alignment = Alignment.center,
139 Widget child, 140 Widget child,
140 }) : transform = Matrix4.rotationZ(angle), 141 }) : transform = Matrix4.rotationZ(angle),
  142 + _relayout = false,
  143 + super(child: child);
  144 +
  145 + /// Creates a widget that transforms its child using a rotation around the
  146 + /// center and relayout the bounding box.
  147 + Transform.rotateBox({
  148 + @required double angle,
  149 + Widget child,
  150 + }) : transform = Matrix4.rotationZ(angle),
  151 + _relayout = true,
  152 + alignment = null,
  153 + origin = null,
141 super(child: child); 154 super(child: child);
142 155
143 /// Creates a widget that transforms its child using a translation. 156 /// Creates a widget that transforms its child using a translation.
@@ -147,6 +160,7 @@ class Transform extends SingleChildWidget { @@ -147,6 +160,7 @@ class Transform extends SingleChildWidget {
147 }) : transform = Matrix4.translationValues(offset.x, offset.y, 0), 160 }) : transform = Matrix4.translationValues(offset.x, offset.y, 0),
148 origin = null, 161 origin = null,
149 alignment = null, 162 alignment = null,
  163 + _relayout = false,
150 super(child: child); 164 super(child: child);
151 165
152 /// Creates a widget that scales its child uniformly. 166 /// Creates a widget that scales its child uniformly.
@@ -156,6 +170,7 @@ class Transform extends SingleChildWidget { @@ -156,6 +170,7 @@ class Transform extends SingleChildWidget {
156 this.alignment = Alignment.center, 170 this.alignment = Alignment.center,
157 Widget child, 171 Widget child,
158 }) : transform = Matrix4.diagonal3Values(scale, scale, 1), 172 }) : transform = Matrix4.diagonal3Values(scale, scale, 1),
  173 + _relayout = false,
159 super(child: child); 174 super(child: child);
160 175
161 /// The matrix to transform the child by during painting. 176 /// The matrix to transform the child by during painting.
@@ -167,6 +182,8 @@ class Transform extends SingleChildWidget { @@ -167,6 +182,8 @@ class Transform extends SingleChildWidget {
167 /// The alignment of the origin, relative to the size of the box. 182 /// The alignment of the origin, relative to the size of the box.
168 final Alignment alignment; 183 final Alignment alignment;
169 184
  185 + final bool _relayout;
  186 +
170 Matrix4 get _effectiveTransform { 187 Matrix4 get _effectiveTransform {
171 final Matrix4 result = Matrix4.identity(); 188 final Matrix4 result = Matrix4.identity();
172 if (origin != null) { 189 if (origin != null) {
@@ -189,6 +206,50 @@ class Transform extends SingleChildWidget { @@ -189,6 +206,50 @@ class Transform extends SingleChildWidget {
189 } 206 }
190 207
191 @override 208 @override
  209 + void layout(Context context, BoxConstraints constraints,
  210 + {bool parentUsesSize = false}) {
  211 + if (!_relayout) {
  212 + return super.layout(context, constraints, parentUsesSize: parentUsesSize);
  213 + }
  214 +
  215 + if (child != null) {
  216 + child.layout(context, constraints, parentUsesSize: parentUsesSize);
  217 + assert(child.box != null);
  218 + box = child.box;
  219 +
  220 + final Matrix4 mat = transform;
  221 + final List<double> values = mat.applyToVector3Array(<double>[
  222 + child.box.left,
  223 + child.box.top,
  224 + 0,
  225 + child.box.right,
  226 + child.box.top,
  227 + 0,
  228 + child.box.right,
  229 + child.box.bottom,
  230 + 0,
  231 + child.box.left,
  232 + child.box.bottom,
  233 + 0,
  234 + ]);
  235 +
  236 + box = PdfRect.fromLTRB(
  237 + math.min(
  238 + math.min(math.min(values[0], values[3]), values[6]), values[9]),
  239 + math.min(
  240 + math.min(math.min(values[1], values[4]), values[7]), values[10]),
  241 + math.max(
  242 + math.max(math.max(values[0], values[3]), values[6]), values[9]),
  243 + math.max(
  244 + math.max(math.max(values[1], values[4]), values[7]), values[10]),
  245 + );
  246 + transform.leftTranslate(-box.x, -box.y);
  247 + } else {
  248 + box = PdfRect.fromPoints(PdfPoint.zero, constraints.smallest);
  249 + }
  250 + }
  251 +
  252 + @override
192 void paint(Context context) { 253 void paint(Context context) {
193 super.paint(context); 254 super.paint(context);
194 255
@@ -191,6 +191,16 @@ void main() { @@ -191,6 +191,16 @@ void main() {
191 ))); 191 )));
192 }); 192 });
193 193
  194 + test('Basic Widgets Transform rotateBox', () {
  195 + pdf.addPage(Page(
  196 + build: (Context context) => Center(
  197 + child: Transform.rotateBox(
  198 + angle: 3.1416 / 2,
  199 + child: Text('Hello'),
  200 + ),
  201 + )));
  202 + });
  203 +
194 tearDownAll(() { 204 tearDownAll(() {
195 final File file = File('widgets-basic.pdf'); 205 final File file = File('widgets-basic.pdf');
196 file.writeAsBytesSync(pdf.save()); 206 file.writeAsBytesSync(pdf.save());