@@ -63,6 +63,9 @@ class MyApp extends StatelessWidget {
63
63
}
64
64
65
65
class PlaygroundModel with ChangeNotifier {
66
+ Rect clampingRect = Rect .largest;
67
+ bool clampingEnabled = false ;
68
+
66
69
Rect ? playgroundArea;
67
70
68
71
final List <BoxData > boxes = [];
@@ -77,6 +80,13 @@ class PlaygroundModel with ChangeNotifier {
77
80
final double width = size.width - kSidePanelWidth - kBoxesPanelWidth;
78
81
final double height = size.height;
79
82
83
+ clampingRect = Rect .fromLTWH (
84
+ 0 ,
85
+ 0 ,
86
+ width,
87
+ size.height,
88
+ );
89
+
80
90
boxes.clear ();
81
91
boxes.add (
82
92
BoxData (
@@ -88,12 +98,6 @@ class PlaygroundModel with ChangeNotifier {
88
98
kInitialWidth,
89
99
kInitialHeight,
90
100
),
91
- clampingRect: Rect .fromLTWH (
92
- 0 ,
93
- 0 ,
94
- width,
95
- size.height,
96
- ),
97
101
flip: Flip .none,
98
102
),
99
103
);
@@ -134,25 +138,21 @@ class PlaygroundModel with ChangeNotifier {
134
138
bool notify = true ,
135
139
bool insidePlayground = false ,
136
140
}) {
137
- if (selectedBox == null ) return ;
138
- selectedBox! .clampingRect = rect;
141
+ clampingRect = rect;
139
142
140
143
if (insidePlayground && playgroundArea != null ) {
141
- selectedBox ! . clampingRect = Rect .fromLTWH (
142
- selectedBox ! . clampingRect.left.clamp (0.0 , playgroundArea! .width),
143
- selectedBox ! . clampingRect.top.clamp (0.0 , playgroundArea! .height),
144
- selectedBox ! . clampingRect.width.clamp (0.0 , playgroundArea! .width),
145
- selectedBox ! . clampingRect.height.clamp (0.0 , playgroundArea! .height),
144
+ clampingRect = Rect .fromLTWH (
145
+ clampingRect.left.clamp (0.0 , playgroundArea! .width),
146
+ clampingRect.top.clamp (0.0 , playgroundArea! .height),
147
+ clampingRect.width.clamp (0.0 , playgroundArea! .width),
148
+ clampingRect.height.clamp (0.0 , playgroundArea! .height),
146
149
);
147
150
}
148
151
149
152
if (notify) notifyListeners ();
150
153
}
151
154
152
155
void addNewBox () {
153
- final double width = playgroundArea! .width;
154
- final double height = playgroundArea! .height;
155
-
156
156
boxes.add (
157
157
BoxData (
158
158
name: 'Box ${boxes .length + 1 }' ,
@@ -163,7 +163,6 @@ class PlaygroundModel with ChangeNotifier {
163
163
kInitialWidth,
164
164
kInitialHeight,
165
165
),
166
- clampingRect: Rect .fromLTWH (0 , 0 , width, height),
167
166
flip: Flip .none,
168
167
),
169
168
);
@@ -213,8 +212,7 @@ class PlaygroundModel with ChangeNotifier {
213
212
}
214
213
215
214
void toggleClamping (bool enabled) {
216
- if (selectedBoxIndex == - 1 ) return ;
217
- selectedBox! .clampingEnabled = enabled;
215
+ clampingEnabled = enabled;
218
216
notifyListeners ();
219
217
}
220
218
@@ -249,11 +247,11 @@ class PlaygroundModel with ChangeNotifier {
249
247
double ? bottom,
250
248
}) {
251
249
if (selectedBox == null ) return ;
252
- selectedBox ! . clampingRect = Rect .fromLTRB (
253
- left ?? selectedBox ! . clampingRect.left,
254
- top ?? selectedBox ! . clampingRect.top,
255
- right ?? selectedBox ! . clampingRect.right,
256
- bottom ?? selectedBox ! . clampingRect.bottom,
250
+ clampingRect = Rect .fromLTRB (
251
+ left ?? clampingRect.left,
252
+ top ?? clampingRect.top,
253
+ right ?? clampingRect.right,
254
+ bottom ?? clampingRect.bottom,
257
255
);
258
256
notifyListeners ();
259
257
}
@@ -381,24 +379,13 @@ class _PlaygroundState extends State<Playground> with WidgetsBindingObserver {
381
379
382
380
final Rect playgroundArea = model.playgroundArea! ;
383
381
384
- for (final box in model.boxes) {
385
- if (box.clampingRect.width > playgroundArea.width ||
386
- box.clampingRect.height > playgroundArea.height) {
387
- if (model.selectedBox? .name == box.name) {
388
- model.setClampingRect (
389
- box.clampingRect,
390
- notify: notify,
391
- insidePlayground: true ,
392
- );
393
- } else {
394
- box.clampingRect = Rect .fromLTWH (
395
- box.clampingRect.left.clamp (0.0 , playgroundArea.width),
396
- box.clampingRect.top.clamp (0.0 , playgroundArea.height),
397
- box.clampingRect.width.clamp (0.0 , playgroundArea.width),
398
- box.clampingRect.height.clamp (0.0 , playgroundArea.height),
399
- );
400
- }
401
- }
382
+ if (model.clampingRect.width > playgroundArea.width ||
383
+ model.clampingRect.height > playgroundArea.height) {
384
+ model.setClampingRect (
385
+ model.clampingRect,
386
+ notify: notify,
387
+ insidePlayground: true ,
388
+ );
402
389
}
403
390
}
404
391
@@ -445,9 +432,7 @@ class _PlaygroundState extends State<Playground> with WidgetsBindingObserver {
445
432
: kGridColor.withOpacity (0.1 ),
446
433
),
447
434
),
448
- if (model.selectedBox != null &&
449
- model.selectedBox! .clampingEnabled &&
450
- model.playgroundArea != null )
435
+ if (model.clampingEnabled && model.playgroundArea != null )
451
436
const ClampingRect (),
452
437
for (int index = 0 ; index < model.boxes.length; index++ )
453
438
ImageBox (
@@ -506,13 +491,13 @@ class _ImageBoxState extends State<ImageBox> {
506
491
507
492
@override
508
493
Widget build (BuildContext context) {
509
- // final PlaygroundModel model = context.watch <PlaygroundModel>();
494
+ final PlaygroundModel model = context.read <PlaygroundModel >();
510
495
final Color handleColor = Theme .of (context).colorScheme.primary;
511
496
return TransformableBox (
512
497
key: ValueKey ('image-box-${box .name }' ),
513
498
rect: box.rect,
514
499
flip: box.flip,
515
- clampingRect: box .clampingEnabled ? box .clampingRect : null ,
500
+ clampingRect: model .clampingEnabled ? model .clampingRect : null ,
516
501
constraints: box.constraintsEnabled ? box.constraints : null ,
517
502
onChanged: widget.onChanged,
518
503
resizable: widget.selected && box.resizable,
@@ -647,16 +632,19 @@ class _ClampingRectState extends State<ClampingRect> {
647
632
label = 'Clamping Box' ;
648
633
}
649
634
650
- final BoxData box = model.selectedBox! ;
635
+ final minWidth = model.boxes.fold (0.0 ,
636
+ (previousValue, element) => max (previousValue, element.rect.width));
637
+ final minHeight = model.boxes.fold (0.0 ,
638
+ (previousValue, element) => max (previousValue, element.rect.height));
651
639
652
640
return TransformableBox (
653
- key: ValueKey ('clamping-box-${ box . name } ' ),
654
- rect: box .clampingRect,
641
+ key: const ValueKey ('clamping-box' ),
642
+ rect: model .clampingRect,
655
643
flip: Flip .none,
656
644
clampingRect: model.playgroundArea! ,
657
645
constraints: BoxConstraints (
658
- minWidth: box.rect.width ,
659
- minHeight: box.rect.height ,
646
+ minWidth: minWidth ,
647
+ minHeight: minHeight ,
660
648
),
661
649
onChanged: (result) => model.setClampingRect (result.rect),
662
650
onTerminalSizeReached: (
@@ -691,8 +679,8 @@ class _ClampingRectState extends State<ClampingRect> {
691
679
handleAlign: HandleAlign .inside,
692
680
),
693
681
contentBuilder: (context, _, flip) => Container (
694
- width: box .clampingRect.width,
695
- height: box .clampingRect.height,
682
+ width: model .clampingRect.width,
683
+ height: model .clampingRect.height,
696
684
alignment: Alignment .bottomRight,
697
685
decoration: BoxDecoration (
698
686
border: Border .symmetric (
@@ -1299,39 +1287,36 @@ class _ClampingControlsState extends State<ClampingControls> {
1299
1287
void initState () {
1300
1288
super .initState ();
1301
1289
leftController =
1302
- TextEditingController (text: box .clampingRect.left.toStringAsFixed (0 ));
1290
+ TextEditingController (text: model .clampingRect.left.toStringAsFixed (0 ));
1303
1291
topController =
1304
- TextEditingController (text: box .clampingRect.top.toStringAsFixed (0 ));
1305
- bottomController =
1306
- TextEditingController ( text: box .clampingRect.bottom.toStringAsFixed (0 ));
1307
- rightController =
1308
- TextEditingController ( text: box .clampingRect.right.toStringAsFixed (0 ));
1292
+ TextEditingController (text: model .clampingRect.top.toStringAsFixed (0 ));
1293
+ bottomController = TextEditingController (
1294
+ text: model .clampingRect.bottom.toStringAsFixed (0 ));
1295
+ rightController = TextEditingController (
1296
+ text: model .clampingRect.right.toStringAsFixed (0 ));
1309
1297
1310
1298
model.addListener (onModelChanged);
1311
1299
}
1312
1300
1313
1301
void onModelChanged () {
1314
- if (model.selectedBox == null ) return ;
1315
- if (box.clampingRect.left != left) {
1316
- leftController.text = box.clampingRect.left.toStringAsFixed (0 );
1302
+ if (model.clampingRect.left != left) {
1303
+ leftController.text = model.clampingRect.left.toStringAsFixed (0 );
1317
1304
}
1318
- if (box .clampingRect.top != top) {
1319
- topController.text = box .clampingRect.top.toStringAsFixed (0 );
1305
+ if (model .clampingRect.top != top) {
1306
+ topController.text = model .clampingRect.top.toStringAsFixed (0 );
1320
1307
}
1321
- if (box .clampingRect.bottom != bottom) {
1322
- bottomController.text = box .clampingRect.bottom.toStringAsFixed (0 );
1308
+ if (model .clampingRect.bottom != bottom) {
1309
+ bottomController.text = model .clampingRect.bottom.toStringAsFixed (0 );
1323
1310
}
1324
- if (box .clampingRect.right != right) {
1325
- rightController.text = box .clampingRect.right.toStringAsFixed (0 );
1311
+ if (model .clampingRect.right != right) {
1312
+ rightController.text = model .clampingRect.right.toStringAsFixed (0 );
1326
1313
}
1327
1314
}
1328
1315
1329
1316
@override
1330
1317
Widget build (BuildContext context) {
1331
1318
final PlaygroundModel model = context.watch <PlaygroundModel >();
1332
1319
1333
- final BoxData box = model.selectedBox! ;
1334
-
1335
1320
return FocusScope (
1336
1321
child: Builder (
1337
1322
builder: (context) {
@@ -1376,15 +1361,15 @@ class _ClampingControlsState extends State<ClampingControls> {
1376
1361
child: Transform .scale (
1377
1362
scale: 0.7 ,
1378
1363
child: Switch (
1379
- value: box .clampingEnabled,
1364
+ value: model .clampingEnabled,
1380
1365
onChanged: (value) => model.toggleClamping (value),
1381
1366
),
1382
1367
),
1383
1368
),
1384
1369
],
1385
1370
),
1386
1371
),
1387
- if (box .clampingEnabled)
1372
+ if (model .clampingEnabled)
1388
1373
Padding (
1389
1374
padding: const EdgeInsets .fromLTRB (16 , 0 , 16 , 16 ),
1390
1375
child: Column (
@@ -1403,7 +1388,7 @@ class _ClampingControlsState extends State<ClampingControls> {
1403
1388
children: [
1404
1389
Expanded (
1405
1390
child: TextField (
1406
- enabled: box .clampingEnabled,
1391
+ enabled: model .clampingEnabled,
1407
1392
controller: leftController,
1408
1393
onSubmitted: (value) {
1409
1394
model.onClampingRectChanged (left: left);
@@ -1421,7 +1406,7 @@ class _ClampingControlsState extends State<ClampingControls> {
1421
1406
const SizedBox (width: 16 ),
1422
1407
Expanded (
1423
1408
child: TextField (
1424
- enabled: box .clampingEnabled,
1409
+ enabled: model .clampingEnabled,
1425
1410
controller: topController,
1426
1411
onSubmitted: (value) {
1427
1412
model.onClampingRectChanged (top: top);
@@ -1451,7 +1436,7 @@ class _ClampingControlsState extends State<ClampingControls> {
1451
1436
children: [
1452
1437
Expanded (
1453
1438
child: TextFormField (
1454
- enabled: box .clampingEnabled,
1439
+ enabled: model .clampingEnabled,
1455
1440
controller: rightController,
1456
1441
onFieldSubmitted: (value) {
1457
1442
model.onClampingRectChanged (right: right);
@@ -1469,7 +1454,7 @@ class _ClampingControlsState extends State<ClampingControls> {
1469
1454
const SizedBox (width: 16 ),
1470
1455
Expanded (
1471
1456
child: TextField (
1472
- enabled: box .clampingEnabled,
1457
+ enabled: model .clampingEnabled,
1473
1458
controller: bottomController,
1474
1459
onSubmitted: (value) {
1475
1460
model.onClampingRectChanged (bottom: bottom);
@@ -1919,12 +1904,10 @@ class BoxData {
1919
1904
Flip flip = Flip .none;
1920
1905
Rect rect2 = Rect .zero;
1921
1906
Flip flip2 = Flip .none;
1922
- Rect clampingRect = Rect .largest;
1923
1907
BoxConstraints constraints;
1924
1908
1925
1909
bool flipRectWhileResizing = true ;
1926
1910
bool flipChild = true ;
1927
- bool clampingEnabled = false ;
1928
1911
bool constraintsEnabled = false ;
1929
1912
bool resizable = true ;
1930
1913
bool movable = true ;
@@ -1939,11 +1922,9 @@ class BoxData {
1939
1922
this .flip = Flip .none,
1940
1923
this .rect2 = Rect .zero,
1941
1924
this .flip2 = Flip .none,
1942
- this .clampingRect = Rect .largest,
1943
1925
this .constraints = const BoxConstraints (minWidth: 0 , minHeight: 0 ),
1944
1926
this .flipRectWhileResizing = true ,
1945
1927
this .flipChild = true ,
1946
- this .clampingEnabled = false ,
1947
1928
this .constraintsEnabled = false ,
1948
1929
this .resizable = true ,
1949
1930
this .movable = true ,
0 commit comments