# Espaçamento (Gap)

> Como espaçar componentes sem Spacer — usando Gap, ingap/outgap e frações de layout.

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

# Espaçamento (Gap)

> ⚠️ **`Spacer` foi removido** na modernização 2026. Não há mais um widget de espaçamento. Para separar componentes use, em ordem de preferência: **frações de layout** (`LAY_AUTO`/`LAY_FILL`/fração), **`ingap`/`outgap`** dos componentes, ou o valor `Gap` diretamente.

`Gap` representa valores de espaçamento (esquerda, topo, direita, baixo) com escala opcional. É usado em toda a UI como **padding** (`ingap`), **margin** (`outgap`), e como espaçamento interno de layouts. Um `Gap` pode ser:

- **pixels fixos** — `Gap.ofPixels(...)`
- **relativo à fonte** — `Gap.ofFont(...)` (escala com `font.scaledHeight()`, ideal para responsividade)
- **relativo à tela** — `Gap.ofScreen(...)` (percentual das dimensões da tela)

> 🟢 · **Pacote:** `dev.crossfly.ui` · **Estende:** `Component` · **Relacionado:** `ComponentStyle.ingap`/`outgap`, layouts

## Quando usar
- Definir padding interno de um componente (`ingap`) ou margem externa (`outgap`).
- Passar espaçamento a um layout (ex.: gaps entre células).
- Substituir o antigo `Spacer` por espaço proporcional.

## Quando NÃO usar
- Para "empurrar" um componente e absorver a sobra → use uma linha `LAY_FILL` no `VerticalLayout`/`HorizontalLayout` (ver [`layouts/`](/docs/ui)), não um `Gap` fixo.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // Styles, ButtonRole, State

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Cabeçalho com altura natural
      add(LAY_AUTO, new Label("Cabeçalho"));

      // Botão afastado dos vizinhos via outgap (margem relativa à fonte)
      Button b = new Button("Enviar").style(
         Styles.theme().button(ButtonRole.PRIMARY, State.NORMAL)
            .pressable()
            .outgap(Gap.ofFont(0.5f)));   // 0.5 × altura da fonte em todos os lados
      add(LAY_AUTO, b);

      // Rodapé empurrado para baixo: a linha LAY_FILL absorve a sobra vertical
      add(LAY_FILL, new Label("(espaço que sobra)"));
      add(LAY_AUTO, new Label("Rodapé"));
   }
}
```

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

### 1. Frações de layout (preferido)
```java
VerticalLayout col = new VerticalLayout();
col.add(LAY_AUTO, cabecalho);   // altura natural
col.add(LAY_FILL, conteudo);    // absorve a sobra (empurra o rodapé p/ baixo)
col.add(LAY_AUTO, rodape);
```

### 2. `ingap` / `outgap` no estilo
```java
// Margem externa (afasta este componente dos vizinhos) via outgap relativo à fonte
Button b = new Button("Enviar").style(
   Styles.theme().button(ButtonRole.PRIMARY, State.NORMAL)
      .pressable()
      .outgap(Gap.ofFont(0.5f)));   // 0.5 × altura da fonte em todos os lados
container.add(LAY_AUTO, b);
```

### 3. `Gap` como padding interno
```java
Label card = new Label("Conteúdo do cartão").style(
   Styles.theme().label(LabelRole.BODY)
      .ingap(Gap.ofFont(1f, 0.5f, 1f, 0.5f)));  // L,T,R,B em unidades de fonte
container.add(LAY_AUTO, card);
```

## Fábricas (`Gap`)
| Fábrica | Escala | Uso |
|---|---|---|
| `Gap.ofPixels(float all)` / `ofPixels(l, t, r, b)` | pixels fixos | valores absolutos |
| `Gap.ofFont(float all)` / `ofFont(l, t, r, b)` | × altura da fonte padrão | **responsivo** (recomendado) |
| `Gap.ofFont(Font, l, t, r, b)` | × altura da fonte informada | rebaseado a uma fonte específica |
| `Gap.ofScreen(float all)` / `ofScreen(l, t, r, b)` | % das dimensões da tela | espaçamento proporcional à tela |
| `Gap.none()` / `Gap.ZERO` | zero | sem espaçamento |

## Propriedades e métodos
| Método | Tipo | O que faz |
|---|---|---|
| `left()` / `top()` / `right()` / `bottom()` | `int` | valor resolvido em pixels (já aplica a escala) |
| `width()` / `height()` | `int` | soma horizontal (`left+right`) / vertical (`top+bottom`) em pixels |
| `withFont(Font)` | `Gap` | rebaseia os fatores para outra fonte (se for font-relative) |
| `isFontRelative()` / `font()` | `boolean` / `Font` | consulta a base de escala |

## Boas práticas
- Para o "espaço que sobra", use **uma única** linha `LAY_FILL` no layout, não vários gaps.
- Reaproveite `Gap.ZERO` para zerar padding sem alocar objetos.

## Erros comuns
- **Procurar a classe `Spacer`:** ela não existe mais. Use frações de layout / `Gap` / `ingap`/`outgap`.
- **Usar `Gap.ofPixels` para tudo:** em telas de densidades diferentes o espaçamento fica inconsistente; prefira `ofFont`/`ofScreen`.
- **Tentar centralizar com dois gaps fixos:** use o alinhamento do layout ou `LAY_FILL` dos dois lados.

## Veja também
- Guia da área: [`ui/`](/docs/ui) · Receitas: [`cookbook/`](/docs/cookbook)
- Conceito (constraints, responsividade): [`concepts/`](/docs/concepts)
- Componentes relacionados: [`Label`](/docs/ui/widgets/label) · [`Button`](/docs/ui/widgets/button)
