# Responsividade

> Como garantir que qualquer layout se adapte a tamanho de tela, densidade e fonte.

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

# Responsividade em todos os layouts

O CrossFly usa **pixels lógicos** e recalcula o layout ao rotacionar/redimensionar. Se você seguir os
princípios abaixo, **a tela se readapta sozinha** — sem código de resize.

> Este é o resumo prático. O guia completo, com exemplo em **cada** layout e um exemplo de tela de
> ponta a ponta, é o Capítulo 36 — Boas Práticas de Layout e Responsividade.

## Os 5 princípios
1. **Nunca posicione em pixels fixos.** Use frações, `Relative` e `LAY_FILL`/`LAY_AUTO` / `RelSize.FILL`.
2. **Deixe o layout medir.** `LAY_AUTO`, `RelSize.AUTOSIZE` e `Relative.AUTO` reportam o tamanho natural.
3. **Espaçamento também escala.** Padding (`ingap`) e margem (`outgap`) via `Gap.ofFont(...)` / `Gap.ofScreen(...)`.
4. **Uma área "elástica".** Marque **um** componente com `LAY_FILL` (Vertical/Horizontal) para absorver a sobra.
5. **Resize é automático** — se você usou os itens acima. Só posicionamento manual (`setBounds`) exige código.

## A ferramenta central: `Relative`
| Forma | Resultado |
|---|---|
| `Relative.ofFont(1.5f)` | 1,5 × altura da fonte (escala com a fonte/DPI) |
| `Relative.ofScreen(0.8f)` | 80% da dimensão da tela |
| `Relative.ofScreen(0.5f, ScreenSize.MIN)` | 50% do **menor** lado (adapta a portrait/landscape) |
| `Relative.FULL` / `AUTO` / `CENTER` | preenche o pai / tamanho de conteúdo / centraliza |

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

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

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   private Component painel;      // reorganizado a cada resize/rotação
   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() é chamado no primeiro layout e a cada resize/rotação:
      // ele escolhe o arranjo do painel conforme a orientação.
   }

   @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);
      }
   }
}
```

> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Quando o arranjo deve MUDAR por orientação
Sobrescreva `Window.onReposition()` (chamado antes do relayout) e reescolha o 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` (o menor lado é estável entre orientações), ex.: `tablet = Screen.minSize >= 600`.

## Veja também
- [Catálogo de layouts](/docs/ui/layouts) · Primitivas: `Relative`/`Gap`
