Files
Terminal.Gui/docfx/docs/arrangement.md
Copilot afa7da3ae5 Fixes #4078 - Implement automatic URL detection with OSC 8 hyperlinks at driver level (#4340)
* Initial plan

* Enable VT processing in WindowsOutput to support hyperlink detection

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Address code review feedback - track VT enablement and add error handling

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Revert VT processing changes - investigating actual root cause

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Implement OSC 8 hyperlink support in Attribute and OutputBase

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Implement automatic URL detection with OSC 8 at driver level

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Fix OSC 8 URL wrapping to handle ANSI escape sequences properly

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Update newinv2.md

Terminal.Gui v2 introduces a reimagined architecture, removing redundant and overly complex code from v1. Key changes include:

- Added TrueColor support with 24-bit RGB handling.
- Introduced modular adornments framework (Margin, Border, Padding).
- Enhanced Unicode and wide character support for internationalization.
- Simplified API with centralized navigation and modern .NET standards.
- Added built-in scrolling via `Viewport` and improved `ScrollBar`.
- Introduced new views (Bar, CharMap, ColorPicker, etc.) and enhanced existing ones.
- Added `ConfigurationManager` for customizable themes and settings.
- Improved visual fidelity with `LineCanvas`, gradients, and borders.
- Introduced logging, metrics, and Sixel image support.
- Enhanced keyboard and mouse APIs for better interaction handling.
- Ensured AOT compatibility for simplified deployment.

These changes modernize the library, improve usability, and expand its capabilities for terminal-based applications.

* Remove automatic URL detection - reverting to clean state

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Revamp View.md documentation for clarity and depth

Comprehensively restructured and enhanced the `View.md` documentation for the `Terminal.Gui` library to improve usability and completeness.

- Added a Table of Contents for easier navigation.
- Rewrote the "View Hierarchy" section to clarify terminology and key properties, with links to relevant API references.
- Expanded "View Composition" and "Core Concepts" sections with detailed explanations of layers, adornments, and scrolling.
- Detailed the "View Lifecycle" with step-by-step processes and code examples for initialization, layout, drawing, input handling, and disposal.
- Reorganized and expanded the "Subsystems" section, covering commands, input handling, layout, drawing, navigation, and scrolling.
- Updated the "Modal Views" section with examples for dialogs, wizards, and modal view types.
- Introduced a "Common View Patterns" section with practical examples for creating custom views, adding subviews, and implementing scrolling.
- Added an "Advanced Topics" section covering diagnostics, view states, and shadow effects.
- Included numerous inline code examples to illustrate key concepts.
- Concluded with a "See Also" section linking to related deep-dive documentation.

These changes significantly improve the structure, clarity, and accessibility of the documentation, making it easier for developers to understand and use the library effectively.

* Restore working automatic URL detection with fix for URLs containing ANSI sequences

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Fix URL regex to handle underscores and trailing punctuation + add comprehensive tests

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Update and expand Configuration Management documentation

The document title was updated to "Configuration Management Deep Dive" to reflect its expanded scope. A new Table of Contents was added for improved navigation. The introduction and "Overview" sections were rewritten to provide a clearer explanation of the `ConfigurationManager` class and its key features.

New sections were added, including "Getting Started," "Themes and Schemes," "Defining Configuration Properties," "Events," and "Best Practices." These sections provide detailed explanations, examples, and recommendations for using the `ConfigurationManager` effectively.

The "Configuration Scopes" and "Configuration Locations and Precedence" sections were restructured and expanded with detailed explanations, diagrams, and examples. Advanced topics such as JSON error handling, runtime configuration, and file system watching were introduced.

The document now includes several new examples, such as theme switching and custom application settings, along with references to related topics and UICatalog examples. The content was reorganized for clarity, with redundant sections removed.

* Refactor and expand Arrangement system documentation

Updated the title to "View Arrangement Deep Dive" and added a Table of Contents for better navigation. Expanded the "Overview" section and restructured "Arrangement Modes" with detailed examples. Added new sections for "Arrange Mode (Interactive)," "Movable Views," "Resizable Views," and "Creating Resizable Splitters," with practical code samples.

Enhanced "Tiled vs Overlapped Layouts" and "Modal Views" sections, and introduced "Runnable Views" to explain non-modal behavior. Expanded the "Examples" section with multiple use cases and added advanced topics like Z-order management and arrangement events.

