Formularios de configuración

El formulario previo a la ejecución que declara un script: campos de número, texto, casilla, selección, color, pincel y paleta.

Un script puede declarar un pequeño formulario que se muestra antes de ejecutarlo. Lo que el usuario rellena llega como la tabla app.config, con la clave de cada campo como id. Los campos son datos simples (un script nunca describe la interfaz) y el editor los dibuja y los valida. Los colores, los pinceles y las paletas son la forma en que un script pide algo de lo que es del usuario: el motor nunca lee sus bibliotecas, así que el script recibe exactamente lo que el usuario elige.

  • number — Un campo numérico. En Lua: number. Opciones: default (El valor inicial.); min (El valor mínimo permitido.); max (El valor máximo permitido.); optional (Permite dejarlo vacío.); randomMin / randomMax (El rango del que elige Aleatorio, dentro de min..max (por omisión min..max; si falta alguno de los dos límites, Aleatorio no lo toca). Números enteros si los límites y el valor predeterminado lo son.); randomize (false conserva el valor cuando el usuario aleatoriza el formulario.).
  • text — Una línea de texto. En Lua: string. Opciones: default (El texto inicial.); optional (Permite dejarlo vacío.).
  • checkbox — Un interruptor de activado/desactivado. En Lua: boolean. Opciones: default (Si empieza marcada.); randomize (false conserva el valor cuando el usuario aleatoriza el formulario.).
  • select — Una opción de una lista fija. En Lua: string (el valor de la opción elegida). Opciones: options (Las opciones, cada una { value, label }.); default (El valor seleccionado al inicio.); randomize (false conserva la opción cuando el usuario aleatoriza el formulario.).
  • color — Un color, elegido con el selector de color del editor, con la paleta del sprite y los colores recientes a un clic. Da a cada papel su propio campo (hoja clara, hoja oscura, corteza...) y el usuario los elige todos. En Lua: string, "#rrggbb" (o "#rrggbbaa" con alfa); se acepta directamente en cualquier lugar donde vaya un color. Opciones: default (El color inicial, "#rrggbb" o "#rrggbbaa" (negro si se omite).); randomize (true permite que Aleatorio también elija un color (conserva el alfa). Desactivado por omisión: los colores de la mayoría de los scripts están ajustados a mano.).
  • brush — Uno de los pinceles guardados del usuario, elegido en su biblioteca de pinceles. En Lua: tabla { name, width, height, mask }; pásala a app.defineBrush; ausente si es opcional y se deja vacío. Opciones: optional (Permite dejarlo vacío (entonces app.config.<id> es nil).).
  • palette — Una de las paletas guardadas del usuario, elegida en su biblioteca de paletas. En Lua: lista de cadenas "#rrggbb" (o "#rrggbbaa"); pásala a app.setPalette, o elige de ella con matemática de colores; ausente si es opcional y se deja vacío. Opciones: optional (Permite dejarlo vacío (entonces app.config.<id> es nil).).

Ejemplo de formulario (JSON) y del script que lo usa:

{
  "fields": [
    {
      "id": "leafLight",
      "type": "color",
      "label": "Leaf (light)",
      "default": "#6cc24a"
    },
    {
      "id": "leafMid",
      "type": "color",
      "label": "Leaf (mid)",
      "default": "#3a8f4a"
    },
    {
      "id": "leafDark",
      "type": "color",
      "label": "Leaf (dark)",
      "default": "#23603a"
    },
    {
      "id": "barkLight",
      "type": "color",
      "label": "Bark (light)",
      "default": "#8a5a35"
    },
    {
      "id": "barkDark",
      "type": "color",
      "label": "Bark (dark)",
      "default": "#5a3a22"
    },
    {
      "id": "stamp",
      "type": "brush",
      "label": "Leaf brush",
      "optional": true
    }
  ]
}
local layer, frame = app.getActiveLayerId(), app.getActiveFrameId()
local c = app.config

-- trunk: two bark colors the user chose
app.drawRectangle(layer, frame, 14, 20, 17, 31, { color = c.barkDark, fill = "filled" })
app.drawRectangle(layer, frame, 14, 20, 15, 31, { color = c.barkLight, fill = "filled" })

-- canopy: three leaf colors, with the user's own brush if they picked one
if c.stamp then app.defineBrush("leaf", c.stamp) end
for i, color in ipairs({ c.leafDark, c.leafMid, c.leafLight }) do
  app.drawStroke(layer, frame, { { 8, 18 - i * 4 }, { 24, 18 - i * 4 } },
    { color = color, brush = c.stamp and "leaf" or nil, brushSize = 4 })
end

Ramificación

Cualquier campo puede llevar un when — { "<earlier field id>": [values] } — y entonces solo se muestra mientras cada select nombrado tenga uno de esos valores de opción (o cada checkbox sea true/false) y ese select o checkbox esté a su vez visible. Las condiciones solo miran los select y checkbox anteriores, así que se encadenan a cualquier profundidad: cambia la raíz y toda su rama se oculta. Un campo oculto no aparece en app.config, así que el script recurre a su propio valor predeterminado: lee todos los campos como opcionales.

{
  "fields": [
    {
      "id": "kind",
      "type": "select",
      "label": "Kind",
      "options": [
        {
          "value": "broadleaf",
          "label": "Broadleaf"
        },
        {
          "value": "conifer",
          "label": "Conifer"
        }
      ],
      "default": "broadleaf"
    },
    {
      "id": "crown",
      "type": "select",
      "label": "Crown",
      "options": [
        {
          "value": "round",
          "label": "Round"
        },
        {
          "value": "weeping",
          "label": "Weeping"
        }
      ],
      "when": {
        "kind": [
          "broadleaf"
        ]
      }
    },
    {
      "id": "droop",
      "type": "number",
      "label": "Droop",
      "min": 0,
      "max": 100,
      "randomMin": 20,
      "randomMax": 80,
      "when": {
        "crown": [
          "weeping"
        ]
      }
    },
    {
      "id": "tiers",
      "type": "number",
      "label": "Tiers",
      "min": 2,
      "max": 12,
      "when": {
        "kind": [
          "conifer"
        ]
      }
    },
    {
      "id": "newLayer",
      "type": "checkbox",
      "label": "Draw on a new layer",
      "randomize": false
    }
  ]
}

Aleatorio

Todos los formularios tienen un botón Aleatorio. Cada número se sortea dentro de randomMin..randomMax (por omisión min..max; un número sin ambos límites se conserva), elige cualquier opción de un select e invierte las casillas; los colores solo se sortean con randomize: true, y el texto, los pinceles y las paletas nunca se tocan. Establece randomMin/randomMax al rango que sigue viéndose bien, y randomize: false en los ajustes que no tienen que ver con el arte (capa nueva, respetar la selección...).

En Markdown: config-forms.md.