# Press and feedback

> Automatic press animation via pressable() and manual control of a component's alpha.

Source: https://crossfly.dev/docs/ui/animations/press-and-feedback — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Press and feedback

The visual response to touch (the "sinking" of a button) is **automatic** in CrossFly when the style is
marked as pressable — you write no animation at all.

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // ComponentStyle

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

      // Automatic press feedback: custom style with .pressable()
      Button botao = new Button("Enviar");
      botao.style(new ComponentStyle().backColor(0xFF0173ED).pressable());
      add(LAY_AUTO, botao);

      // Manual opacity control to represent state (selected/disabled)
      Label item = new Label("Item");
      add(LAY_AUTO, item);
      boolean selecionado = false;
      item.alpha(selecionado ? 1f : 0.5f);
      Component.repaint();

      // Toggles the state with feedback: on tap, highlights the item back to opaque
      botao.onAction(c -> { item.alpha(1f); Component.repaint(); });
   }
}
```
> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

## Automatic press feedback — `pressable()`
Mark the style as `pressable()` and the component animates itself when touched (using the theme's
`animationDuration`):
```java
Button b = new Button("Enviar");
b.style(Styles.button());   // the Skin's button style already comes .pressable()

// in a custom style, enable it explicitly:
b.style(new ComponentStyle().backColor(0xFF0173ED).pressable());
```
The `Skin` generates the `pressed` state from the normal one (by default, a darker background). To customize it,
define a `pressedStyle(...)` (see [Styling components](/docs/ui/theming/styling-components)).

## Feedback duration
Comes from `Styles.animationDuration` (default `0.3s`) and is read by the `Skin` styles. Global adjustment:
```java
Styles.animationDuration = 0.2f;   // more "crisp" tap across the whole app
```

## Manual opacity control — `alpha(...)`
To fade/highlight a component on your own (e.g., visually disable, emphasize a
selection), use `alpha(float)` (0 = transparent, 1 = opaque):
```java
item.alpha(selecionado ? 1f : 0.5f);
Component.repaint();
```
For a **smooth** opacity transition, combine it with [`AlphaAnimation`](/docs/ui/animations/value-animations):
```java
AlphaAnimation fade = new AlphaAnimation(item.alpha(), 1f, 0.2f);
fade.onUpdate(() -> { item.alpha(fade.getValue()); Component.repaint(); }).start();
```

## Best practices
- Let `pressable()` handle the touch feedback — don't animate the press by hand.
- Use `alpha()` for state (disabled/selected); animate only when the transition adds value.
- A **disabled** component already fades via the style's `disabledAlpha` — don't duplicate it.

## Common mistakes
- Custom style without `pressable()` → button with no feedback on touch.
- Setting `alpha(...)` and forgetting `Component.repaint()` (on-demand rendering).

## See also
- [Value animations](/docs/ui/animations/value-animations) · [Styling components](/docs/ui/theming/styling-components)
