Skip to content

Commit 58db24a

Browse files
SaadArdatiBirjuVachhani
authored andcommitted
Resizing refactor #1
- Fix resizing without overflow.
1 parent 7ae2fa3 commit 58db24a

File tree

14 files changed

+1932
-298
lines changed

14 files changed

+1932
-298
lines changed

packages/box_transform/lib/src/enums.dart

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import 'package:vector_math/vector_math.dart';
2+
3+
import 'geometry.dart';
4+
15
/// Represents a resizing handle on corners.
26
enum HandlePosition {
7+
/// Represents no handle. An empty resize operation.
8+
none,
9+
310
/// Represents the left side of the rect.
411
left,
512

@@ -24,6 +31,9 @@ enum HandlePosition {
2431
/// Represents the bottom right corner of the rect.
2532
bottomRight;
2633

34+
/// Whether the handle is none or not.
35+
bool get isNone => this == HandlePosition.none;
36+
2737
/// Whether the handle is on the left side of the rect.
2838
bool get influencesLeft =>
2939
this == topLeft || this == bottomLeft || this == left;
@@ -87,6 +97,108 @@ enum HandlePosition {
8797
HandlePosition.left,
8898
HandlePosition.right,
8999
];
100+
101+
/// Returns the opposite handle position on the horizontal axis.
102+
HandlePosition flipY() {
103+
switch (this) {
104+
case HandlePosition.top:
105+
return HandlePosition.bottom;
106+
case HandlePosition.bottom:
107+
return HandlePosition.top;
108+
case HandlePosition.topLeft:
109+
return HandlePosition.bottomLeft;
110+
case HandlePosition.topRight:
111+
return HandlePosition.bottomRight;
112+
case HandlePosition.bottomLeft:
113+
return HandlePosition.topLeft;
114+
case HandlePosition.bottomRight:
115+
return HandlePosition.topRight;
116+
default:
117+
return this;
118+
}
119+
}
120+
121+
/// Returns the opposite handle position on the vertical axis.
122+
HandlePosition flipX() {
123+
switch (this) {
124+
case HandlePosition.left:
125+
return HandlePosition.right;
126+
case HandlePosition.right:
127+
return HandlePosition.left;
128+
case HandlePosition.topLeft:
129+
return HandlePosition.topRight;
130+
case HandlePosition.topRight:
131+
return HandlePosition.topLeft;
132+
case HandlePosition.bottomLeft:
133+
return HandlePosition.bottomRight;
134+
case HandlePosition.bottomRight:
135+
return HandlePosition.bottomLeft;
136+
default:
137+
return this;
138+
}
139+
}
140+
141+
/// Returns the opposite handle position on the given [flip] state.
142+
HandlePosition flip(Flip flip) {
143+
switch (flip) {
144+
case Flip.none:
145+
return this;
146+
case Flip.horizontal:
147+
return flipX();
148+
case Flip.vertical:
149+
return flipY();
150+
case Flip.diagonal:
151+
return flipX().flipY();
152+
}
153+
}
154+
155+
/// Gets the opposite handle position.
156+
HandlePosition get opposite {
157+
switch (this) {
158+
case HandlePosition.top:
159+
return HandlePosition.bottom;
160+
case HandlePosition.bottom:
161+
return HandlePosition.top;
162+
case HandlePosition.left:
163+
return HandlePosition.right;
164+
case HandlePosition.right:
165+
return HandlePosition.left;
166+
case HandlePosition.topLeft:
167+
return HandlePosition.bottomRight;
168+
case HandlePosition.topRight:
169+
return HandlePosition.bottomLeft;
170+
case HandlePosition.bottomLeft:
171+
return HandlePosition.topRight;
172+
case HandlePosition.bottomRight:
173+
return HandlePosition.topLeft;
174+
default:
175+
return this;
176+
}
177+
}
178+
179+
/// Gets the anchor point for the handle. Anchor point is the point on the
180+
/// opposite handle.
181+
Vector2 anchor(Box rect) {
182+
switch (this) {
183+
case HandlePosition.topLeft:
184+
return rect.bottomRight;
185+
case HandlePosition.top:
186+
return rect.bottomCenter;
187+
case HandlePosition.topRight:
188+
return rect.bottomLeft;
189+
case HandlePosition.left:
190+
return rect.centerRight;
191+
case HandlePosition.right:
192+
return rect.centerLeft;
193+
case HandlePosition.bottomLeft:
194+
return rect.topRight;
195+
case HandlePosition.bottom:
196+
return rect.topCenter;
197+
case HandlePosition.bottomRight:
198+
case HandlePosition.none:
199+
return rect.topLeft;
200+
}
201+
}
90202
}
91203

92204
/// Represents the flip state of a rectangle, or, in other words, if the

packages/box_transform/lib/src/geometry.dart

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,32 @@ class Box {
420420
math.max(a.y, b.y),
421421
);
422422

423+
/// Construct a rectangle from given handle and its origin.
424+
factory Box.fromHandle(
425+
Vector2 origin, HandlePosition handle, double width, double height) {
426+
switch (handle) {
427+
case HandlePosition.none:
428+
case HandlePosition.topLeft:
429+
return Box.fromLTWH(origin.x - width, origin.y - height, width, height);
430+
case HandlePosition.topRight:
431+
return Box.fromLTWH(origin.x, origin.y - height, width, height);
432+
case HandlePosition.bottomLeft:
433+
return Box.fromLTWH(origin.x - width, origin.y, width, height);
434+
case HandlePosition.bottomRight:
435+
return Box.fromLTWH(origin.x, origin.y, width, height);
436+
case HandlePosition.left:
437+
return Box.fromLTWH(
438+
origin.x - width, origin.y - height / 2, width, height);
439+
case HandlePosition.top:
440+
return Box.fromLTWH(
441+
origin.x - width / 2, origin.y - height, width, height);
442+
case HandlePosition.right:
443+
return Box.fromLTWH(origin.x, origin.y - height / 2, width, height);
444+
case HandlePosition.bottom:
445+
return Box.fromLTWH(origin.x - width / 2, origin.y, width, height);
446+
}
447+
}
448+
423449
/// The Vector2 of the left edge of this rectangle from the x axis.
424450
final double left;
425451

@@ -490,8 +516,12 @@ class Box {
490516
/// To translate a rectangle by an [Vector2] rather than by separate x and y
491517
/// components, consider [shift].
492518
Box translate(double translateX, double translateY) {
493-
return Box.fromLTRB(left + translateX, top + translateY, right + translateX,
494-
bottom + translateY);
519+
return Box.fromLTRB(
520+
left + translateX,
521+
top + translateY,
522+
right + translateX,
523+
bottom + translateY,
524+
);
495525
}
496526

497527
/// Returns a new rectangle with edges moved outwards by the given delta.
@@ -624,20 +654,55 @@ class Box {
624654
);
625655
}
626656

657+
/// Whether this box is overflowing the given [child] box. Returns true if
658+
/// any of the child's edges are outside of this box.
659+
bool isOverflowing(Box child) {
660+
return child.left < left ||
661+
child.top < top ||
662+
child.right > right ||
663+
child.bottom > bottom ||
664+
child.width > width ||
665+
child.height > height;
666+
}
667+
627668
/// Constrains the given [child] box instance within the bounds of this box.
628669
/// This function will preserve the sign of the child's width and height.
629670
/// It will also maintain the aspect ratio of the child if the [aspectRatio]
630671
/// is specified.
631672
///
632673
/// [child] the child box to clamp inside this box.
674+
///
633675
/// [resizeMode] defines how to contain the child, whether it should keep its
634676
/// aspect ratio or not, or if it should be resized to fit.
635677
///
678+
/// [allowResizeOverflow] decides whether to allow the box to overflow the
679+
/// resize operation to its opposite side to continue the resize operation
680+
/// until its constrained on both sides.
681+
///
682+
/// If this is set to false, the box will cease the resize operation the
683+
/// instant it hits an edge of the [clampingRect].
684+
///
685+
/// If this is set to true, the box will continue the resize operation until
686+
/// it is constrained to both sides of the [clampingRect].
687+
///
688+
/// [handle] defines the handle that is being dragged to resize the box if
689+
/// available. This only matters if [allowResizeOverflow] is set to false.
690+
///
691+
/// [currentFlip] defines the current flip of the box if available.
692+
///
693+
/// [aspectRatio] will allow the box to maintain its aspect ratio if
694+
/// it overflows outside its clamping box and needs to be re-adjusted to
695+
/// fit back inside. This will ensure that the correction operation will
696+
/// maintain the aspect ratio of the box.
697+
///
636698
/// [returns] a new box instance.
637699
Box containOther(
638700
Box child, {
639701
ResizeMode resizeMode = ResizeMode.freeform,
702+
HandlePosition handle = HandlePosition.none,
703+
Flip currentFlip = Flip.none,
640704
double? aspectRatio,
705+
bool allowResizeOverflow = true,
641706
}) {
642707
final double xSign = child.width.sign;
643708
final double ySign = child.height.sign;

0 commit comments

Comments
 (0)