---
title: Using a controller
---

## 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.

<Warning>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.</Warning>

Initialize a controller like so:

```dart title="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.

```dart title="Disposing a controller"
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
```

Pass the controller to the `TransformableBox` constructor.

```dart title="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.

```dart title="Listening to changes"
  controller.addListener(onControllerChanged);
```
Remove the listener when no longer needed.

```dart title="Removing a listener"
  controller.removeListener(onControllerChanged);
```
### Setting constraints

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

```dart title="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.

```dart title="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...

```dart title="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);
```
