> For the complete documentation index, see [llms.txt](https://viridian-games.gitbook.io/pixel-palette/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://viridian-games.gitbook.io/pixel-palette/core-components/selection-system.md).

# Selection System

Three pieces work together: **SelectionBrush** (draws the marquee), **SelectionManager** (stores captured pixels, handles move), and **SelectionOverlay** (renders marching ants).

#### SelectionBrush

The Select tool (`BrushType.Select`) creates a `SelectionBrush` with `SelectionKind.Rect`. On drag:

* `StrokeStart` — clears any existing selection, records the anchor pixel, calls `SelectRect()` or `SelectEllipse()` with a 1×1 rect
* `StrokeMove` — expands the rect from anchor to current pixel, calls `SelectRect`/`SelectEllipse` each frame to update
* `StrokeEnd` — just clears the anchor state

Only rect selections are created currently (the brush always uses `SelectionKind.Rect`).

#### SelectionManager — Lifecycle

**Creating a selection** (`SelectRect` / `SelectEllipse`):

1. Clears any previous selection (stamps captured pixels back first)
2. Stores the bounds rect and shape kind (Rect/Ellipse)
3. `CaptureSelectedPixels()` — walks every pixel within the shape bounds on the active layer's `RawPixels`. Pixels outside the shape (for ellipse) are skipped (left as default `Color32(0,0,0,0)`). Copies into `selectedPixels[]`.
4. `ClearActiveLayerAtBounds()` — zeroes out (alpha=0) every pixel within the shape that had non-zero alpha. Uploads the full layer texture.
5. Fires `OnSelectionChanged`

The area inside the selection is now empty on the layer — the pixels are safely stored in `selectedPixels`.

**Ending a selection** (`ClearSelection`):

1. `StampSelectionToLayer()` — writes all non-transparent `selectedPixels` back into the active layer's `RawPixels` at the original bounds position. This is wrapped in `BeginDirectLayerChange`/`EndDirectLayerChange` for undo support.
2. Clears `hasSelection`, nulls out the pixel buffer
3. Fires `OnSelectionChanged`

**Deleting a selection** (`DeleteSelection`):

1. Discards `selectedPixels` without stamping back
2. The selected area stays empty (cleared)
3. Fires `OnSelectionChanged`

#### Selection Move (drag)

**Starting a move** (`StartMove`) — if you click inside an existing selection (checked in `CanvasInputHandler`) and the current tool is NOT the Select tool:

1. Sets `isMoving = true`, `moveOffset = Vector2Int.zero`
2. Refreshes the composite of the original bounds area (shows the cleared layer underneath)

**During move** (`UpdateMove`) — called each frame with the offset from the click start:

1. Refreshes composite of both the old visual position and the new visual position (so the marching ants and floating selection content redraw)
2. `moveOffset` tracks the accumulated offset

**Committing a move** (`EndMove`) — when the pointer lifts:

1. Bakes the offset into bounds permanently: `bounds += moveOffset`
2. Resets `moveOffset` to zero
3. Fires `OnSelectionMoved`

**Hit test** (`ContainsPoint`) — checks if a pixel falls within the visual bounds (bounds + moveOffset), accounting for shape kind. Uses `IsInShapeStatic` which anyone can call without a SelectionManager reference.

#### Selection Overlay (Marching Ants)

`SelectionOverlay` is a separate RawImage on top of the canvas. It creates its own Texture2D matching the canvas size.

Each frame:

1. If `HasSelection` is false → hide overlay
2. If selection bounds or kind changed (tracked by hash) → recompute the outline path:
   * **Rect** — walks the 4 perimeter edges
   * **Ellipse** — midpoint ellipse algorithm, points sorted by angle for a continuous path
3. `DrawAnts()` — clears the overlay texture, then draws dashes along the path. Dash visibility is determined by `((index + phase) % 8) < 4` where `phase` advances with `Time.unscaledTime * 4`. This creates the marching animation.

#### Selection in Compositing

During `RefreshComposite`, two extra steps run after the layer blend:

1. **`StampSelectionOverlay`** — if `HasSelection && HasSelectionPixels`, alpha-blends `selectedPixels` (offset by `moveOffset`) onto the composited result. This makes the floating selection content visible.
2. **`StampOutlineOnPixels`** — reads the outline path from `SelectionManager.GetOutline()` and draws the animated marching ants dashes directly on the composited pixels. Uses `Mathf.Sin(time * 8 + index)` for the dash pattern.

Both only run on the dirty intersection with the visual bounds — not the whole canvas.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://viridian-games.gitbook.io/pixel-palette/core-components/selection-system.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
