# Desenho customizado

> Sobrescrever onPaint(Paint) e usar as primitivas — rect (GRect), text, line, image.

Source: https://crossfly.dev/pt/docs/ui/images-and-graphics/custom-drawing — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Desenho customizado (`onPaint`)

Quando nenhum widget serve, crie um `Component` e sobrescreva **`onPaint(Paint paint)`**. As
coordenadas são **locais** (0,0 = canto superior esquerdo; `width`/`height` são o tamanho do
componente).

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.graphics.*;    // Paint, GRect, Font
import dev.crossfly.ui.style.*;       // Styles

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   /** Componente custom: desenha um "badge" (pílula colorida com um número). */
   static class Badge extends Component
   {
      private int valor;

      Badge(int valor) { this.valor = valor; }

      @Override
      public void onPaint(Paint paint) throws Exception
      {
         // Coordenadas LOCAIS: (0,0) = topo-esquerda; width/height = tamanho do componente.
         GRect r = new GRect()
            .bounds(0, 0, width, height)
            .fill(0xFFE53935)          // vermelho ARGB
            .radius(height / 2);       // pílula / círculo
         paint.rect(r);

         Font f = Styles.font;
         String s = String.valueOf(valor);
         int tx = (width - (int) f.width(s)) / 2;
         int ty = (height - f.scaledHeight()) / 2;
         paint.text(s, tx, ty, 0xFFFFFFFF, f);   // texto branco centralizado
      }
   }

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());
      Badge badge = new Badge(7);
      add(LAY_AUTO, badge);   // adiciona o componente custom à tela
   }
}
```
> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Esqueleto
```java
public class Badge extends Component {
   private int valor;
   public Badge(int valor) { this.valor = valor; }

   @Override public void onPaint(Paint paint) throws Exception {
      // fundo redondo preenchido
      GRect r = new GRect()
         .bounds(0, 0, width, height)
         .fill(0xFFE53935)               // vermelho
         .radius(height / 2);            // pílula/círculo
      paint.rect(r);

      // texto centralizado
      Font f = Styles.font;
      String s = String.valueOf(valor);
      int tx = (width - (int) f.width(s)) / 2;
      int ty = (height - f.scaledHeight()) / 2;
      paint.text(s, tx, ty, 0xFFFFFFFF, f);
   }
}
// para redesenhar após mudar 'valor': repaint();
```

## Primitivas do `Paint`
| Chamada | Desenha |
|---|---|
| `paint.rect(GRect r)` | retângulo (preenchido/borda/cantos/sombra) — configure o `GRect` |
| `paint.text(String, x, y, color, Font)` | texto |
| `paint.line(x1, y1, x2, y2, color, thick)` | linha |
| `paint.image(Image, x, y[, w, h])` | imagem |
| `paint.polyline(GLines)` / `paint.polygon(GLines)` | polilinha / polígono |

## `GRect` — o retângulo configurável
Fluent: `.bounds(x,y,w,h)` · `.fill(color)` · `.border(color, thick)` · `.radius(r)` /
`.radius(tl,tr,br,bl)`. Depois `paint.rect(gr)`.
```java
GRect card = new GRect().bounds(0, 0, width, height)
   .fill(0xFFFFFFFF).border(0xFFE0E0E0, 1).radius(8);
paint.rect(card);
```

## Boas práticas
- Desenhe **relativo a `width`/`height`** (não valores fixos) — mantém responsivo.
- Reaproveite objetos `GRect`/`Font` (campos) em vez de alocar por frame.
- Chame `repaint()` quando o estado que afeta o desenho mudar (render é sob demanda).

## Erros comuns
- Usar coordenadas absolutas de tela no `onPaint` — elas são **locais** ao componente.
- Esquecer `repaint()` após mudar o dado desenhado.
- Passar cor como objeto — cores são `int` ARGB (a classe `Color` não existe).

## Veja também
- [Imagens](/docs/ui/images-and-graphics/images) · [Whiteboard](/docs/ui/images-and-graphics/whiteboard) · [Cores](/docs/ui/theming/color-schemes)
