Using a controller

TransformableBox uses a controller pattern. This is the most flexible pattern and allows you to control the transformable box externally with proper state management.

To create a controller, you can use the TransformableBoxController class. It mirrors a lot of the observed parameters in the constructor excluding contentBuilder, handleBuilder, handleTapSize, allowFlippingWhileResizing, movable, resizable, handleAlignment, enabledHandles, visibleHandles, and allowContentFlipping since these are accessibility and rendering features that are controlled at the Widget level.

When using a controller, you should move these parameters from your TransformableBox to the constructor of the TransformableBoxController: box, flip, clampingRect, constraints, and resizeModeResolver. These are all intrinsically managed by the controller. There must always be only one source of truth, either the TransformableBox or the TransformableBoxController, not both.

Initialize a controller like so:

Initializing a controller
  late final TransformableBoxController controller;

  @override
  void initState() {
    super.initState();
    controller = TransformableBoxController(rect: rect);
  }

Don't forget to dispose your controller when no longer needed.

Disposing a controller
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

Pass the controller to the TransformableBox constructor.

Passing a controller
  TransformableBox(
    controller: controller,
    contentBuilder: (context, rect, flip) {...},
  );

Listening to changes

You can listen to changes in the controller using the addListener method. This will be called whenever the controller changes. You can use the removeListener method to remove the listener.

Listening to changes
  controller.addListener(onControllerChanged);

Remove the listener when no longer needed.

Removing a listener
  controller.removeListener(onControllerChanged);

Setting constraints

You can set constraints on the controller using the setConstraints method.

Setting constraints
  controller.setConstraints(BoxConstraints(
    minWidth: 100,
    minHeight: 100,
    maxWidth: 1000,
    maxHeight: 1000,
  ));

Limiting movements

You can limit the movements of the controller using the setClampingBox method.

Limiting movements
  controller.setClampingRect(Rect.fromLTWH(0, 0, 1000, 1000));

Other things you can do with a controller

The TransformableBoxController almost mirrors the constructor parameters of the TransformableBox. You can do things like setting a rect, flip, constraints, clampingRect, disabling resizing or moving, etc...

Things controller can do
// Change current rect
controller.setRect(rect);

// Change current flip
controller.setFlip(flip);

// Change constraints
controller.setConstraints(constraints);

// Change clamping rect
controller.setClampingRect(clampingRect);

// Disable flipping the rect while resizing
controller.setAllowFlippingWhileResizing(false);