Updated `arrangement-lexicon.md` with API links for key terms. Improved formatting and consistency throughout the document to enhance clarity and usability.

* Update CONTRIBUTING.md references and add critical note

Updated the reference to `CONTRIBUTING.md` to use a relative
path (`../CONTRIBUTING.md`) for accurate resolution. Enhanced
instructions for AI agents, including CoPilot and Cursor, to
strictly follow the updated guidelines. Added a **CRITICAL**
note requiring CoPilot to internalize and adhere to the
guidelines, including when operating in Agent mode.

* Refactor URL handling and add OSC 8 hyperlink support

Replaced `UrlRegex` with the new `Osc8UrlLinker` utility to handle URL detection and wrapping with OSC 8 hyperlink sequences, improving modularity and maintainability. Updated `OutputBase` to use `Osc8UrlLinker.WrapOsc8` for URL processing and removed legacy `WrapUrlsWithHyperlinks` logic.

Added the `Osc8UrlLinker` class with robust URL parsing, support for allowed schemes, and handling of edge cases like trailing punctuation and ANSI escape sequences. Improved performance with efficient `StringBuilder` usage.

Enhanced `AnimationScenario` to ensure URLs with underscores are drawn correctly. Improved code readability by renaming constants, simplifying nullable handling, and updating documentation.

Replaced legacy `UrlDetectionTests` with `Osc8UrlLinkerTests`, covering standalone URLs, URLs in text, multiple URLs, and edge cases. Verified hyperlink wrapping correctness and visible content integrity.

Updated `Terminal.sln.ToDo.DotSettings` to disable auto-opening of the Stack Trace Explorer. Cleaned up unused code, enabled nullable reference types, and improved XML documentation formatting.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: tig <585482+tig@users.noreply.github.com>
Co-authored-by: Tig <tig@users.noreply.github.com>
2025-10-26 13:03:17 -06:00

736 lines
20 KiB
Markdown

