# Progress

> Indicador de progresso — barra determinada, animação infinita ou ícone girando.

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

# Progress

`Progress` é um indicador de progresso com **três modos** mutuamente exclusivos, escolhidos no construtor (o campo `mode` é `final`): barra determinada (porcentagem conhecida), animação indeterminada infinita, ou ícone girando em loop. As animações iniciam ao ser adicionado (`onAdd`, exceto sob teste) e param ao ser removido (`onRemove`).

> 🟢 · **Pacote:** `dev.crossfly.ui` · **Estende:** `Component` · **Estilo:** `ProgressStyle`

## Quando usar
- **`DETERMINATE_BAR`**: quando há uma porcentagem/valor conhecido a mostrar.
- **`INDETERMINATE`** / **`SPINNING_ICON`**: quando a duração é desconhecida (carregando…).

## Quando NÃO usar
- Para o usuário **escolher** um valor arrastando → use [`slider`](/docs/ui/widgets/slider).

## Aparência
Depende do modo (`Progress.Mode`) e, no indeterminado, do `ProgressType`:

| `ProgressType` | Visual |
|---|---|
| `IOS` | spinner circular (estilo iOS) |
| `FLUTTER` | indicador circular (timing easeInOut) |
| `MATERIAL` | barra linear Material (wrap contínuo) |
| `STRIPED` | barra listrada animada |

A barra é **só horizontal**; a altura é `max(fontHeight * barHeight, 4)`. As cores vêm de `filledColor`/`emptyColor` do `ProgressStyle`.

## 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.progress()
import dev.crossfly.ui.graphics.*;   // MaterialIcon

/** 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());

      // 1) Barra determinada (0..100) preenchida em 75%
      Progress barra = new Progress(0f, 100f);
      barra.setValue(75f);
      barra.style(Styles.progress().barHeight(1.5f));
      add(LAY_AUTO, barra);

      // 2) Barra indeterminada (Material) — anima sozinha ao ser adicionada
      Progress material = new Progress(ProgressType.MATERIAL);
      material.style(Styles.progress().barHeight(1.5f));
      add(LAY_AUTO, material);

      // 3) Ícone girando em loop
      Progress spinner = new Progress(new MaterialIcon("autorenew", 48));
      add(LAY_AUTO, spinner);
   }
}
```

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

## Uso básico
```java
Progress barra = new Progress(0f, 100f);                // modo DETERMINATE_BAR
barra.setValue(75f);                                    // 75%
barra.style(Styles.progress().barHeight(1.5f));
container.add(0f, barra);
```

## Construtores
| Construtor | Modo | Descrição |
|---|---|---|
| `Progress(float min, float max)` | `DETERMINATE_BAR` | Barra proporcional a `value` (inicia em `min`). |
| `Progress(ProgressType type)` | `INDETERMINATE` | Animação infinita (Material/Flutter/iOS/Striped). |
| `Progress(Icon icon)` | `SPINNING_ICON` | Gira um ícone em loop contínuo. |

## Propriedades e personalização
| Propriedade / método | Tipo | Padrão | O que faz |
|---|---|---|---|
| `setValue(float)` | `Progress` (fluente) | — | **Modo barra**: define o valor (com `clamp`) e recalcula `progress`. |
| `mode` | `Progress.Mode` (campo, `final`) | ctor | Modo de operação (leitura). |
| `value` / `min` / `max` | `float` (campo) | ctor | Estado da barra determinada. |
| `progress` | `float` (campo) | — | Progresso normalizado `[0,1]` (barra). |
| `pivot(int, int)` | `Progress` (fluente) | `-1,-1` | **Modo ícone**: pivô de rotação (`-1,-1` = auto-centro). |

## Callbacks e eventos
`Progress` é **não interativo**: não expõe callbacks. Atualize a barra chamando `setValue(...)` conforme o trabalho avança.

## Estados
- **DETERMINATE_BAR**: `setValue(v)` faz `clamp` em `[min,max]`, `progress = (value-min)/(max-min)` e `filledW = barW * progress`.
- **INDETERMINATE / SPINNING_ICON**: `LoopAnimation` contínua iniciada em `onAdd`, parada em `onRemove`.

### Os três modos
```java
// Barra determinada 0..50 com 35 preenchido
Progress bar = new Progress(0f, 50f);
bar.setValue(35f);
bar.style(Styles.progress().barHeight(1.5f));
container.add(0f, bar);

// Barra indeterminada (Material)
Progress material = new Progress(ProgressType.MATERIAL);
material.style(Styles.progress().barHeight(1.5f));
container.add(0f, material);

// Ícone girando
Progress spinner = new Progress(new MaterialIcon("autorenew", 48));
container.add(0f, spinner);
```

## Boas práticas
- Use `DETERMINATE_BAR` sempre que souber a porcentagem; reserve o indeterminado para durações desconhecidas.
- Customize cores via `filledColor`/`emptyColor` do estilo em vez de subclassificar.

## Erros comuns
- Chamar `setValue` em modo indeterminado/spinner: não tem efeito visual útil (o valor só importa em `DETERMINATE_BAR`).
- Esperar barra vertical ou texto de porcentagem embutido: a barra é só horizontal e sem rótulo prefix/suffix.

## Veja também
- Guia da área: [`ui/`](/docs/ui) · Receitas: [`cookbook/`](/docs/cookbook)
- Conceito (animação e ciclo de vida): [`concepts/`](/docs/concepts)
- Componentes relacionados: [`slider`](/docs/ui/widgets/slider)
