# Draggable Window

## 🪟 DraggableWindow Class

The `DraggableWindow` class is a parent class of all split UI windows. It essentially allows the windows to be draggable. The window must be created with the UI Toolkit and must have a button named 'Dragger' that will begin dragging and it should have an element named 'Root' that contains all content.

> **Namespace:** `Esper.Inventool.UI`\
> **Access:** `public`\
> **Type:** `class`\
> **Inherits:** `CrossInputSupportedWindow`

***

#### 📦 Fields

| Access          | Field                    | Type                    | Description                                     |
| --------------- | ------------------------ | ----------------------- | ----------------------------------------------- |
| `public`        | `activeSortingOrder`     | `int`                   | Sorting order when window is active.            |
| `public`        | `inactiveSortingOrder`   | `int`                   | Sorting order when window is inactive.          |
| `public`        | `startingPosition`       | `StartingPosition`      | Initial placement anchor and offset.            |
| `protected`     | `dragger`                | `Button`                | UI element used to drag the window.             |
| `protected`     | `root`                   | `VisualElement`         | Root container of window content.               |
| `protected`     | `startingMousePosition`  | `Vector3`               | Mouse position at start of drag.                |
| `protected`     | `startingWindowPosition` | `Vector3`               | Window position at drag start.                  |
| `protected`     | `pointerDown`            | `bool`                  | True while mouse button is held on dragger.     |
| `protected`     | `firstOpen`              | `bool`                  | True until the window opens for the first time. |
| `public static` | `windows`                | `List<DraggableWindow>` | All instantiated draggable windows.             |
| `public static` | `active`                 | `DraggableWindow`       | Currently active window.                        |
| `public static` | `onDragStarted`          | `UnityEvent`            | Event when any window drag begins.              |
| `public static` | `onDrag`                 | `UnityEvent`            | Event when any window is being dragged.         |
| `public static` | `onStopDrag`             | `UnityEvent`            | Event when any window drag ends.                |

***

### 🧰 Methods

| Access               | Method                                            | Returns | Description                                            |
| -------------------- | ------------------------------------------------- | ------- | ------------------------------------------------------ |
| `protected override` | `Awake()`                                         | `void`  | Initialize UI elements, register drag callbacks.       |
| `private`            | `OnDestroy()`                                     | `void`  | Remove this window from static registry.               |
| `protected virtual`  | `RegisterButtonEvents(Button button)`             | `void`  | Wire hover and click events for a button.              |
| `public`             | `SetNextAsActive()`                               | `void`  | Activate the next open window in stacking order.       |
| `public virtual`     | `Open()`                                          | `void`  | Prepare window placement on first open.                |
| `public`             | `PlaceAtStartingPosition(GeometryChangedEvent e)` | `void`  | Position window based on `startingPosition`.           |
| `public virtual`     | `Close()`                                         | `void`  | Hide window and clear active status.                   |
| `public`             | `SetAsActive()`                                   | `void`  | Mark this window as topmost active.                    |
| `public`             | `SetAsInactive()`                                 | `void`  | Mark this window as inactive.                          |
| `protected`          | `SetActive(PointerDownEvent e)`                   | `void`  | Handle pointer-down to activate window.                |
| `protected`          | `StartDrag(PointerDownEvent e)`                   | `void`  | Begin drag, capture positions, invoke `onDragStarted`. |
| `protected`          | `Drag(PointerMoveEvent e)`                        | `void`  | Move window with pointer, clamp to panel bounds.       |
| `protected`          | `StopDrag(PointerUpEvent e)`                      | `void`  | End drag and invoke `onStopDrag`.                      |

***

### 🧩 Nested Types

#### `public struct StartingPosition`

| Field    | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `anchor` | `Anchor`  | Screen anchor for placement. |
| `offset` | `Vector2` | Pixel offset from anchor.    |

#### `public enum StartingPosition.Anchor`

| Name          | Description          |
| ------------- | -------------------- |
| `Center`      | Center of the panel. |
| `TopLeft`     | Top-left corner.     |
| `TopRight`    | Top-right corner.    |
| `BottomLeft`  | Bottom-left corner.  |
| `BottomRight` | Bottom-right corner. |

## Active Window

The active draggable window is the one that was last interacted with. This happens automatically. You can access the active draggable window with `DraggableWindow.active`.

You can set a draggable window as the active one with the `SetAsActive` method. Use `SetAsInactive` to have the opposite effect.

```csharp
myDraggableWindow.SetAsActive();
```

To set the next one as active, use `SetNextAsActive`.

```csharp
myDraggableWindow.SetNextAsActive();
```
