# Responsiveness

> How to ensure any layout adapts to screen size, density and font.

Source: https://crossfly.dev/docs/ui/layouts/responsiveness — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Responsiveness in every layout

CrossFly uses **logical pixels** and recomputes the layout on rotation/resize. If you follow the
principles below, **the screen re-adapts on its own** — with no resize code.

> This is the practical summary. The complete guide, with an example in **each** layout and an
> end-to-end screen example, is Chapter 36 — Layout and Responsiveness Best Practices.

## The 5 principles
1. **Never position in fixed pixels.** Use fractions, `Relative` and `LAY_FILL`/`LAY_AUTO` / `RelSize.FILL`.
2. **Let the layout measure.** `LAY_AUTO`, `RelSize.AUTOSIZE` and `Relative.AUTO` report the natural size.
3. **Spacing scales too.** Padding (`ingap`) and margin (`outgap`) via `Gap.ofFont(...)` / `Gap.ofScreen(...)`.
4. **One "elastic" area.** Mark **one** component with `LAY_FILL` (Vertical/Horizontal) to absorb the remainder.
5. **Resize is automatic** — if you used the items above. Only manual positioning (`setBounds`) requires code.

## The central tool: `Relative`
| Form | Result |
|---|---|
| `Relative.ofFont(1.5f)` | 1.5 × font height (scales with the font/DPI) |
| `Relative.ofScreen(0.8f)` | 80% of the screen dimension |
| `Relative.ofScreen(0.5f, ScreenSize.MIN)` | 50% of the **smaller** side (adapts to portrait/landscape) |
| `Relative.FULL` / `AUTO` / `CENTER` | fills the parent / content size / centers |

## Full example (copy, paste and run)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   private Component painel;      // rearranged on each resize/rotation
   private Component lista;
   private Component detalhe;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      lista   = new Label("Lista");
      detalhe = new Label("Detalhe");

      painel = new Component();
      setLayout(new VerticalLayout(Position.START, Position.START));
      add(LAY_FILL, painel);
      // onReposition() is called on the first layout and on each resize/rotation:
      // it chooses the panel arrangement according to the orientation.
   }

   @Override
   protected void onReposition() throws Exception
   {
      painel.removeAll();
      if (Screen.isLandscape) {
         painel.setLayout(new HorizontalLayout());
         painel.add(0.5f, lista); painel.add(0.5f, detalhe);
      } else {
         painel.setLayout(new VerticalLayout());
         painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
      }
   }
}
```

> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

## When the arrangement should CHANGE by orientation
Override `Window.onReposition()` (called before the relayout) and re-pick the layout:
```java
@Override protected void onReposition() throws Exception {
   painel.removeAll();
   if (Screen.isLandscape) {
      painel.setLayout(new HorizontalLayout());
      painel.add(0.5f, lista); painel.add(0.5f, detalhe);
   } else {
      painel.setLayout(new VerticalLayout());
      painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
   }
}
```
**Breakpoints:** use `Screen.minSize` (the smaller side is stable across orientations), e.g.: `tablet = Screen.minSize >= 600`.

## See also
- [Layout catalog](/docs/ui/layouts) · Primitives: `Relative`/`Gap`
