# Toque y feedback

> Animación de presión automática vía pressable() y control manual de alpha del componente.

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

# Toque y feedback

La respuesta visual al toque (el "hundirse" de un botón) es **automática** en CrossFly cuando el estilo está
marcado como presionable — no escribes ninguna animación.

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // Feedback automático de pulsación: estilo custom con .pressable()
      Button botao = new Button("Enviar");
      botao.style(new ComponentStyle().backColor(0xFF0173ED).pressable());
      add(LAY_AUTO, botao);

      // Control manual de opacidad para representar estado (seleccionado/deshabilitado)
      Label item = new Label("Item");
      add(LAY_AUTO, item);
      boolean selecionado = false;
      item.alpha(selecionado ? 1f : 0.5f);
      Component.repaint();

      // Alterna el estado con feedback: al tocar, resalta el ítem volviéndolo a opaco
      botao.onAction(c -> { item.alpha(1f); Component.repaint(); });
   }
}
```
> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` de arriba.

## Feedback automático de presión — `pressable()`
Marca el estilo como `pressable()` y el componente se anima solo al ser tocado (usando la
`animationDuration` del tema):
```java
Button b = new Button("Enviar");
b.style(Styles.button());   // el estilo de botón del Skin ya viene con .pressable()

// en un estilo custom, habilítalo explícitamente:
b.style(new ComponentStyle().backColor(0xFF0173ED).pressable());
```
El `Skin` genera el estado `pressed` a partir del normal (por defecto, fondo más oscuro). Para personalizar,
define un `pressedStyle(...)` (ver [Estilizar componentes](/docs/ui/theming/styling-components)).

## Duración del feedback
Viene de `Styles.animationDuration` (por defecto `0.3s`) y es leída por los estilos del `Skin`. Ajuste global:
```java
Styles.animationDuration = 0.2f;   // toque más "seco" en toda la app
```

## Control manual de opacidad — `alpha(...)`
Para atenuar/resaltar un componente por tu cuenta (ej.: deshabilitar visualmente, destacar
selección), usa `alpha(float)` (0 = transparente, 1 = opaco):
```java
item.alpha(selecionado ? 1f : 0.5f);
Component.repaint();
```
Para una transición **suave** de opacidad, combínalo con [`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();
```

## Buenas prácticas
- Deja que `pressable()` se encargue del feedback de toque — no animes la presión a mano.
- Usa `alpha()` para estado (deshabilitado/seleccionado); anima solo cuando la transición aporte.
- Un componente **deshabilitado** ya se atenúa por el `disabledAlpha` del estilo — no lo dupliques.

## Errores comunes
- Estilo custom sin `pressable()` → botón sin feedback al toque.
- Setear `alpha(...)` y olvidar `Component.repaint()` (render bajo demanda).

## Véase también
- [Animaciones de valor](/docs/ui/animations/value-animations) · [Estilizar componentes](/docs/ui/theming/styling-components)
