All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.
Packages with breaking changes:
box_transform-Unreleased: the defaultbindingStrategyonBoxTransformer.move/resize/rotateflips fromoriginalBoxtoboundingBox. The old behavior is preserved for callers that pass the strategy explicitly. The list-based LP inspection API (LinearInequality,ProjectionResult,buildCornerInequalities,buildCenterInequalities,projectOntoFeasibleRegion) is removed; production callers go through the flat-buffer hot path (IneqBuffer+*Intobuilders +projectOntoFeasibleRegionFlat), and tests use a private test helper attest/lp_inspect.dart.flutter_box_transform-Unreleased: the defaultbindingStrategyonTransformableBox,TransformableBoxController, andUIBoxTransform.*flips fromoriginalBoxtoboundingBox. Existing apps will see a behavior change at non-zero rotation: the rendered footprint is now the containment surface, not the unrotated logical rect. Top-level rotated-layout helpers (rotateOffsetAround,handleCornerInParent,rotatedCornerInWorld,anchorInHandle,handleTopLeftInWorld,sideHandleRectInWorld,computeEffectiveContainmentRect) are relocated as static methods onRotatedLayout; the file-private default handle builders are promoted toHandleBuilders.defaultCorner/HandleBuilders.defaultSide. The top-leveldefaultResizeModeResolver()is relocated toTransformableBoxController.defaultResizeModeResolver().
Packages with other changes:
- Add first-class rotation support around a box's center via
Box.rotationand a newBoxTransformer.rotate(...)entry point. - Add
BindingStrategyenum:originalBoxkeeps the unrotated logical rect inside the clamp;boundingBoxkeeps the rendered rotated polygon (and therefore its axis-aligned bounding box) fully inside. - [BREAKING] Default
bindingStrategyflipped fromoriginalBoxtoboundingBoxonBoxTransformer.move/resize/rotate. PassBindingStrategy.originalBoxexplicitly to restore the previous behavior. BoxTransformer.move(),.resize(),.rotate()are all rotation-aware. Freeform, scale, symmetric, symmetricScale, side-handle, and force-flip resize paths each honor rotation under both binding strategies.- Rotation gestures slide-then-freeze: when the requested angle would push the rect outside the clamp, the engine first tries to translate into available slack; if no translation rescues it, the rotation caps at the last feasible angle.
- Force-flip on a rotated rect falls back to natural direction when the flipped state can't fit clamp + constraints. The rect tracks the cursor by clamp-pinning at the natural wall instead of leaking the clamp or freezing.
- Add
feasiblefield toRotateResultandResizeResult.falsemeans the engine could not honor the requested target without leaking; consumers (controllers) use it to hold the last feasible state. - Solver: dedicated rotated-clamping LP with corner-, side-, and center-anchored inequality builders, an L2 projector with 1D fallback at saturation, and a unified violator-priority loop.
FlatProjectionnow exposesfeasible+worstResidual. - Tests: extensive rotated-resize, rotated-move, rotated-flip, side-handle, scale, symmetric, symmetricScale, and clamp-invariant coverage. New
clamp_invariants_test.dartasserts engine invariants (clamp containment, side-handle scope, constraint compliance) on recorded playground scenarios.
- [BREAKING] Top-level rotated-layout helpers are now static methods on
RotatedLayout(rotateOffsetAround,handleCornerInParent,rotatedCornerInWorld,anchorInHandle,handleTopLeftInWorld,sideHandleRectInWorld, andcomputeEffectiveContainmentRect). The previous top-level forms are removed. - [BREAKING] Default handle builders moved from file-private functions to public statics on
HandleBuilders(HandleBuilders.defaultCorner,HandleBuilders.defaultSide). - Add
rotation,rotatable, andbindingStrategyparameters onTransformableBox. - [BREAKING] Default
bindingStrategyflipped fromoriginalBoxtoboundingBoxonTransformableBox,TransformableBoxController, andUIBoxTransform.move/resize/rotate. Existing apps that relied on the unrotated-logical-rect semantic must passBindingStrategy.originalBoxexplicitly. - Add per-corner rotation gesture: an outer ring around each corner-handle captures rotation when
rotatable: true. Sized viarotationHandleGestureSize(default 64 px). Add rotation callbacks:onRotationStart/onRotationUpdate/onRotationEnd/onRotationCancel. TransformableBoxControlleraddsrotation,initialRotation,bindingStrategy,onRotateStart/onRotateUpdate/onRotateEnd/onRotateCancel.onResizeUpdateandonRotateUpdateskip state writes onresult.feasible == falseand overrideresult.rect/result.rotationto the controller's last feasible value, so consumers binding visible state via callbacks (box.rect = result.rect) stay clamp-pinned at the last feasible position rather than snapping back to gesture-start.- Side handles render rotated under non-zero rotation and translate gesture coordinates into the box's un-rotated frame so resize tracks the cursor visually.
- Hit-testing gates corner taps to the rotated polygon (not the AABB) so rotated boxes don't capture clicks in their AABB wedges.
- Playground gains a rotation slider,
bindingStrategytoggle, debug overlays for rotated/unrotated bounds, and a tick-by-tick test recorder that captures full gesture sequences (rotation + bindingStrategy aware) for regression replay. - Tests: rotated controller gestures, rotated layout, rotated drag hit-gating, rotated gesture integration, clamp-shrink continuity under rotation, and a force-flip fallback regression test.
- [BREAKING]
defaultResizeModeResolver()is nowTransformableBoxController.defaultResizeModeResolver(). The top-level function has been removed; consumers that referenced it directly (e.g. as a default forresizeModeResolver) must update to the qualified static.
Packages with changes:
- Fix taps should pass through when onTap is not set. Issue#31
Packages with changes:
- Fix child positioning offset bug. Issue#27
Packages with changes:
- Add parameters for supported devices. (PR #28 by @Gold872).
- Upgrade dependencies.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Update root pubspec.yaml name from box_transform to melos_box_transform.
- Fix repository & homepage url in pubspec.yaml
- Update root pubspec.yaml name from box_transform to melos_box_transform.
- Fix repository & homepage url in pubspec.yaml
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Update dependencies & resolve deprecation warnings.
- Added onTap event to BoxTransformController. (PR #23 by @joakimunge)
- Deny different transform operations when a box is already undergoing.
- Add optional
resizeModeResolveroverride toonResizeUpdateinTransformableBoxController.
- Update dependencies & resolve deprecation warnings.
- Fix a bug where terminal resize events triggered on the incorrect axis.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Fix an issue where visibleHandles disabled the handles instead of hiding them but keeping them enabled.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Remove
DoubleExtfrom package exports.
- Deny trackpad pointer devices to prevent erratic drag events when interacting with TransformableBox.
- Inherit
handleAlignmentfromTransformableBoxforAngularHandle. - Add
debugPaintHandleBoundsparam for painting handle bounds.
Packages with breaking changes:
Packages with other changes:
- There are no breaking changes in this release.
- Fix stack overflow error when the clamping rect is smaller than the box rect.
- [BREAKING]: Replace
hideHandlesWhenNotResizablewithenabledHandlesandvisibleHandles. - Replace the usage of Listener widgets with GestureDetectors in the TransformableBox.
- Add new controls to the playground to reflect the new handle parameters.
- Bump up box_transform version to
0.4.0.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Fix controller pattern not updating the UI when the controller is updated.
- Change null resizeModeResolver pattern to a non-null pattern to fix a crash.
- Correct two broken doc pages.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Bump up box_transform version to
0.3.0.
Packages with breaking changes:
Packages with other changes:
- There are no breaking changes in this release.
- Refactored the core logic to make it more readable, cleaner and easier to maintain.
- Fix issues with resizing, constraints, clamping and flipping.
- [BREAKING]: Replace
flipRectwithallowFlipping. - [BREAKING]: Rename
initialBoxtoinitialRectinBoxTransformer.moveandBoxTransformer.resizemethods. ResizeResultnow exposeslaregestrect andhandleused.- Refactored code and performed some cleanup.
- Bump up Dart sdk constraints to
3.0.0. - Update all documentation to reflect the new changes.
- Fix broken links in docs.
- Add tests for resizing features.
- Bump up Dart sdk constraints to
3.0.0. - Bump up box_transform version to
0.3.0. - [BREAKING]: Replace
onResizedwithonResizeUpdate. - [BREAKING]: Replace
flipWhileResizingwithallowFlippingWhileResizing. - [BREAKING]: Replace
onMovedwithonDragUpdate. - [BREAKING]: Rename
resolveResizeModeCallbacktoresizeModeResolver. - [BREAKING]:
onChangedcallback now has two parameters:UITransformResultandPointerMoveEvent. - [BREAKING]:
onTerminalSizeReachedcallback now also exposes underlyingPointerEvent. - Add
onResizeStartandonResizeEndcallbacks. - Add
onDragStartandonDragEndcallbacks for move operation. - Add simple example alongside an advanced playground example.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Update license to Apache 2.0.
- Update docs and fix broken links.
- Update license to Apache 2.0.
- Update playground to use unified clamping rect.
- Update docs and fix broken links.
Packages with breaking changes:
Packages with other changes:
- Fix scaling of rect not matching cursor position.
- Add
hideHandlesWhenNotResizableflag to hide handles when the box is not resizable by @timmaffett. - BREAKING CHANGE:
TransformableBox.childBuilderis nowTransformableBox.contentBuilder. - More advanced example with multiple boxes.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Add example.
- Bump "flutter_box_transform" to
0.1.1.
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- Bump "box_transform" to
0.1.0.
- Bump "flutter_box_transform" to
0.1.0.