@@ -63,6 +63,9 @@ class MyApp extends StatelessWidget {
6363}
6464
6565class PlaygroundModel with ChangeNotifier {
66+ Rect clampingRect = Rect .largest;
67+ bool clampingEnabled = false ;
68+
6669 Rect ? playgroundArea;
6770
6871 final List <BoxData > boxes = [];
@@ -77,6 +80,13 @@ class PlaygroundModel with ChangeNotifier {
7780 final double width = size.width - kSidePanelWidth - kBoxesPanelWidth;
7881 final double height = size.height;
7982
83+ clampingRect = Rect .fromLTWH (
84+ 0 ,
85+ 0 ,
86+ width,
87+ size.height,
88+ );
89+
8090 boxes.clear ();
8191 boxes.add (
8292 BoxData (
@@ -88,12 +98,6 @@ class PlaygroundModel with ChangeNotifier {
8898 kInitialWidth,
8999 kInitialHeight,
90100 ),
91- clampingRect: Rect .fromLTWH (
92- 0 ,
93- 0 ,
94- width,
95- size.height,
96- ),
97101 flip: Flip .none,
98102 ),
99103 );
@@ -134,25 +138,21 @@ class PlaygroundModel with ChangeNotifier {
134138 bool notify = true ,
135139 bool insidePlayground = false ,
136140 }) {
137- if (selectedBox == null ) return ;
138- selectedBox! .clampingRect = rect;
141+ clampingRect = rect;
139142
140143 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),
146149 );
147150 }
148151
149152 if (notify) notifyListeners ();
150153 }
151154
152155 void addNewBox () {
153- final double width = playgroundArea! .width;
154- final double height = playgroundArea! .height;
155-
156156 boxes.add (
157157 BoxData (
158158 name: 'Box ${boxes .length + 1 }' ,
@@ -163,7 +163,6 @@ class PlaygroundModel with ChangeNotifier {
163163 kInitialWidth,
164164 kInitialHeight,
165165 ),
166- clampingRect: Rect .fromLTWH (0 , 0 , width, height),
167166 flip: Flip .none,
168167 ),
169168 );
@@ -213,8 +212,7 @@ class PlaygroundModel with ChangeNotifier {
213212 }
214213
215214 void toggleClamping (bool enabled) {
216- if (selectedBoxIndex == - 1 ) return ;
217- selectedBox! .clampingEnabled = enabled;
215+ clampingEnabled = enabled;
218216 notifyListeners ();
219217 }
220218
@@ -249,11 +247,11 @@ class PlaygroundModel with ChangeNotifier {
249247 double ? bottom,
250248 }) {
251249 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,
257255 );
258256 notifyListeners ();
259257 }
@@ -381,24 +379,13 @@ class _PlaygroundState extends State<Playground> with WidgetsBindingObserver {
381379
382380 final Rect playgroundArea = model.playgroundArea! ;
383381
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+ );
402389 }
403390 }
404391
@@ -445,9 +432,7 @@ class _PlaygroundState extends State<Playground> with WidgetsBindingObserver {
445432 : kGridColor.withOpacity (0.1 ),
446433 ),
447434 ),
448- if (model.selectedBox != null &&
449- model.selectedBox! .clampingEnabled &&
450- model.playgroundArea != null )
435+ if (model.clampingEnabled && model.playgroundArea != null )
451436 const ClampingRect (),
452437 for (int index = 0 ; index < model.boxes.length; index++ )
453438 ImageBox (
@@ -506,13 +491,13 @@ class _ImageBoxState extends State<ImageBox> {
506491
507492 @override
508493 Widget build (BuildContext context) {
509- // final PlaygroundModel model = context.watch <PlaygroundModel>();
494+ final PlaygroundModel model = context.read <PlaygroundModel >();
510495 final Color handleColor = Theme .of (context).colorScheme.primary;
511496 return TransformableBox (
512497 key: ValueKey ('image-box-${box .name }' ),
513498 rect: box.rect,
514499 flip: box.flip,
515- clampingRect: box .clampingEnabled ? box .clampingRect : null ,
500+ clampingRect: model .clampingEnabled ? model .clampingRect : null ,
516501 constraints: box.constraintsEnabled ? box.constraints : null ,
517502 onChanged: widget.onChanged,
518503 resizable: widget.selected && box.resizable,
@@ -647,16 +632,19 @@ class _ClampingRectState extends State<ClampingRect> {
647632 label = 'Clamping Box' ;
648633 }
649634
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));
651639
652640 return TransformableBox (
653- key: ValueKey ('clamping-box-${ box . name } ' ),
654- rect: box .clampingRect,
641+ key: const ValueKey ('clamping-box' ),
642+ rect: model .clampingRect,
655643 flip: Flip .none,
656644 clampingRect: model.playgroundArea! ,
657645 constraints: BoxConstraints (
658- minWidth: box.rect.width ,
659- minHeight: box.rect.height ,
646+ minWidth: minWidth ,
647+ minHeight: minHeight ,
660648 ),
661649 onChanged: (result) => model.setClampingRect (result.rect),
662650 onTerminalSizeReached: (
@@ -691,8 +679,8 @@ class _ClampingRectState extends State<ClampingRect> {
691679 handleAlign: HandleAlign .inside,
692680 ),
693681 contentBuilder: (context, _, flip) => Container (
694- width: box .clampingRect.width,
695- height: box .clampingRect.height,
682+ width: model .clampingRect.width,
683+ height: model .clampingRect.height,
696684 alignment: Alignment .bottomRight,
697685 decoration: BoxDecoration (
698686 border: Border .symmetric (
@@ -1299,39 +1287,36 @@ class _ClampingControlsState extends State<ClampingControls> {
12991287 void initState () {
13001288 super .initState ();
13011289 leftController =
1302- TextEditingController (text: box .clampingRect.left.toStringAsFixed (0 ));
1290+ TextEditingController (text: model .clampingRect.left.toStringAsFixed (0 ));
13031291 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 ));
13091297
13101298 model.addListener (onModelChanged);
13111299 }
13121300
13131301 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 );
13171304 }
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 );
13201307 }
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 );
13231310 }
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 );
13261313 }
13271314 }
13281315
13291316 @override
13301317 Widget build (BuildContext context) {
13311318 final PlaygroundModel model = context.watch <PlaygroundModel >();
13321319
1333- final BoxData box = model.selectedBox! ;
1334-
13351320 return FocusScope (
13361321 child: Builder (
13371322 builder: (context) {
@@ -1376,15 +1361,15 @@ class _ClampingControlsState extends State<ClampingControls> {
13761361 child: Transform .scale (
13771362 scale: 0.7 ,
13781363 child: Switch (
1379- value: box .clampingEnabled,
1364+ value: model .clampingEnabled,
13801365 onChanged: (value) => model.toggleClamping (value),
13811366 ),
13821367 ),
13831368 ),
13841369 ],
13851370 ),
13861371 ),
1387- if (box .clampingEnabled)
1372+ if (model .clampingEnabled)
13881373 Padding (
13891374 padding: const EdgeInsets .fromLTRB (16 , 0 , 16 , 16 ),
13901375 child: Column (
@@ -1403,7 +1388,7 @@ class _ClampingControlsState extends State<ClampingControls> {
14031388 children: [
14041389 Expanded (
14051390 child: TextField (
1406- enabled: box .clampingEnabled,
1391+ enabled: model .clampingEnabled,
14071392 controller: leftController,
14081393 onSubmitted: (value) {
14091394 model.onClampingRectChanged (left: left);
@@ -1421,7 +1406,7 @@ class _ClampingControlsState extends State<ClampingControls> {
14211406 const SizedBox (width: 16 ),
14221407 Expanded (
14231408 child: TextField (
1424- enabled: box .clampingEnabled,
1409+ enabled: model .clampingEnabled,
14251410 controller: topController,
14261411 onSubmitted: (value) {
14271412 model.onClampingRectChanged (top: top);
@@ -1451,7 +1436,7 @@ class _ClampingControlsState extends State<ClampingControls> {
14511436 children: [
14521437 Expanded (
14531438 child: TextFormField (
1454- enabled: box .clampingEnabled,
1439+ enabled: model .clampingEnabled,
14551440 controller: rightController,
14561441 onFieldSubmitted: (value) {
14571442 model.onClampingRectChanged (right: right);
@@ -1469,7 +1454,7 @@ class _ClampingControlsState extends State<ClampingControls> {
14691454 const SizedBox (width: 16 ),
14701455 Expanded (
14711456 child: TextField (
1472- enabled: box .clampingEnabled,
1457+ enabled: model .clampingEnabled,
14731458 controller: bottomController,
14741459 onSubmitted: (value) {
14751460 model.onClampingRectChanged (bottom: bottom);
@@ -1919,12 +1904,10 @@ class BoxData {
19191904 Flip flip = Flip .none;
19201905 Rect rect2 = Rect .zero;
19211906 Flip flip2 = Flip .none;
1922- Rect clampingRect = Rect .largest;
19231907 BoxConstraints constraints;
19241908
19251909 bool flipRectWhileResizing = true ;
19261910 bool flipChild = true ;
1927- bool clampingEnabled = false ;
19281911 bool constraintsEnabled = false ;
19291912 bool resizable = true ;
19301913 bool movable = true ;
@@ -1939,11 +1922,9 @@ class BoxData {
19391922 this .flip = Flip .none,
19401923 this .rect2 = Rect .zero,
19411924 this .flip2 = Flip .none,
1942- this .clampingRect = Rect .largest,
19431925 this .constraints = const BoxConstraints (minWidth: 0 , minHeight: 0 ),
19441926 this .flipRectWhileResizing = true ,
19451927 this .flipChild = true ,
1946- this .clampingEnabled = false ,
19471928 this .constraintsEnabled = false ,
19481929 this .resizable = true ,
19491930 this .movable = true ,
0 commit comments