# View Arrangement Deep Dive
Terminal.Gui provides a powerful **Arrangement** system that enables users to interactively move and resize views using the keyboard and mouse. This system supports both **Tiled** and **Overlapped** layout modes, allowing for flexible UI organization.
See the [Layout Deep Dive](layout.md) for the broader layout system context.
## Table of Contents
- [Overview](#overview)
- [Arrangement Modes](#arrangement-modes)
- [Arrange Mode (Interactive)](#arrange-mode-interactive)
- [Tiled vs Overlapped Layouts](#tiled-vs-overlapped-layouts)
- [Movable Views](#movable-views)
- [Resizable Views](#resizable-views)
- [Creating Resizable Splitters](#creating-resizable-splitters)
- [Modal Views](#modal-views)
- [Runnable Views](#runnable-views)
- [Examples](#examples)
---
## Overview
The [View.Arrangement](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_Arrangement) property controls how users can arrange views within their [SuperView](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_SuperView). The [ViewArrangement](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) enum provides flags that can be combined to specify arrangement behavior.
### Arrangement Lexicon
[!INCLUDE [Arrangement Lexicon](~/includes/arrangement-lexicon.md)]
### ViewArrangement Flags
The [ViewArrangement](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) enum supports these flags (can be combined):
- **Fixed** (0) - View cannot be moved or resized (default)
- **Movable** (1) - View can be moved by the user
- **LeftResizable** (2) - Left edge can be resized
- **RightResizable** (4) - Right edge can be resized
- **TopResizable** (8) - Top edge can be resized
- **BottomResizable** (16) - Bottom edge can be resized
- **Resizable** (30) - All edges can be resized (combines all resize flags)
- **Overlapped** (32) - View overlaps other views (enables Z-order)
---
## Arrangement Modes
### Fixed (Default)
Views with [ViewArrangement.Fixed](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) cannot be moved or resized by the user:
```csharp
var view = new View
{
Arrangement = ViewArrangement.Fixed // Default
};
```
### Movable
Views with [ViewArrangement.Movable](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) can be dragged with the mouse or moved with keyboard:
```csharp
var window = new Window
{
Title = "Movable Window",
Arrangement = ViewArrangement.Movable
};
```
**User Interaction:**
- **Mouse**: Drag the top [Border](~/api/Terminal.Gui.ViewBase.Border.yml)
- **Keyboard**: Press `Ctrl+F5` to enter Arrange Mode, use arrow keys to move
### Resizable
Views with [ViewArrangement.Resizable](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) can be resized by the user:
```csharp
var window = new Window
{
Title = "Resizable Window",
Arrangement = ViewArrangement.Resizable
};
```
**User Interaction:**
- **Mouse**: Drag any border edge
- **Keyboard**: Press `Ctrl+F5` to enter Arrange Mode, press `Tab` to cycle resize handles
### Movable and Resizable
Combine flags for full desktop-like experience:
```csharp
var window = new Window
{
Title = "Movable and Resizable",
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
};
```
**Note:** When both `Movable` and `Resizable` are set, the top edge cannot be resized (Movable takes precedence).
### Individual Edge Resizing
For fine-grained control, use individual edge flags:
```csharp
// Only bottom edge resizable
var view = new View
{
Arrangement = ViewArrangement.BottomResizable
};
// Left and right edges resizable
var view2 = new View
{
Arrangement = ViewArrangement.LeftResizable | ViewArrangement.RightResizable
};
```
---
## Arrange Mode (Interactive)
**Arrange Mode** is an interactive mode for arranging views using the keyboard. It is activated by pressing the **Arrange Key** (default: `Ctrl+F5`, configurable via [Application.ArrangeKey](~/api/Terminal.Gui.App.Application.yml#Terminal_Gui_App_Application_ArrangeKey)).
### Entering Arrange Mode
When the user presses `Ctrl+F5`:
1. Visual indicators appear on arrangeable views
2. If [ViewArrangement.Movable](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml), a move indicator (`◊`) appears in top-left corner
3. If [ViewArrangement.Resizable](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml), pressing `Tab` cycles to resize indicators
4. Arrow keys move or resize the view
5. Press `Esc`, `Ctrl+F5`, or click outside to exit
### Arrange Mode Indicators
The [Border](~/api/Terminal.Gui.ViewBase.Border.yml) shows visual indicators based on arrangement options:
| Arrangement Flag | Indicator | Location |
|------------------|-----------|----------|
| Movable | `◊` (Glyphs.Move) | Top-left corner |
| Resizable | `⇲` (Glyphs.SizeBottomRight) | Bottom-right corner |
| LeftResizable | `↔` (Glyphs.SizeHorizontal) | Left edge, centered |
| RightResizable | `↔` (Glyphs.SizeHorizontal) | Right edge, centered |
| TopResizable | `↕` (Glyphs.SizeVertical) | Top edge, centered |
| BottomResizable | `↕` (Glyphs.SizeVertical) | Bottom edge, centered |
### Keyboard Controls in Arrange Mode
- **Arrow Keys** - Move or resize based on active mode
- **Tab** - Cycle between move and resize modes (if both available)
- **Shift+Tab** - Cycle backwards
- **Esc** - Exit Arrange Mode
- **Ctrl+F5** - Exit Arrange Mode
### Requirements for Arrangement
For a View to be arrangeable:
1. Must be part of a [SuperView](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_SuperView)
2. Position and dimensions must be independent of other SubViews
3. Must have [View.Arrangement](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_Arrangement) flags set
4. Typically needs a [Border](~/api/Terminal.Gui.ViewBase.Border.yml) for mouse interaction
---
## Tiled vs Overlapped Layouts
### Tiled Layout
In **Tiled** layouts, SubViews typically do not overlap. There is no Z-order; all views are at the same layer.
```csharp
var container = new View { Arrangement = ViewArrangement.Fixed };
var view1 = new View { X = 0, Y = 0, Width = 20, Height = 10 };
var view2 = new View { X = 21, Y = 0, Width = 20, Height = 10 };
container.Add(view1, view2);
// Views are side-by-side, non-overlapping
```
**Characteristics:**
- Default mode for most TUI applications
- Views use [Pos](~/api/Terminal.Gui.Pos.yml) and [Dim](~/api/Terminal.Gui.Dim.yml) for relative positioning
- No Z-order management needed
- More predictable layout behavior
### Overlapped Layout
In **Overlapped** layouts, SubViews can overlap with Z-order determining visual stacking.
Enable overlapped mode with [ViewArrangement.Overlapped](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml):
```csharp
var container = new View
{
Arrangement = ViewArrangement.Overlapped
};
var window1 = new Window
{
X = 5, Y = 3, Width = 40, Height = 15,
Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped
};
var window2 = new Window
{
X = 15, Y = 8, Width = 40, Height = 15,
Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped
};
container.Add(window1, window2);
// window2 will overlap window1
```
**Characteristics:**
- Z-order determined by SubViews collection order
- Later views appear above earlier views
- Tab navigation constrained to current overlapped view
- Use `Ctrl+Tab` / `Ctrl+Shift+Tab` to switch between overlapped views
---
## Movable Views
Views with [ViewArrangement.Movable](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) can be repositioned by the user.
### Enabling Movable
```csharp
var window = new Window
{
Title = "Drag Me!",
X = 10,
Y = 5,
Width = 40,
Height = 15,
Arrangement = ViewArrangement.Movable,
BorderStyle = LineStyle.Single
};
```
### Moving with Mouse
- **Click and drag** the top [Border](~/api/Terminal.Gui.ViewBase.Border.yml) to move the view
- The view's [Frame](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_Frame) updates as it moves
- Release the mouse to complete the move
### Moving with Keyboard
1. Press `Ctrl+F5` to enter **Arrange Mode**
2. A move indicator (`◊`) appears in the top-left corner
3. Use **arrow keys** to move the view
4. Press `Esc` or `Ctrl+F5` to exit Arrange Mode
---
## Resizable Views
Views with resizable flags can be resized by the user on specific edges.
### All Edges Resizable
```csharp
var window = new Window
{
Title = "Resize Me!",
Arrangement = ViewArrangement.Resizable,
BorderStyle = LineStyle.Single
};
```
### Specific Edge Resizable
```csharp
// Only right and bottom edges resizable
var view = new View
{
Arrangement = ViewArrangement.RightResizable | ViewArrangement.BottomResizable,
BorderStyle = LineStyle.Single
};
```
### Resizing with Mouse
- **Click and drag** any enabled border edge
- Resize indicators appear on hover
- The view's [Width](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_Width) and [Height](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_Height) update
### Resizing with Keyboard
1. Press `Ctrl+F5` to enter **Arrange Mode**
2. Press `Tab` to cycle to resize mode
3. Resize indicator (`⇲`) appears
4. Use **arrow keys** to resize
5. Press `Esc` or `Ctrl+F5` to exit
---
## Creating Resizable Splitters
A common pattern in tiled layouts is creating a resizable splitter between two panes.
### Horizontal Splitter (Left/Right Panes)
```csharp
View leftPane = new ()
{
X = 0,
Y = 0,
Width = Dim.Fill(Dim.Func(_ => rightPane.Frame.Width)),
Height = Dim.Fill(),
BorderStyle = LineStyle.Single
};
View rightPane = new ()
{
X = Pos.Right(leftPane) - 1,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill(),
Arrangement = ViewArrangement.LeftResizable,
BorderStyle = LineStyle.Single,
SuperViewRendersLineCanvas = true
};
rightPane.Border.Thickness = new Thickness(1, 0, 0, 0); // Only left border
container.Add(leftPane, rightPane);
```
**How it works:**
- `rightPane` has [ViewArrangement.LeftResizable](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml) - its left border is draggable
- `leftPane` uses [Dim.Fill](~/api/Terminal.Gui.Dim.yml) with a function to fill remaining space
- `SuperViewRendersLineCanvas = true` ensures proper line rendering
- Only the left border is visible, acting as the splitter
### Vertical Splitter (Top/Bottom Panes)
```csharp
View topPane = new ()
{
X = 0,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill(Dim.Func(_ => bottomPane.Frame.Height)),
BorderStyle = LineStyle.Single
};
View bottomPane = new ()
{
X = 0,
Y = Pos.Bottom(topPane) - 1,
Width = Dim.Fill(),
Height = Dim.Fill(),
Arrangement = ViewArrangement.TopResizable,
BorderStyle = LineStyle.Single,
SuperViewRendersLineCanvas = true
};
bottomPane.Border.Thickness = new Thickness(1, 0, 0, 0); // Only top border
container.Add(topPane, bottomPane);
```
---
## Modal Views
**Modal** views run as exclusive applications that capture all user input until closed.
See the [Multitasking Deep Dive](multitasking.md) for complete details on modal execution.
### What Makes a View Modal
A view is modal when:
- Run via [Application.Run](~/api/Terminal.Gui.App.Application.yml#Terminal_Gui_App_Application_Run_Terminal_Gui_Views_Toplevel_System_Func_System_Exception_System_Boolean__)
- [Toplevel.Modal](~/api/Terminal.Gui.Views.Toplevel.yml#Terminal_Gui_Views_Toplevel_Modal) = `true`
### Modal Characteristics
- **Exclusive Input** - All keyboard and mouse input goes to the modal view
- **Constrained Z-Order** - Modal view has Z-order of 1, everything else at 0
- **Blocks Execution** - `Application.Run` blocks until [Application.RequestStop](~/api/Terminal.Gui.App.Application.yml#Terminal_Gui_App_Application_RequestStop_Terminal_Gui_Views_Toplevel_) is called
- **Own RunState** - Each modal view has its own [RunState](~/api/Terminal.Gui.App.RunState.yml)
### Modal View Types
- [Dialog](~/api/Terminal.Gui.Views.Dialog.yml) - Centered modal window with button support
- [MessageBox](~/api/Terminal.Gui.Views.MessageBox.yml) - Simple message dialogs
- [Wizard](~/api/Terminal.Gui.Views.Wizard.yml) - Multi-step modal dialogs
### Modal Example
```csharp
var dialog = new Dialog
{
Title = "Confirm",
Width = 40,
Height = 10
};
var label = new Label
{
Text = "Are you sure?",
X = Pos.Center(),
Y = 2
};
dialog.Add(label);
var ok = new Button { Text = "OK" };
ok.Accepting += (s, e) => Application.RequestStop();
dialog.AddButton(ok);
// Run modally - blocks until closed
Application.Run(dialog);
// Dialog has been closed
```
---
## Runnable Views
**Runnable** views are those run via [Application.Run](~/api/Terminal.Gui.App.Application.yml). Each non-modal Runnable view operates as a self-contained "application" with its own [RunState](~/api/Terminal.Gui.App.RunState.yml).
See the [Multitasking Deep Dive](multitasking.md) for complete details.
### Non-Modal Runnable Views
```csharp
var toplevel = new Toplevel
{
Modal = false // Non-modal
};
// Runs as independent application
Application.Run(toplevel);
```
**Characteristics:**
- Has its own `RunState`
- Events dispatched independently
- Can run on separate threads
- See `BackgroundWorkerCollection` for multi-threaded examples
### Modal vs Non-Modal Runnable
| Aspect | Modal | Non-Modal |
|--------|-------|-----------|
| Input | Exclusive | Shared |
| Z-Order | Constrained (1 vs 0) | Full Z-order support |
| Blocks Execution | Yes | No |
| Use Case | Dialogs, confirmations | Multi-window apps |
---
## Tiled vs Overlapped Layouts
### Tiled Layout (Default)
SubViews do not overlap, positioned side-by-side or top-to-bottom:
```csharp
var container = new View();
var left = new View
{
X = 0,
Y = 0,
Width = Dim.Percent(50),
Height = Dim.Fill()
};
var right = new View
{
X = Pos.Right(left),
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill()
};
container.Add(left, right);
```
**Benefits:**
- Simpler layout logic
- No Z-order management
- More predictable behavior
- Standard for most TUI applications
### Overlapped Layout
SubViews can overlap with Z-order determining which is on top:
```csharp
var container = new View
{
Arrangement = ViewArrangement.Overlapped
};
var window1 = new Window
{
X = 5,
Y = 3,
Width = 40,
Height = 15,
Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped
};
var window2 = new Window
{
X = 15,
Y = 8,
Width = 40,
Height = 15,
Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped
};
container.Add(window1, window2);
// window2 appears on top of window1
```
**Z-Order:**
- Order in [View.SubViews](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_SubViews) determines Z-order
- Later views appear above earlier views
- Use [View.BringSubviewToFront](~/api/Terminal.Gui.ViewBase.View.yml) to change Z-order
**Navigation:**
- `Tab` / `Shift+Tab` - Navigate within current overlapped view
- `Ctrl+Tab` (`Ctrl+PageDown`) - Switch to next overlapped view
- `Ctrl+Shift+Tab` (`Ctrl+PageUp`) - Switch to previous overlapped view
---
## Examples
### Example 1: Movable and Resizable Window
```csharp
using Terminal.Gui;
Application.Init();
var window = new Window
{
Title = "Drag and Resize Me! (Ctrl+F5 for keyboard mode)",
X = Pos.Center(),
Y = Pos.Center(),
Width = 50,
Height = 15,
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
BorderStyle = LineStyle.Double
};
var label = new Label
{
Text = "Try dragging the border with mouse\nor press Ctrl+F5!",
X = Pos.Center(),
Y = Pos.Center()
};
window.Add(label);
Application.Run(window);
Application.Shutdown();
```
### Example 2: Horizontal Resizable Splitter
```csharp
Application.Init();
var top = new Toplevel();
var leftPane = new FrameView
{
Title = "Left Pane",
X = 0,
Y = 0,
Width = Dim.Fill(Dim.Func(_ => rightPane.Frame.Width)),
Height = Dim.Fill()
};
var rightPane = new FrameView
{
Title = "Right Pane (drag left edge)",
X = Pos.Right(leftPane) - 1,
Y = 0,
Width = Dim.Fill(),
Height = Dim.Fill(),
Arrangement = ViewArrangement.LeftResizable,
SuperViewRendersLineCanvas = true
};
rightPane.Border.Thickness = new Thickness(1, 0, 0, 0);
top.Add(leftPane, rightPane);
Application.Run(top);
Application.Shutdown();
```
### Example 3: Overlapped Windows
```csharp
Application.Init();
var desktop = new Toplevel
{
Arrangement = ViewArrangement.Overlapped
};
var window1 = new Window
{
Title = "Window 1",
X = 5,
Y = 3,
Width = 40,
Height = 12,
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable | ViewArrangement.Overlapped
};
var window2 = new Window
{
Title = "Window 2 (overlaps Window 1)",
X = 15,
Y = 8,
Width = 40,
Height = 12,
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable | ViewArrangement.Overlapped
};
desktop.Add(window1, window2);
Application.Run(desktop);
Application.Shutdown();
```
### Example 4: Custom Arrange Key
```csharp
using Terminal.Gui;
using Terminal.Gui.Configuration;
// Change the arrange key
Application.ArrangeKey = Key.F2;
var window = new Window
{
Title = "Press F2 to enter arrange mode",
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
};
Application.Run(window);
```
---
## Advanced Topics
### Constraints and Limitations
Arrangement only works when:
1. **View has a SuperView** - Root views cannot be arranged
2. **Independent Position/Size** - Views with [Pos.Align](~/api/Terminal.Gui.Pos.yml) or complex [Dim](~/api/Terminal.Gui.Dim.yml) constraints may not resize properly
3. **Border Required** - Mouse-based arrangement requires a visible [Border](~/api/Terminal.Gui.ViewBase.Border.yml)
### SuperViewRendersLineCanvas
When creating splitters, set [View.SuperViewRendersLineCanvas](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_SuperViewRendersLineCanvas) = `true`:
```csharp
rightPane.SuperViewRendersLineCanvas = true;
```
This ensures [LineCanvas](~/api/Terminal.Gui.Drawing.LineCanvas.yml) properly handles line intersections at borders.
### Z-Order Management
For overlapped views, manage Z-order with:
```csharp
// Bring a view to the front
container.BringSubviewToFront(window1);
// Send a view to the back
container.SendSubviewToBack(window2);
// Check current order
int index = container.SubViews.IndexOf(window1);
```
### Arrangement Events
Monitor arrangement changes by handling layout events:
```csharp
view.FrameChanged += (s, e) =>
{
Console.WriteLine($"View moved/resized to {e.NewValue}");
};
view.LayoutComplete += (s, e) =>
{
// Layout has completed after arrangement change
};
```
---
## See Also
- **[Layout Deep Dive](layout.md)** - Overall layout system
- **[View Deep Dive](View.md)** - View base class
- **[Multitasking Deep Dive](multitasking.md)** - Modal and runnable views
- **[Drawing Deep Dive](drawing.md)** - LineCanvas and borders
- **[Configuration Deep Dive](config.md)** - Configuring Application.ArrangeKey
### API Reference
- [View.Arrangement](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_Arrangement)
- [ViewArrangement](~/api/Terminal.Gui.ViewBase.ViewArrangement.yml)
- [Border](~/api/Terminal.Gui.ViewBase.Border.yml)
- [Application.ArrangeKey](~/api/Terminal.Gui.App.Application.yml#Terminal_Gui_App_Application_ArrangeKey)
- [Toplevel.Modal](~/api/Terminal.Gui.Views.Toplevel.yml#Terminal_Gui_Views_Toplevel_Modal)
### UICatalog Examples
The UICatalog application demonstrates arrangement:
- **Arrangement Editor** - Interactive arrangement demonstration
- **Overlapped** scenario - Shows overlapped window management
- **Splitter** examples - Various splitter configurations