# ColorPicker

> Color selection via a hue×saturation matrix + brightness slider.

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

# ColorPicker

`ColorPicker` selects a **color** through a 2-D hue×saturation matrix plus a brightness slider. It follows the picker pattern (see [`Picker`](/docs/ui/widgets/picker)) and returns an ARGB `Integer` **without an alpha channel**.

> 🟡 · **Package:** `dev.crossfly.ui.picker` · **Extends:** `Picker` · **Selection:** internal `ColorMatrix`

## When to use
- Let the user choose a color (theme, accent, label).

## Appearance
An 80%×80% window with the hue×saturation matrix filling the body, a brightness slider, and the **Cancel** and **Select** buttons (Select shows the hex and is painted with the chosen color itself).

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

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

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button abrir = new Button("Escolher cor");
      // Uses the chosen color itself as the button background
      abrir.onAction(c ->
      {
         ColorPicker cp = new ColorPicker(0xFF3366CC);
         cp.show(answer ->
         {
            int argb = 0xFF000000 | (Integer) answer;  // adds alpha (color without alpha)
            abrir.style(abrir.getStyle().copy().backColor(argb));
         });
      });
      add(LAY_AUTO, abrir);
   }
}
```

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

## Basic usage
```java
ColorPicker cp = new ColorPicker(0xFF3366CC);
cp.show(answer ->
{
   int rgb = (Integer) answer;    // 0x00RRGGBB (no alpha)
   int argb = 0xFF000000 | rgb;   // add alpha to use it as an opaque color
   botao.style(botao.getStyle().copy().backColor(argb));
});
```

## Constructors
| Constructor | Description |
|---|---|
| `ColorPicker(int defaultColor)` | Initial ARGB color shown on opening. |

## Properties and customization
| Member | Type | What it does |
|---|---|---|
| `choosenColor` | `int` (public) | Current color (RGB without alpha); `-1` if canceled. |
| `ColorPicker.selectStr` (static) | `String` | Prefix of the Select button label (`"Select color "`). |

## Callbacks and events
| Callback | When it fires |
|---|---|
| `show(onAnswer)` | on confirming (Select), delivers the `Integer` (RGB without alpha). |

## Result (important)
`getAnswer()` returns `Integer` (RGB color **without alpha**, masked with `& 0x00FFFFFF`), or `null` if canceled. The type is `Integer` (not `int`) precisely so it can be `null`.

> ⚠️ **The color has no alpha channel.** Apply `0xFF000000 |` if you need an opaque color.

## States
- **Select** → `answer = choosenColor` and closes.
- **Cancel** → `answer = null`, `choosenColor = -1` and closes (the `onAnswer` does **not** fire).

### Use the chosen color as a button's background
```java
ColorPicker cp = new ColorPicker(0xFF3366CC);
cp.show(answer ->
{
   int argb = 0xFF000000 | (Integer) answer;
   botao.style(botao.getStyle().copy().backColor(argb));
});
```

## Best practices
- Remember to **add alpha** (`0xFF000000 |`) when using the result as an opaque color.
- Cast to `Integer` (not `int`) so as not to lose the `null` semantics on cancellation.

## Common mistakes
- **Using the result without alpha** — it comes out transparent (`0x00RRGGBB`).
- **Expecting `onAnswer` on cancellation** — it does not fire (`answer = null`).

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Pattern base: [`Picker`](/docs/ui/widgets/picker)
