xonecode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -0
- package/dist/agent/authEnDisco.js +56 -0
- package/dist/agent/authEnDisco.js.map +1 -0
- package/dist/agent/configEnDisco.js +109 -0
- package/dist/agent/configEnDisco.js.map +1 -0
- package/dist/agent/crearProyecto.js +34 -0
- package/dist/agent/crearProyecto.js.map +1 -0
- package/dist/agent/entorno.js +124 -0
- package/dist/agent/entorno.js.map +1 -0
- package/dist/agent/guionizado.js +53 -0
- package/dist/agent/guionizado.js.map +1 -0
- package/dist/agent/instantanea.js +129 -0
- package/dist/agent/instantanea.js.map +1 -0
- package/dist/agent/interrupts.js +83 -0
- package/dist/agent/interrupts.js.map +1 -0
- package/dist/agent/mensajes.js +24 -0
- package/dist/agent/mensajes.js.map +1 -0
- package/dist/agent/modelos.js +42 -0
- package/dist/agent/modelos.js.map +1 -0
- package/dist/agent/normalizar.js +20 -0
- package/dist/agent/normalizar.js.map +1 -0
- package/dist/agent/perfiles.js +103 -0
- package/dist/agent/perfiles.js.map +1 -0
- package/dist/agent/proyecto.js +107 -0
- package/dist/agent/proyecto.js.map +1 -0
- package/dist/agent/puente.js +142 -0
- package/dist/agent/puente.js.map +1 -0
- package/dist/agent/resumenDeTool.js +48 -0
- package/dist/agent/resumenDeTool.js.map +1 -0
- package/dist/agent/skills.js +65 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/textoDeTool.js +113 -0
- package/dist/agent/textoDeTool.js.map +1 -0
- package/dist/agent/turnoReal.js +173 -0
- package/dist/agent/turnoReal.js.map +1 -0
- package/dist/agent/verificador.js +65 -0
- package/dist/agent/verificador.js.map +1 -0
- package/dist/agent/xoneAgent.js +106 -0
- package/dist/agent/xoneAgent.js.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/aprobar.js +82 -0
- package/dist/cli/aprobar.js.map +1 -0
- package/dist/cli/config.js +133 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/consola.js +346 -0
- package/dist/cli/consola.js.map +1 -0
- package/dist/cli/describe.js +53 -0
- package/dist/cli/describe.js.map +1 -0
- package/dist/cli/doctor.js +45 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/main.js +520 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/markdown.js +90 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/run.js +164 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/spinner.js +89 -0
- package/dist/cli/spinner.js.map +1 -0
- package/dist/cli/stdio.js +193 -0
- package/dist/cli/stdio.js.map +1 -0
- package/dist/cli/tema.js +40 -0
- package/dist/cli/tema.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/core/bitacora.js +30 -0
- package/dist/core/bitacora.js.map +1 -0
- package/dist/core/config.js +236 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contextos.js +56 -0
- package/dist/core/contextos.js.map +1 -0
- package/dist/core/deps.js +51 -0
- package/dist/core/deps.js.map +1 -0
- package/dist/core/diff.js +79 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/esqueleto.js +366 -0
- package/dist/core/esqueleto.js.map +1 -0
- package/dist/core/events.js +2 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/modelos.js +85 -0
- package/dist/core/modelos.js.map +1 -0
- package/dist/core/notify.js +106 -0
- package/dist/core/notify.js.map +1 -0
- package/dist/core/ports.js +114 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/turno.js +127 -0
- package/dist/core/turno.js.map +1 -0
- package/dist/vendor/hitl.js +103 -0
- package/dist/vendor/hitl.js.map +1 -0
- package/dist/vendor/skillLoaders/catalog.js +74 -0
- package/dist/vendor/skillLoaders/catalog.js.map +1 -0
- package/dist/vendor/tokenTracking.js +58 -0
- package/dist/vendor/tokenTracking.js.map +1 -0
- package/package.json +41 -0
- package/skills/xone-debugging/SKILL.md +52 -0
- package/skills/xone-debugging/references/faq.md +561 -0
- package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
- package/skills/xone-development/SKILL.md +105 -0
- package/skills/xone-development/references/anti-patrones.md +94 -0
- package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
- package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
- package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
- package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
- package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
- package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
- package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
- package/skills/xone-development/references/datos/appdata.md +611 -0
- package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
- package/skills/xone-development/references/datos/http.md +366 -0
- package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
- package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
- package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
- package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
- package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
- package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
- package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
- package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
- package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
- package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
- package/skills/xone-development/references/indice-completo.md +77 -0
- package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
- package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
- package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
- package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
- package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
- package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
- package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
- package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
- package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
- package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
- package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
- package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
- package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
- package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
- package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
- package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
- package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
- package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
- package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
- package/skills/xone-development/references/tipos-de-prop.md +28 -0
- package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
- package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
- package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
- package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
- package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
- package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
- package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
- package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
- package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
- package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
- package/skills/xone-development/references/xml-ui/mapas.md +685 -0
- package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
- package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
- package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
- package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
- package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
- package/skills/xone-plan-builder/SKILL.md +183 -0
- package/skills/xone-plan-builder/agents/openai.yaml +5 -0
- package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
- package/skills/xone-project-generator/SKILL.md +111 -0
- package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
- package/skills/xone-project-generator/references/colecciones-base.md +16 -0
- package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
- package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
- package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
- package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
- package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
- package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
- package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
- package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
- package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
- package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
- package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
- package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
- package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
- package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
- package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
- package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
- package/skills/xone-review/SKILL.md +189 -0
- package/skills/xone-spec-builder/SKILL.md +235 -0
- package/skills/xone-spec-builder/agents/openai.yaml +5 -0
- package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
- package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
- package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
# XOne XML — Props por tipo: texto, número, label, botón, fecha, imagen
|
|
2
|
+
|
|
3
|
+
> Fuente: `xone/v2/xone-help-docs/topics/02b-xml-prop-tipos.md` §5.9.1–§5.9.10. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
|
|
4
|
+
|
|
5
|
+
Contenido: §5.9.1 texto T · §5.9.2 label L/TL · §5.9.3 numérico N y TN · §5.9.4 botón B · §5.9.5 checkbox NC · §5.9.6 fecha y hora D/DT/TT · §5.9.8 imagen IMG · §5.9.9 foto PH · §5.9.10 vídeo VD y escáner QR
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
#### 5.9.1 Texto (T)
|
|
10
|
+
|
|
11
|
+
Campo de texto editable. El control más básico de XOne.
|
|
12
|
+
|
|
13
|
+
```xml
|
|
14
|
+
<!-- Texto simple -->
|
|
15
|
+
<prop name="NOMBRE" type="T" visible="7"
|
|
16
|
+
title="Nombre Completo"
|
|
17
|
+
size="100" width="100%"
|
|
18
|
+
tooltip="Ingrese su nombre" />
|
|
19
|
+
|
|
20
|
+
<!-- Texto multilinea -->
|
|
21
|
+
<prop name="MAP_TEXTAREA" type="T" visible="1"
|
|
22
|
+
title="Descripción"
|
|
23
|
+
class="classTMultiline"
|
|
24
|
+
lines="5" fixed-lines="true" />
|
|
25
|
+
|
|
26
|
+
<!-- Texto con tooltip flotante -->
|
|
27
|
+
<prop name="MAP_USUARIO" type="T" visible="1"
|
|
28
|
+
floating-tooltip="true"
|
|
29
|
+
tooltip="Usuario"
|
|
30
|
+
tmargin="94p"
|
|
31
|
+
class="xnTextoEditable" />
|
|
32
|
+
|
|
33
|
+
<!-- Texto con teclado personalizado -->
|
|
34
|
+
<prop name="MAP_TEXT" type="T" visible="1"
|
|
35
|
+
title="Texto"
|
|
36
|
+
fixed-lines="true"
|
|
37
|
+
keyboard-bar="false"
|
|
38
|
+
show-keyboard="false" />
|
|
39
|
+
|
|
40
|
+
<!-- Texto con evento de cambio en tiempo real -->
|
|
41
|
+
<prop name="MAP_BUSCAR" type="T" visible="1"
|
|
42
|
+
ontextchanged="javascript:buscarTexto(e);"
|
|
43
|
+
labelwidth="0"
|
|
44
|
+
tooltip="Texto a buscar" />
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Atributos especificos de T**:
|
|
48
|
+
|
|
49
|
+
| Atributo | Descripción |
|
|
50
|
+
|----------|-------------|
|
|
51
|
+
| `size` | Tamaño de la columna en BD. Con `fixed-text="true"` también limita la entrada en UI |
|
|
52
|
+
| `lines` | Número de lineas visibles |
|
|
53
|
+
| `fixed-lines` | Si es `true`, el campo no crece en altura |
|
|
54
|
+
| `fixed-text` | Si es `true`, el texto no se puede editar |
|
|
55
|
+
| `keyboard-bar` | Muestra/oculta la barra sobre el teclado |
|
|
56
|
+
| `show-keyboard` | Muestra/oculta el teclado al entrar al campo |
|
|
57
|
+
| `ontextchanged` | Evento que se dispara con cada carácter escrito |
|
|
58
|
+
|
|
59
|
+
#### 5.9.2 Label (L / TL)
|
|
60
|
+
|
|
61
|
+
Texto de solo lectura. Ideal para títulos, etiquetas y textos informativos.
|
|
62
|
+
|
|
63
|
+
```xml
|
|
64
|
+
<!-- Label como título -->
|
|
65
|
+
<prop name="lblTitulo" type="L" visible="7"
|
|
66
|
+
title="Bienvenido de nuevo"
|
|
67
|
+
fontbold="true" fontsize="18"
|
|
68
|
+
forecolor="#212121" />
|
|
69
|
+
|
|
70
|
+
<!-- Label como subtitulo -->
|
|
71
|
+
<prop name="lblSubtitulo" type="L" visible="7"
|
|
72
|
+
title="Inicia sesion para continuar"
|
|
73
|
+
fontsize="14" forecolor="#9E9E9E" />
|
|
74
|
+
|
|
75
|
+
<!-- Label como separador con fondo -->
|
|
76
|
+
<prop name="MAP_SPACE" type="L" visible="7"
|
|
77
|
+
width="100%" height="3p"
|
|
78
|
+
bgcolor="#cccccc" title=" " />
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> **No pongas `labelwidth="0"` en un label.** En un `L`/`TL` el texto es el propio `title`, que se pinta dentro del ancho reservado para la etiqueta; con `labelwidth="0"` no hay sitio y el texto desaparece (queda un control vacío). Deja `labelwidth` por defecto y, si necesitas centrar o alinear el texto, usa `label-align="left|center|right"`. El `labelwidth="0"` solo es correcto en campos cuyo contenido va en el *valor* (`T`, `N`…) o que no tienen texto (`IMG`, botón de icono).
|
|
82
|
+
|
|
83
|
+
#### 5.9.3 Numérico (N, N2..N6, TN, TN2..TN6)
|
|
84
|
+
|
|
85
|
+
```xml
|
|
86
|
+
<!-- Número entero -->
|
|
87
|
+
<prop name="CANTIDAD" type="N" visible="7"
|
|
88
|
+
title="Cantidad" input-type="numeric" />
|
|
89
|
+
|
|
90
|
+
<!-- Precio con 2 decimales -->
|
|
91
|
+
<prop name="PRECIO" type="N2" visible="7"
|
|
92
|
+
title="Precio" width="50%" align="right" />
|
|
93
|
+
|
|
94
|
+
<!-- Coordenada con 6 decimales -->
|
|
95
|
+
<prop name="LATITUD" type="N6" visible="1"
|
|
96
|
+
title="Latitud" locked="true" />
|
|
97
|
+
|
|
98
|
+
<!-- Teléfono (número con enlace telefonico) -->
|
|
99
|
+
<prop name="MAP_TELEFONO" type="N" visible="1"
|
|
100
|
+
title="Teléfono" phone="true" />
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### 5.9.4 Botón (B)
|
|
104
|
+
|
|
105
|
+
Los botones son uno de los elementos más usados. Pueden ejecutar acciones de dos formas: `method` (invoca un nodo) u `onclick` (ejecuta JavaScript directo).
|
|
106
|
+
|
|
107
|
+
> **CRÍTICO: `onclick` SIEMPRE es JavaScript inline, NO el nombre de un nodo.** Es un error común poner `onclick="nombreNodo"` (sin paréntesis) esperando que XOne invoque el nodo `<nombreNodo>`. XOne lo evalúa como variable JS global, queda `undefined`, y **el botón no hace nada silenciosamente** (no falla, no logea). Formas válidas de `onclick`:
|
|
108
|
+
>
|
|
109
|
+
> - `onclick="ui.openEditView('X');"` — JS inline simple
|
|
110
|
+
> - `onclick="appData.getCollection('X').setMacro('##F##',''); ui.openEditView('X');"` — JS inline multi-sentencia (escapar `<`, `>`, `&` con entidades XML)
|
|
111
|
+
> - `onclick="miFuncion();"` — llamada a función global declarada en `functions.js` (con paréntesis)
|
|
112
|
+
> - `onclick="self.executeNode('miNodo');"` — invocar un nodo handler XML explícitamente
|
|
113
|
+
> - `onclick="refresh"` o `onclick="refresh(MAP_CAMPO)"` — comandos internos especiales del framework
|
|
114
|
+
>
|
|
115
|
+
> Para invocar un nodo XML, el atributo idiomático es **`method="executenode(nombreNodo)"`**, no `onclick`.
|
|
116
|
+
|
|
117
|
+
```xml
|
|
118
|
+
<!-- Botón con method (invoca nodo XML) -->
|
|
119
|
+
<prop name="BTN_GUARDAR" type="B" visible="1"
|
|
120
|
+
title="Guardar"
|
|
121
|
+
method="executenode(guardar)"
|
|
122
|
+
class="btnPrimario"
|
|
123
|
+
img="icon_save.png" />
|
|
124
|
+
|
|
125
|
+
<!-- Botón con onclick (JavaScript directo) -->
|
|
126
|
+
<prop name="BTN_BUSCAR" type="B" visible="1"
|
|
127
|
+
title="Buscar"
|
|
128
|
+
onclick="buscarDatos();"
|
|
129
|
+
width="100%" height="80p" />
|
|
130
|
+
|
|
131
|
+
<!-- Botón con method y parametros -->
|
|
132
|
+
<prop name="BTN_IR" type="B" visible="1"
|
|
133
|
+
method="ExecuteNode(irGrupo(2))" />
|
|
134
|
+
|
|
135
|
+
<!-- Botón con imagen y sin texto (solo icono) -->
|
|
136
|
+
<prop name="BTN_VOLVER" type="B" visible="1"
|
|
137
|
+
img="icon_back.png"
|
|
138
|
+
labelwidth="0"
|
|
139
|
+
width="48p" height="48p" />
|
|
140
|
+
|
|
141
|
+
<!-- Botón con imagen seleccionada (estado pressed) -->
|
|
142
|
+
<prop name="BTN_ADD" type="B" visible="1"
|
|
143
|
+
img="add.png"
|
|
144
|
+
imgsel="add_click.png"
|
|
145
|
+
labelwidth="0" width="75p" />
|
|
146
|
+
|
|
147
|
+
<!-- Botón con imagen deshabilitada -->
|
|
148
|
+
<prop name="BEdit" type="B" visible="1"
|
|
149
|
+
img="editar.png"
|
|
150
|
+
img-disabled="editarlocked.png"
|
|
151
|
+
disableedit="MAP_IDSELECTED=0"
|
|
152
|
+
method="ExecuteNode(editar)" />
|
|
153
|
+
|
|
154
|
+
<!-- Botón con ripple effect y colores -->
|
|
155
|
+
<prop name="BTN_ACCION" type="B" visible="1"
|
|
156
|
+
title="Acción"
|
|
157
|
+
bgcolor="#1565C0"
|
|
158
|
+
forecolor="#FFFFFF"
|
|
159
|
+
border-corner-radius="28"
|
|
160
|
+
ripple-effect="true" />
|
|
161
|
+
|
|
162
|
+
<!-- Botón con postonchange (ejecuta algo al volver) -->
|
|
163
|
+
<prop name="BNew" type="B" visible="1"
|
|
164
|
+
img="nuevo.png"
|
|
165
|
+
method="ExecuteNode(nuevo)"
|
|
166
|
+
postonchange="refresh" />
|
|
167
|
+
|
|
168
|
+
<!-- Botón de texto plano (TextButton Material): SIN caja ni borde -->
|
|
169
|
+
<prop name="BTN_SALTAR" type="B" visible="1"
|
|
170
|
+
title="saltar"
|
|
171
|
+
bgcolor="#F4EFFB" <!-- = color de fondo de la pantalla -->
|
|
172
|
+
forecolor="#7C3AED"
|
|
173
|
+
border-width="0"
|
|
174
|
+
onclick="omitir();" />
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
> **Botón de solo texto (sin caja).** Para emular un `TextButton` de Material (solo texto/icono, sin fondo ni borde — p. ej. "saltar", "atrás", "cancelar"), pon **`border-width="0"`** y un `bgcolor` igual al color de fondo de la pantalla. El botón se funde con el fondo y solo queda visible el texto, conservando toda su área de toque. No hace falta envolverlo en un `<frame>` ni usar un `type="L"`.
|
|
178
|
+
|
|
179
|
+
**Atributos especificos de B**:
|
|
180
|
+
|
|
181
|
+
| Atributo | Descripción |
|
|
182
|
+
|----------|-------------|
|
|
183
|
+
| `method` | Método a ejecutar. Formato: `executenode(nombreNodo)` o `ExecuteNode(nodo(param))` |
|
|
184
|
+
| `onclick` | Código JavaScript a ejecutar directamente |
|
|
185
|
+
| `img` | Imagen del botón (ruta relativa a `icons/`) |
|
|
186
|
+
| `imgsel` | Imagen en estado pulsado |
|
|
187
|
+
| `img-disabled` | Imagen cuando el botón esta deshabilitado |
|
|
188
|
+
| `caption` | Texto alternativo (similar a `title`) |
|
|
189
|
+
| `ripple-effect` | Efecto de onda al pulsar (Material Design) |
|
|
190
|
+
| `postonchange` | Acción a ejecutar al volver de la vista invocada |
|
|
191
|
+
| `labelwidth` | Si es `0`, no muestra etiqueta (botón solo icono) |
|
|
192
|
+
|
|
193
|
+
#### 5.9.5 Checkbox (NC)
|
|
194
|
+
|
|
195
|
+
```xml
|
|
196
|
+
<!-- Checkbox básico -->
|
|
197
|
+
<prop name="MAP_CHECK" type="NC" visible="1"
|
|
198
|
+
title="Acepto los terminos" />
|
|
199
|
+
|
|
200
|
+
<!-- Toggle / Switch -->
|
|
201
|
+
<prop name="MAP_TOGGLE" type="NC" visible="1"
|
|
202
|
+
check-type="toggle"
|
|
203
|
+
track-color="#FF0000"
|
|
204
|
+
thumb-color="#00FF00" />
|
|
205
|
+
|
|
206
|
+
<!-- Radio button con grupo -->
|
|
207
|
+
<prop name="MAP_RADIO1" type="NC" visible="1"
|
|
208
|
+
check-type="radio"
|
|
209
|
+
radio-group="1"
|
|
210
|
+
title="Opción A" />
|
|
211
|
+
<prop name="MAP_RADIO2" type="NC" visible="1"
|
|
212
|
+
check-type="radio"
|
|
213
|
+
radio-group="1"
|
|
214
|
+
title="Opción B" />
|
|
215
|
+
|
|
216
|
+
<!-- Switch con colores dinamicos -->
|
|
217
|
+
<prop name="MAP_CHECK_COLOR" type="NC" visible="1"
|
|
218
|
+
check-color-checked="##FLD_MAP_COLOR##"
|
|
219
|
+
bgcolor="##FLD_MAP_COLOR##" />
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
| Atributo | Descripción |
|
|
223
|
+
|----------|-------------|
|
|
224
|
+
| `check-type` | Tipo: `toggle`, `radio`, `switch` |
|
|
225
|
+
| `radio-group` | ID del grupo de radio buttons |
|
|
226
|
+
| `allow-radio-group-uncheck` | Permite deseleccionar un radio |
|
|
227
|
+
| `track-color` | Color de la pista (toggle/switch) |
|
|
228
|
+
| `thumb-color` | Color del circulo (toggle/switch) |
|
|
229
|
+
| `check-color-checked` | Color cuando esta marcado |
|
|
230
|
+
|
|
231
|
+
#### 5.9.6 Tipos de fecha y hora: D, DT, TT
|
|
232
|
+
|
|
233
|
+
XOne tiene tres tipos de prop para mostrar y editar fechas/horas:
|
|
234
|
+
|
|
235
|
+
| Tipo | Formato | Pickers asociados | Notas |
|
|
236
|
+
|------|---------|-------------------|-------|
|
|
237
|
+
| `D` | Fecha tradicional `DD/MM/AAAA` | DatePicker (icono de calendario) | Más común |
|
|
238
|
+
| `DT` | Fecha + hora `DD/MM/AAAA HH:MM` | DatePicker + TimePicker (calendario + reloj) | Para timestamps con hora |
|
|
239
|
+
| `TT` | Solo hora `HH:MM` | TimePicker (icono de reloj) | **Siempre asociar `mask="Hh#:#Mm"`** o el campo no se ve |
|
|
240
|
+
|
|
241
|
+
> **Selector por defecto (nuevo diseño).** Por defecto, al pulsar un campo `D`/`DT`/`TT` se abre un selector moderno: el de fecha es un calendario con **deslizamiento lateral entre meses** (además de los botones `‹ ›`) y el de hora son **ruedas** de hora y minuto. Para volver al selector nativo del sistema, fijar `date-mode`/`time-mode` a `0`. El selector admite `bgcolor-dialog`, `forecolor-dialog` (color de acento) y `fontsize-dialog`.
|
|
242
|
+
|
|
243
|
+
**Ejemplos:**
|
|
244
|
+
|
|
245
|
+
```xml
|
|
246
|
+
<!-- type=D: fecha tradicional -->
|
|
247
|
+
<prop name="FECHA" type="D" visible="1" title="FECHA"
|
|
248
|
+
labelwidth="6" fieldsize="7" onchange="Refresh255" />
|
|
249
|
+
|
|
250
|
+
<!-- type=DT: fecha + hora con icono custom y formato controlado -->
|
|
251
|
+
<prop name="MAP_TYPEDT" type="DT" title="Fecha y hora"
|
|
252
|
+
date-format="dd/MM/yyyy"
|
|
253
|
+
time-format="HH:mm"
|
|
254
|
+
locale="esES"
|
|
255
|
+
time-interval="2"
|
|
256
|
+
img-date="logo.png"
|
|
257
|
+
width="100%" height="10%"
|
|
258
|
+
img-date-width="96p" img-date-height="96p"
|
|
259
|
+
img-time-width="96p" img-time-height="96p" />
|
|
260
|
+
|
|
261
|
+
<!-- type=TT: solo hora — la mask es OBLIGATORIA -->
|
|
262
|
+
<prop name="MAP_TYPETT" type="TT" title="Hora"
|
|
263
|
+
mask="Hh#:#Mm"
|
|
264
|
+
time-interval="2"
|
|
265
|
+
width="100%"
|
|
266
|
+
img-time-width="96p" img-time-height="96p" />
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Atributos relacionados (D / DT / TT):**
|
|
270
|
+
|
|
271
|
+
| Atributo | Descripción |
|
|
272
|
+
|----------|-------------|
|
|
273
|
+
| `title` | Texto/etiqueta visible de la propiedad en edición |
|
|
274
|
+
| `date-format` | Formato de visualizacion de la fecha (ej. `dd/MM/yyyy`). Modifica el formato por defecto |
|
|
275
|
+
| `time-format` | Formato de visualizacion de la hora (ej. `HH:mm`). Solo en DT/TT |
|
|
276
|
+
| `mask` | Mascara de entrada. **Obligatoria en TT**: `mask="Hh#:#Mm"` |
|
|
277
|
+
| `locale` | Locale para nombres de mes/día (ej. `esES`, `enUS`) |
|
|
278
|
+
| `time-interval` | Intervalo de minutos en el TimePicker (ej. `2` = saltos de 2 minutos) |
|
|
279
|
+
| `date-mode` | Estilo del selector de fecha. Ausente o `4` = nuevo diseño moderno (calendario con swipe lateral de meses); `0`–`3` = selectores nativos del sistema (0 dispositivo, 1 oscuro, 2 claro, 3 oscuro) |
|
|
280
|
+
| `time-mode` | Estilo del selector de hora. Ausente o `4` = nuevo diseño moderno (ruedas de hora/minuto); `0`–`3` = selectores nativos del sistema |
|
|
281
|
+
| `bgcolor-dialog` | Color de fondo del selector (nuevo diseño) |
|
|
282
|
+
| `forecolor-dialog` | Color de acento del selector (día/hora seleccionados, botones) |
|
|
283
|
+
| `fontsize-dialog` | Tamaño de los números del selector |
|
|
284
|
+
| `img-date` | Imagen para el icono del DatePicker |
|
|
285
|
+
| `img-date-width` / `img-date-height` | Tamaño del icono del calendario |
|
|
286
|
+
| `img-time-width` / `img-time-height` | Tamaño del icono del reloj |
|
|
287
|
+
| `ios-datepicker-mode` | Modo del selector en iOS: `inline`, `wheels`, `compact` |
|
|
288
|
+
| `bgcolor` / `forecolor` | Colores de fondo y texto |
|
|
289
|
+
| `width` / `height` | Dimensiones |
|
|
290
|
+
| `lmargin` / `rmargin` / `tmargin` / `bmargin` | Margenes |
|
|
291
|
+
| `newline` | `true`/`false`. Forzar salto de linea |
|
|
292
|
+
| `fontsize` | Tamaño de fuente |
|
|
293
|
+
| `labelwidth` | Ancho de la etiqueta. `0` para que no aparezca |
|
|
294
|
+
| `locked` | Bloquear el campo según finalidad |
|
|
295
|
+
|
|
296
|
+
**Funciones JS asociadas (`ui.showDatePicker`, `ui.showTimePicker`):**
|
|
297
|
+
|
|
298
|
+
```javascript
|
|
299
|
+
// Inicializar valores en before-edit
|
|
300
|
+
function doBeforeEdit() {
|
|
301
|
+
self.MAP_TYPEDT = new Date();
|
|
302
|
+
self.MAP_TYPED = "2023-07-14 00:00:00";
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Abrir DatePicker que escribe directamente en un prop
|
|
306
|
+
function showDatePicker() {
|
|
307
|
+
ui.showDatePicker({
|
|
308
|
+
targetProperty: "MAP_TYPED"
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Abrir DatePicker con callback (sin targetProperty)
|
|
313
|
+
function showDatePickerCallback() {
|
|
314
|
+
ui.showDatePicker({
|
|
315
|
+
onDateSet: function(nYear, nMonth, nDay) {
|
|
316
|
+
ui.showToast("Dia: " + nDay + " Mes: " + nMonth + " Anio: " + nYear);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Abrir TimePicker — pre-rellena con la hora actual del prop
|
|
322
|
+
function showTimePicker() {
|
|
323
|
+
var horaSpliteada = self.MAP_TYPETT.split(":");
|
|
324
|
+
ui.showTimePicker({
|
|
325
|
+
targetProperty: "MAP_TYPETT",
|
|
326
|
+
initialHour: horaSpliteada[0],
|
|
327
|
+
initialMinute: horaSpliteada[1],
|
|
328
|
+
is24HoursMode: true,
|
|
329
|
+
title: "Seleccione el tiempo"
|
|
330
|
+
// theme: "holo_light" // opcional
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Obtener fecha/hora actual como string
|
|
335
|
+
function getCurrentDate() {
|
|
336
|
+
ui.showToast(new Date().toUTCString());
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
> **Diseño del picker.** Sin `theme`, `ui.showDatePicker`/`ui.showTimePicker` usan el nuevo selector moderno (calendario con swipe lateral de meses / ruedas de hora). Pasar `theme` fuerza el selector nativo del sistema con ese tema; `ui.showTimePicker` con `is24HoursMode: false` también usa el nativo (el nuevo diseño es 24 h).
|
|
341
|
+
|
|
342
|
+
> **Tip:** En `type="DT"` y `type="TT"`, `time-interval` es útil para forzar saltos de N minutos (ej. citas de 15 en 15 min se haria con `time-interval="15"`).
|
|
343
|
+
|
|
344
|
+
> **Para temporizadores continuos / cronometros**, NO usar pickers. La API correcta es `control.startChronometer({fromDate, dateFormat})` y `control.stopChronometer()`. Ver tópico 03 sección `startChronometer / stopChronometer`.
|
|
345
|
+
|
|
346
|
+
#### 5.9.8 Imagen (IMG)
|
|
347
|
+
|
|
348
|
+
```xml
|
|
349
|
+
<!-- Imagen estática con ruta -->
|
|
350
|
+
<prop name="MAP_LOGO" type="IMG" visible="1"
|
|
351
|
+
path="logo.png"
|
|
352
|
+
width="100p" height="100p"
|
|
353
|
+
keep-aspect-ratio="true" />
|
|
354
|
+
|
|
355
|
+
<!-- Imagen con ruta del sistema -->
|
|
356
|
+
<prop name="MAP_IMAGE" type="IMG" visible="1"
|
|
357
|
+
path="##APP##\icons\xone.png"
|
|
358
|
+
labelwidth="0"
|
|
359
|
+
height="40%" lmargin="2%" />
|
|
360
|
+
|
|
361
|
+
<!-- Imagen como dato (valor almacenado en campo) -->
|
|
362
|
+
<prop name="FOTO" type="IMG" visible="1"
|
|
363
|
+
width="100p" height="100p"
|
|
364
|
+
keep-aspect-ratio="true"
|
|
365
|
+
scale-type="center_crop"
|
|
366
|
+
border-corner-radius="50" />
|
|
367
|
+
|
|
368
|
+
<!-- Imagen con error fallback -->
|
|
369
|
+
<prop name="AVATAR" type="IMG" visible="7"
|
|
370
|
+
path="avatar_default.png"
|
|
371
|
+
error-image="avatar_error.png"
|
|
372
|
+
keep-aspect-ratio="true" />
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
| Atributo | Descripción |
|
|
376
|
+
|----------|-------------|
|
|
377
|
+
| `path` | Ruta de la imagen (relativa a `icons/` o con `##APP##`) |
|
|
378
|
+
| `keep-aspect-ratio` | Mantiene la proporcion de la imagen |
|
|
379
|
+
| `scale-type` | Tipo de escalado: `center_crop`, `fit_center`, `fit_xy` |
|
|
380
|
+
| `error-image` | Imagen a mostrar si la principal falla |
|
|
381
|
+
| `abort-on-error` | Si es `true`, no intenta cargar si hay error |
|
|
382
|
+
|
|
383
|
+
> **Formatos:** `path` (igual que los atributos `img`/`imgbk`) acepta **PNG, JPG y SVG indistintamente**. El SVG se renderiza de forma nativa y escala sin perder calidad — **no** envuelvas un SVG en un `type="WEB"` ni lo conviertas previamente; basta con apuntar `path="dibujo.svg"`. Además acepta **GIF animado** y **animaciones Lottie** (ver abajo), decidiendo por la extensión del fichero.
|
|
384
|
+
|
|
385
|
+
##### Animaciones Lottie en un `IMG`
|
|
386
|
+
|
|
387
|
+
Un `IMG` cuyo fichero sea `.json`, `.lottie` o `.tgs` se renderiza como animación Lottie (las exportadas de After Effects con Bodymovin, o las descargadas de LottieFiles) y **arranca sola en bucle infinito**, sin necesidad de llamar a nada:
|
|
388
|
+
|
|
389
|
+
```xml
|
|
390
|
+
<!-- Animación en bucle, ida y vuelta -->
|
|
391
|
+
<prop name="MAP_LOADER" type="IMG" visible="1"
|
|
392
|
+
path="loader.json"
|
|
393
|
+
labelwidth="0"
|
|
394
|
+
width="120p" height="120p"
|
|
395
|
+
repeat-mode="reverse" />
|
|
396
|
+
|
|
397
|
+
<!-- Animación con texto de párrafo recortado a su caja -->
|
|
398
|
+
<prop name="MAP_CARTEL" type="IMG" visible="1"
|
|
399
|
+
path="cartel.lottie"
|
|
400
|
+
labelwidth="0"
|
|
401
|
+
width="100%" height="200p"
|
|
402
|
+
clip-text-to-bounds="true" />
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
| Atributo | Descripción |
|
|
406
|
+
|----------|-------------|
|
|
407
|
+
| `repeat-mode` | `restart` (vuelve a empezar) o `reverse` (va y vuelve). Sin declararlo, se repite desde el inicio |
|
|
408
|
+
| `clip-text-to-bounds` | Solo para animaciones con texto de párrafo: recorta el texto a la caja definida en el diseño en vez de dejar que las líneas que no caben se salgan. Apagado por omisión, y con motivo: una línea que desborde la altura **no se dibuja en absoluto**, así que si la fuente no es la del diseño y el texto se reparte en más líneas, desaparece contenido |
|
|
409
|
+
|
|
410
|
+
**Formatos y qué lleva cada uno:**
|
|
411
|
+
|
|
412
|
+
| Extensión | Qué es |
|
|
413
|
+
|---|---|
|
|
414
|
+
| `.json` | La animación exportada, en texto plano. Las imágenes pueden ir embebidas en el propio fichero (base64) o aparte |
|
|
415
|
+
| `.lottie` | Paquete comprimido con la animación y sus imágenes dentro. Un `.json` renombrado a `.lottie` también se acepta |
|
|
416
|
+
| `.tgs` | Sticker de Telegram: un `.json` comprimido con gzip. Se reconoce y reproduce igual |
|
|
417
|
+
|
|
418
|
+
**Fuentes de la animación.** Si la animación lleva texto, la fuente se busca **solo** en la carpeta `fonts/` del proyecto, con el nombre de la familia que declara el propio fichero: si la animación pide `Roboto`, hace falta `fonts/Roboto.ttf` (o `.otf`). Si no está, el texto se pinta con la fuente por defecto del dispositivo, de modo que se ve pero con otras medidas — que es justo lo que puede descolocar el reparto de líneas. Nunca se toman fuentes del sistema por nombre, para que la animación se vea igual en todos los terminales.
|
|
419
|
+
|
|
420
|
+
**Imágenes de la animación.** Se resuelven de tres maneras, por este orden: embebidas en el propio fichero, dentro del `.lottie`, o como ficheros sueltos junto al fichero de animación, respetando la subcarpeta que declare el diseño (lo habitual es `images/`, de modo que un `loader.json` que pida `images/img_0.png` lo busca en `images/img_0.png` junto a él y, si no está, al lado del propio `loader.json`). Una imagen que no se encuentre deja su capa sin pintar: no rompe la animación ni la app.
|
|
421
|
+
|
|
422
|
+
> **Los atributos `img` e `imgbk` de cualquier control usan el mismo cargador**, así que también aceptan estas extensiones. Lo que solo existe en el `type="IMG"` es el control de la reproducción: los atributos de arriba y los métodos de animación desde JavaScript (`playAnimation`, `stopAnimation`, `setAnimationFrame`…, ver [métodos de los controles](../javascript/metodos-de-los-controles.md)).
|
|
423
|
+
|
|
424
|
+
#### 5.9.9 Foto (PH)
|
|
425
|
+
|
|
426
|
+
Captura de foto con la camara del dispositivo:
|
|
427
|
+
|
|
428
|
+
```xml
|
|
429
|
+
<!-- Capturar foto -->
|
|
430
|
+
<prop name="MAP_FOTO" type="PH" visible="1"
|
|
431
|
+
title="Foto"
|
|
432
|
+
height="40%"
|
|
433
|
+
img-width="48p" img-height="48p"
|
|
434
|
+
lmargin="2%" />
|
|
435
|
+
|
|
436
|
+
<!-- Ver foto (solo lectura) -->
|
|
437
|
+
<prop name="MAP_FOTOVER" type="PH" visible="1"
|
|
438
|
+
locked="true"
|
|
439
|
+
height="40%"
|
|
440
|
+
title="Foto capturada" />
|
|
441
|
+
|
|
442
|
+
<!-- Foto en movimiento, con la cámara del propio framework -->
|
|
443
|
+
<prop name="MAP_FOTOMOV" type="PH" visible="1"
|
|
444
|
+
title="Foto"
|
|
445
|
+
height="40%"
|
|
446
|
+
use-internal-camera="true"
|
|
447
|
+
motion-photo="true" />
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
| Atributo | Descripción |
|
|
451
|
+
|----------|-------------|
|
|
452
|
+
| `use-internal-camera` | Captura con la cámara que trae el framework en vez de abrir la app de cámara del dispositivo. Da una pantalla de captura igual en todos los terminales (disparador, temporizador, flash, zoom, brillo y previsualización antes de aceptar) |
|
|
453
|
+
| `motion-photo` | Captura una **foto en movimiento**: un JPG que lleva embebido detrás un clip de vídeo corto con el instante del disparo. Para cualquier visor sigue siendo una foto normal, y las galerías que entienden el formato (Google Fotos) reproducen el movimiento al abrirla |
|
|
454
|
+
| `file-maxsize`, `file-maxwidth`, `file-maxheight`, `file-quality` | Límites de tamaño y calidad de la foto guardada |
|
|
455
|
+
| `analyze-exif-metadata` | Gira el fichero según la orientación con la que se hizo la foto, de modo que se vea derecho en cualquier visor |
|
|
456
|
+
|
|
457
|
+
##### Fotos en movimiento (`motion-photo`)
|
|
458
|
+
|
|
459
|
+
> **Úsalo junto a `use-internal-camera="true"`.** Así funciona en cualquier versión de Android, porque la captura y el montaje del fichero los hace el propio framework. Sin `use-internal-camera` se delega en la app de cámara del dispositivo, que solo puede atender la petición a partir de **Android 16** y únicamente si la implementa: a día de hoy no lo hace ninguna, ni siquiera la de los Pixel, con lo que se obtiene una foto normal sin más aviso.
|
|
460
|
+
|
|
461
|
+
Al capturar una foto en movimiento se **ignoran** `file-maxsize`, `file-maxwidth`, `file-maxheight` y `file-quality`: redimensionar o recomprimir la imagen se llevaría por delante el vídeo embebido. Si necesitas fotos ligeras, no uses `motion-photo`. El fichero resultante pesa lo que la foto más el clip, del orden de varios megas.
|
|
462
|
+
|
|
463
|
+
`analyze-exif-metadata="true"` sí es compatible: al girar la foto se conserva el vídeo.
|
|
464
|
+
|
|
465
|
+
#### 5.9.10 Video/Camara (VD) y escaner QR
|
|
466
|
+
|
|
467
|
+
```xml
|
|
468
|
+
<!-- Grabar video -->
|
|
469
|
+
<prop name="MAP_VIDEO" type="VD" visible="1"
|
|
470
|
+
readonly="false"
|
|
471
|
+
width="50%" height="40%"
|
|
472
|
+
title="Video"
|
|
473
|
+
onchange="refresh(MAP_VIDEO)" />
|
|
474
|
+
|
|
475
|
+
<!-- Reproducir video local -->
|
|
476
|
+
<prop name="MAP_VIDEOVER" type="VD" visible="1"
|
|
477
|
+
readonly="true"
|
|
478
|
+
width="50%" height="40%" />
|
|
479
|
+
|
|
480
|
+
<!-- Escaner QR -->
|
|
481
|
+
<prop name="SCANNER" type="VD" visible="1"
|
|
482
|
+
viewmode="camerapreview"
|
|
483
|
+
width="100%" height="300p"
|
|
484
|
+
code-type="qr"
|
|
485
|
+
oncodescanned="procesarCodigo(e);" />
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
| Atributo | Descripción |
|
|
489
|
+
|----------|-------------|
|
|
490
|
+
| `code-type` | Tipo de código a escanear: `qr`, `datamatrix`, `barcode` |
|
|
491
|
+
| `oncodescanned` | Evento al leer un código |
|
|
492
|
+
| `readonly` | Si es `true`, solo reproduce; si es `false`, captura |
|
|
493
|
+
|