Skip to content

Commit 1336e4d

Browse files
committed
♻️ Unified clamping box for playground.
1 parent 37a581c commit 1336e4d

File tree

1 file changed

+62
-81
lines changed
  • packages/flutter_box_transform/example/lib

1 file changed

+62
-81
lines changed

packages/flutter_box_transform/example/lib/main.dart

Lines changed: 62 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class MyApp extends StatelessWidget {
6363
}
6464

6565
class 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

Comments
 (0)