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.
Files changed (187) hide show
  1. package/README.md +167 -0
  2. package/dist/agent/authEnDisco.js +56 -0
  3. package/dist/agent/authEnDisco.js.map +1 -0
  4. package/dist/agent/configEnDisco.js +109 -0
  5. package/dist/agent/configEnDisco.js.map +1 -0
  6. package/dist/agent/crearProyecto.js +34 -0
  7. package/dist/agent/crearProyecto.js.map +1 -0
  8. package/dist/agent/entorno.js +124 -0
  9. package/dist/agent/entorno.js.map +1 -0
  10. package/dist/agent/guionizado.js +53 -0
  11. package/dist/agent/guionizado.js.map +1 -0
  12. package/dist/agent/instantanea.js +129 -0
  13. package/dist/agent/instantanea.js.map +1 -0
  14. package/dist/agent/interrupts.js +83 -0
  15. package/dist/agent/interrupts.js.map +1 -0
  16. package/dist/agent/mensajes.js +24 -0
  17. package/dist/agent/mensajes.js.map +1 -0
  18. package/dist/agent/modelos.js +42 -0
  19. package/dist/agent/modelos.js.map +1 -0
  20. package/dist/agent/normalizar.js +20 -0
  21. package/dist/agent/normalizar.js.map +1 -0
  22. package/dist/agent/perfiles.js +103 -0
  23. package/dist/agent/perfiles.js.map +1 -0
  24. package/dist/agent/proyecto.js +107 -0
  25. package/dist/agent/proyecto.js.map +1 -0
  26. package/dist/agent/puente.js +142 -0
  27. package/dist/agent/puente.js.map +1 -0
  28. package/dist/agent/resumenDeTool.js +48 -0
  29. package/dist/agent/resumenDeTool.js.map +1 -0
  30. package/dist/agent/skills.js +65 -0
  31. package/dist/agent/skills.js.map +1 -0
  32. package/dist/agent/textoDeTool.js +113 -0
  33. package/dist/agent/textoDeTool.js.map +1 -0
  34. package/dist/agent/turnoReal.js +173 -0
  35. package/dist/agent/turnoReal.js.map +1 -0
  36. package/dist/agent/verificador.js +65 -0
  37. package/dist/agent/verificador.js.map +1 -0
  38. package/dist/agent/xoneAgent.js +106 -0
  39. package/dist/agent/xoneAgent.js.map +1 -0
  40. package/dist/bin.js +9 -0
  41. package/dist/bin.js.map +1 -0
  42. package/dist/cli/aprobar.js +82 -0
  43. package/dist/cli/aprobar.js.map +1 -0
  44. package/dist/cli/config.js +133 -0
  45. package/dist/cli/config.js.map +1 -0
  46. package/dist/cli/consola.js +346 -0
  47. package/dist/cli/consola.js.map +1 -0
  48. package/dist/cli/describe.js +53 -0
  49. package/dist/cli/describe.js.map +1 -0
  50. package/dist/cli/doctor.js +45 -0
  51. package/dist/cli/doctor.js.map +1 -0
  52. package/dist/cli/main.js +520 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/markdown.js +90 -0
  55. package/dist/cli/markdown.js.map +1 -0
  56. package/dist/cli/run.js +164 -0
  57. package/dist/cli/run.js.map +1 -0
  58. package/dist/cli/spinner.js +89 -0
  59. package/dist/cli/spinner.js.map +1 -0
  60. package/dist/cli/stdio.js +193 -0
  61. package/dist/cli/stdio.js.map +1 -0
  62. package/dist/cli/tema.js +40 -0
  63. package/dist/cli/tema.js.map +1 -0
  64. package/dist/cli/verify.js +62 -0
  65. package/dist/cli/verify.js.map +1 -0
  66. package/dist/core/bitacora.js +30 -0
  67. package/dist/core/bitacora.js.map +1 -0
  68. package/dist/core/config.js +236 -0
  69. package/dist/core/config.js.map +1 -0
  70. package/dist/core/contextos.js +56 -0
  71. package/dist/core/contextos.js.map +1 -0
  72. package/dist/core/deps.js +51 -0
  73. package/dist/core/deps.js.map +1 -0
  74. package/dist/core/diff.js +79 -0
  75. package/dist/core/diff.js.map +1 -0
  76. package/dist/core/esqueleto.js +366 -0
  77. package/dist/core/esqueleto.js.map +1 -0
  78. package/dist/core/events.js +2 -0
  79. package/dist/core/events.js.map +1 -0
  80. package/dist/core/modelos.js +85 -0
  81. package/dist/core/modelos.js.map +1 -0
  82. package/dist/core/notify.js +106 -0
  83. package/dist/core/notify.js.map +1 -0
  84. package/dist/core/ports.js +114 -0
  85. package/dist/core/ports.js.map +1 -0
  86. package/dist/core/turno.js +127 -0
  87. package/dist/core/turno.js.map +1 -0
  88. package/dist/vendor/hitl.js +103 -0
  89. package/dist/vendor/hitl.js.map +1 -0
  90. package/dist/vendor/skillLoaders/catalog.js +74 -0
  91. package/dist/vendor/skillLoaders/catalog.js.map +1 -0
  92. package/dist/vendor/tokenTracking.js +58 -0
  93. package/dist/vendor/tokenTracking.js.map +1 -0
  94. package/package.json +41 -0
  95. package/skills/xone-debugging/SKILL.md +52 -0
  96. package/skills/xone-debugging/references/faq.md +561 -0
  97. package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
  98. package/skills/xone-development/SKILL.md +105 -0
  99. package/skills/xone-development/references/anti-patrones.md +94 -0
  100. package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
  101. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
  102. package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
  103. package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
  104. package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
  105. package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
  106. package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
  107. package/skills/xone-development/references/datos/appdata.md +611 -0
  108. package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
  109. package/skills/xone-development/references/datos/http.md +366 -0
  110. package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
  111. package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
  112. package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
  113. package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
  114. package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
  115. package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
  116. package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
  117. package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
  118. package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
  119. package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
  120. package/skills/xone-development/references/indice-completo.md +77 -0
  121. package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
  122. package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
  123. package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
  124. package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
  125. package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
  126. package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
  127. package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
  128. package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
  129. package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
  130. package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
  131. package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
  132. package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
  133. package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
  134. package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
  135. package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
  136. package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
  137. package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
  138. package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
  139. package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
  140. package/skills/xone-development/references/tipos-de-prop.md +28 -0
  141. package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
  142. package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
  143. package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
  144. package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
  145. package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
  146. package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
  147. package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
  148. package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
  149. package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
  150. package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
  151. package/skills/xone-development/references/xml-ui/mapas.md +685 -0
  152. package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
  153. package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
  154. package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
  155. package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
  156. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
  157. package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
  158. package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
  159. package/skills/xone-plan-builder/SKILL.md +183 -0
  160. package/skills/xone-plan-builder/agents/openai.yaml +5 -0
  161. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
  162. package/skills/xone-project-generator/SKILL.md +111 -0
  163. package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
  164. package/skills/xone-project-generator/references/colecciones-base.md +16 -0
  165. package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
  166. package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
  167. package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
  168. package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
  169. package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
  170. package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
  171. package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
  172. package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
  173. package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
  174. package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
  175. package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
  176. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
  177. package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
  178. package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
  179. package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
  180. package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
  181. package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
  182. package/skills/xone-review/SKILL.md +189 -0
  183. package/skills/xone-spec-builder/SKILL.md +235 -0
  184. package/skills/xone-spec-builder/agents/openai.yaml +5 -0
  185. package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
  186. package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
  187. package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
@@ -0,0 +1,681 @@
1
+ # Generación XOne — Fase 7: viewmodes de gráficos y listas
2
+
3
+ > Fuente: `xone/v2/xone-project-generator/references/xone-project-generation-workflow.md` L3977–4651. Referencia de la skill; el índice está en [../SKILL.md](../SKILL.md).
4
+
5
+ Contenido: §7.13c gráficos (barchart, piechart, linechart) · §7.13d picturemap · §7.13e slideview · §7.13f expanview · §7.13g gridview · §7.13h patrón contentselitem
6
+
7
+ ---
8
+
9
+ ### 7.13c ViewMode: Gráficos (barchart, piechart, linechart...)
10
+
11
+ **Cuando usarlo:** dashboards con KPIs, estadisticas de ventas, distribución de datos por categorías, evoluciones temporales.
12
+
13
+ Los gráficos en XOne se implementan como un `prop type="Z"` con `viewmode` especificando el tipo de gráfico. Requieren que la coleccion de datos tenga un campo marcado con `classid="XOneCharts"` en el prop, o que el propio prop lo declare.
14
+
15
+ #### Tipos de gráfico disponibles
16
+
17
+ | viewmode | Tipo | Cuando usarlo |
18
+ |----------|------|---------------|
19
+ | `barchart` | Barras verticales | Comparacion de valores entre categorías |
20
+ | `3dbarchart` | Barras 3D | Igual que barchart con efecto visual 3D |
21
+ | `linechart` | Lineas | Evolución de valores en el tiempo |
22
+ | `xylinechart` | Lineas XY | Relación entre dos variables numéricas |
23
+ | `areachart` | Área rellena | Tendencias acumuladas, volúmenes |
24
+ | `piechart` | Tarta | Distribución porcentual de categorías |
25
+ | `piechart2` | Tarta alternativa | Variante visual del piechart |
26
+ | `timeserieschart` | Series temporales | Datos con eje temporal preciso (sensores, IoT) |
27
+ | `slidingbarchart` | Barras con scroll | Muchas categorías con navegación horizontal |
28
+
29
+ #### Estructura general — prop y contents
30
+
31
+ ```xml
32
+ <!-- Prop que muestra el gráfico -->
33
+ <prop name="@GraficoVentas"
34
+ type="Z"
35
+ viewmode="barchart"
36
+ classid="XOneCharts"
37
+ contents="GraficoVentas"
38
+ width="100%"
39
+ height="300p"
40
+ locked="true" />
41
+
42
+ <contents name="GraficoVentas" src="ContentGraficoVentas" />
43
+ ```
44
+
45
+ #### Coleccion de datos del gráfico
46
+
47
+ La coleccion que alimenta el gráfico debe tener campos con atributos especiales que indican al framework que rol tiene cada campo:
48
+
49
+ ```xml
50
+ <coll name="ContentGraficoVentas" title="gráfico ventas"
51
+ sql="SELECT t1.MES, t1.TOTAL_VENTAS, t1.TOTAL_COSTES
52
+ FROM ##PREF##ventas_mensuales t1"
53
+ objname="ventas_mensuales" updateobj="ventas_mensuales"
54
+ progid="ASData.CASBasicDataObj" loadall="true">
55
+ <group name="General" id="1">
56
+ <!-- chart-label=true: este campo es la etiqueta del eje X (categorias) -->
57
+ <prop name="MES" type="T" visible="4" chart-label="true" />
58
+ <!-- chart-value=true: este campo es el valor a graficar (eje Y) -->
59
+ <prop name="TOTAL_VENTAS" type="N2" visible="4"
60
+ chart-value="true" chart-series="Ventas" />
61
+ <!-- Multiples series: un prop chart-value por cada serie -->
62
+ <prop name="TOTAL_COSTES" type="N2" visible="4"
63
+ chart-value="true" chart-series="Costes" />
64
+ </group>
65
+ </coll>
66
+ ```
67
+
68
+ #### Atributos clave de los props en la coleccion del gráfico
69
+
70
+ | Atributo | Descripción |
71
+ |----------|-------------|
72
+ | `chart-label="true"` | Este campo es la etiqueta del eje X (nombre de la categoría) |
73
+ | `chart-value="true"` | Este campo es el valor numérico a representar en el gráfico |
74
+ | `chart-series="NombreSerie"` | Nombre de la serie en el gráfico (aparece en la leyenda) |
75
+ | `chart-color="#RRGGBB"` | Color de la barra/linea/sector de esta serie |
76
+
77
+ #### Ejemplos por tipo de gráfico
78
+
79
+ **Barchart — comparacion de ventas por mes:**
80
+
81
+ ```xml
82
+ <prop name="@GraficoBarras" type="Z" viewmode="barchart"
83
+ classid="XOneCharts" contents="GraficoBarras"
84
+ width="100%" height="350p" locked="true" />
85
+ <contents name="GraficoBarras" src="ContentVentasMes" />
86
+ ```
87
+
88
+ **Piechart — distribución porcentual:**
89
+
90
+ ```xml
91
+ <prop name="@GraficoPie" type="Z" viewmode="piechart"
92
+ classid="XOneCharts" contents="GraficoPie"
93
+ width="100%" height="300p" locked="true" />
94
+ <contents name="GraficoPie" src="ContentDistribucion" />
95
+ ```
96
+
97
+ ```xml
98
+ <!-- Coleccion para piechart: una fila por sector -->
99
+ <coll name="ContentDistribucion" title="distribucion"
100
+ sql="SELECT CATEGORIA, TOTAL FROM ##PREF##distribucion"
101
+ objname="distribucion" updateobj="distribucion"
102
+ progid="ASData.CASBasicDataObj" loadall="true">
103
+ <group name="General" id="1">
104
+ <prop name="CATEGORIA" type="T" visible="4" chart-label="true" />
105
+ <prop name="TOTAL" type="N2" visible="4" chart-value="true" />
106
+ </group>
107
+ </coll>
108
+ ```
109
+
110
+ **Linechart — evolución temporal:**
111
+
112
+ ```xml
113
+ <prop name="@GraficoLinea" type="Z" viewmode="linechart"
114
+ classid="XOneCharts" contents="GraficoLinea"
115
+ width="100%" height="300p" locked="true" />
116
+ <contents name="GraficoLinea" src="ContentEvolucion" />
117
+ ```
118
+
119
+ #### Regla de decisión para elegir tipo de gráfico
120
+
121
+ ```
122
+ El usuario pide... -> Usar
123
+ "comparar ventas por categoría" -> barchart o 3dbarchart
124
+ "ver evolucion en el tiempo" -> linechart o timeserieschart
125
+ "distribucion porcentual" -> piechart o piechart2
126
+ "comparar dos variables numericas" -> xylinechart
127
+ "volumen acumulado" -> areachart
128
+ "muchas categorias con scroll" -> slidingbarchart
129
+ ```
130
+
131
+ ---
132
+
133
+ ### 7.13d ViewMode: picturemap
134
+
135
+ **Cuando usarlo:** planos de instalaciones, mapas de planta de un edificio, esquemas de infraestructura, cualquier imagen sobre la que se quieran colocar marcadores en coordenadas fijas.
136
+
137
+ A diferencia de `mapview` (que usa Google Maps o OpenStreetMap con coordenadas GPS), `picturemap` superpone marcadores sobre una **imagen estática** propia. Las coordenadas son en pixeles relativos a esa imagen, no coordenadas geograficas.
138
+
139
+ #### Declaración del prop tipo picturemap
140
+
141
+ ```xml
142
+ <frame name="frmPictureMap" width="700p" height="700p"
143
+ lmargin="10p" tmargin="20p" framebox="true">
144
+ <prop name="@PictureMapData"
145
+ type="Z"
146
+ viewmode="picturemap"
147
+ contents="PictureMapData"
148
+ imgbk="mapa-planta.png"
149
+ ignore-touch-in-transparent-area="true"
150
+ width="100%"
151
+ height="100%" />
152
+ <contents name="PictureMapData" src="ContentPictureMapData" />
153
+ </frame>
154
+ ```
155
+
156
+ #### Coleccion de datos del picturemap
157
+
158
+ Cada registro de la coleccion representa un marcador en el mapa. Los campos con atributos especiales indican al framework el rol de cada campo:
159
+
160
+ ```xml
161
+ <coll name="ContentPictureMapData" title="PictureMapData"
162
+ sql="SELECT t1.* FROM ##PREF##puntos_mapa t1"
163
+ objname="puntos_mapa" updateobj="puntos_mapa"
164
+ progid="ASData.CASBasicDataObj" loadall="true">
165
+ <group name="General" id="1">
166
+ <prop name="CODIGO" type="T" visible="0" />
167
+ <!-- Texto mostrado en el popup al pulsar el marcador -->
168
+ <prop name="TITULO" type="T" visible="4" />
169
+ <prop name="DESCRIPCION" type="T" visible="4" />
170
+ <prop name="ESTADO" type="T" visible="4" />
171
+ <!-- xcoord=true: coordenada X del marcador en pixeles sobre la imagen -->
172
+ <prop name="XCOORD" type="N" visible="4" xcoord="true" />
173
+ <!-- ycoord=true: coordenada Y del marcador en pixeles sobre la imagen -->
174
+ <prop name="YCOORD" type="N" visible="4" ycoord="true" />
175
+ <!-- icon-big=true: icono grande que se muestra en el popup al seleccionar -->
176
+ <prop name="ICONBIG" type="T" visible="4" icon-big="true"
177
+ width="126" height="168" size="250" />
178
+ <!-- circle-radius=true: radio del circulo de zona alrededor del marcador -->
179
+ <prop name="RADIO" type="N" visible="4" circle-radius="true" />
180
+ <!-- icon-mark=true: icono del marcador en estado normal (sin pulsar) -->
181
+ <prop name="ICONOFF" type="T" visible="4" icon-mark="true"
182
+ width="126" height="168" size="250" />
183
+ <!-- icon-touch=true: icono del marcador al estar seleccionado/pulsado -->
184
+ <prop name="ICONON" type="T" visible="4" icon-touch="true"
185
+ width="126" height="168" size="250" />
186
+ </group>
187
+
188
+ <!-- Al seleccionar un marcador: pasar datos al objeto padre -->
189
+ <selecteditem show-wait-dialog="false" refresh="false">
190
+ <action name="runscript">
191
+ <script language="javascript">
192
+ var parent = self.getOwnerCollection().getOwnerObject();
193
+ parent.MAP_ID = self.ID;
194
+ parent.MAP_NOMBRE = self.TITULO;
195
+ parent.MAP_DESCRIPCION = self.DESCRIPCION;
196
+ ui.getView(parent).refresh("MAP_NOMBRE,MAP_DESCRIPCION");
197
+ </script>
198
+ </action>
199
+ </selecteditem>
200
+ </coll>
201
+ ```
202
+
203
+ #### Atributos del prop picturemap
204
+
205
+ | Atributo | Descripción |
206
+ |----------|-------------|
207
+ | `imgbk="archivo.png"` | Imagen de fondo sobre la que se colocan los marcadores |
208
+ | `ignore-touch-in-transparent-area="true"` | Ignora toques en zonas transparentes de la imagen |
209
+ | `viewmode="picturemap"` | Activa el modo mapa de imagen |
210
+
211
+ #### Atributos especiales en los props de la coleccion de datos
212
+
213
+ | Atributo en prop | Tipo de campo | Descripción |
214
+ |------------------|---------------|-------------|
215
+ | `xcoord="true"` | `N` | Coordenada X del marcador en pixeles sobre la imagen |
216
+ | `ycoord="true"` | `N` | Coordenada Y del marcador en pixeles sobre la imagen |
217
+ | `icon-mark="true"` | `T` | Nombre del fichero PNG del icono en estado normal |
218
+ | `icon-touch="true"` | `T` | Nombre del fichero PNG del icono al estar seleccionado |
219
+ | `icon-big="true"` | `T` | Nombre del fichero PNG del icono grande en el popup |
220
+ | `circle-radius="true"` | `N` | Radio en pixeles del circulo de zona alrededor del marcador |
221
+
222
+ > **NOTA:** Los valores de `XCOORD` e `YCOORD` son coordenadas en pixeles relativas a la imagen definida en `imgbk`. No son coordenadas GPS.
223
+
224
+ ---
225
+
226
+ ### 7.13e ViewMode: slideview
227
+
228
+ **Cuando usarlo:** carruseles de imágenes, banners promocionales, onboarding de la app, presentaciones de productos, galería de fotos navegable una a una.
229
+
230
+ El slideview muestra los registros de uno en uno y permite desplazarse entre ellos con un gesto horizontal (o vertical). Si el ancho del prop es menor que el ancho de pantalla, pueden verse varios registros a la vez.
231
+
232
+ #### Declaración del prop tipo slideview
233
+
234
+ ```xml
235
+ <prop name="@MiSlider"
236
+ type="Z"
237
+ viewmode="slideview"
238
+ contents="MiSlider"
239
+ width="100%"
240
+ height="400p"
241
+ slide-circular="true"
242
+ autoslide-delay="5"
243
+ forceonchange="true"
244
+ onchange="refresh(@MiSlider)" />
245
+ <contents name="MiSlider" src="ContentSlider" />
246
+ ```
247
+
248
+ #### Coleccion de datos del slideview
249
+
250
+ Cada registro es una "diapositiva". Los campos con `visible="4"` se muestran en el slide. Los campos con `visible="1"` se muestran al editar el registro.
251
+
252
+ ```xml
253
+ <coll name="ContentSlider" title="slider"
254
+ sql="SELECT t1.* FROM ##PREF##banners t1"
255
+ objname="banners" updateobj="banners"
256
+ progid="ASData.CASBasicDataObj"
257
+ loadall="true"
258
+ notab="true">
259
+ <group name="General" id="1">
260
+ <!-- Contenido de cada slide -->
261
+ <prop name="IMAGEN" type="IMG" visible="4"
262
+ width="100%" height="400p" labelwidth="0" locked="true" />
263
+ <prop name="TITULO" type="T" visible="4"
264
+ labelwidth="0" locked="true"
265
+ text-align="center" fontsize="16" />
266
+ <prop name="DESCRIPCION" type="T" visible="4"
267
+ labelwidth="0" locked="true" lines="2"
268
+ text-align="center" fontsize="12" />
269
+ </group>
270
+
271
+ <!-- auto-selecteditem: se ejecuta en cada cambio automático de slide -->
272
+ <auto-selecteditem refresh="false" show-wait-dialog="false">
273
+ <action name="runscript">
274
+ <script language="javascript">
275
+ // self = objeto del slide que se esta mostrando
276
+ // lógica al pasar al siguiente slide automaticamente
277
+ </script>
278
+ </action>
279
+ </auto-selecteditem>
280
+
281
+ <!-- selecteditem: se ejecuta cuando el usuario toca un slide -->
282
+ <selecteditem refresh="false" show-wait-dialog="false">
283
+ <action name="runscript">
284
+ <script language="javascript">
285
+ // Acción al pulsar un slide
286
+ ui.showToast("Slide seleccionado: " + self.TITULO);
287
+ </script>
288
+ </action>
289
+ </selecteditem>
290
+ </coll>
291
+ ```
292
+
293
+ #### Atributos del prop slideview
294
+
295
+ | Atributo | Descripción |
296
+ |----------|-------------|
297
+ | `slide-circular="true"` | Al llegar al último slide vuelve al primero automáticamente |
298
+ | `autoslide-delay="N"` | Segundos entre cambios automáticos de slide. Sin este atributo no hay autoplay |
299
+ | `forceonchange="true"` | Fuerza el refresco al cambiar de slide |
300
+ | `orientation` | `horizontal` (por defecto) o `vertical` para desplazamiento vertical |
301
+
302
+ #### Eventos del slideview (en la coleccion de datos)
303
+
304
+ | Evento | Cuando se dispara |
305
+ |--------|-------------------|
306
+ | `selecteditem` | El usuario pulsa sobre un slide |
307
+ | `auto-selecteditem` | Cambia automáticamente al siguiente slide (solo con `autoslide-delay`) |
308
+
309
+ > **Diferencia clave entre eventos:** `selecteditem` requiere interaccion del usuario. `auto-selecteditem` se dispara con el autoplay sin interaccion.
310
+
311
+ #### Patron típico — Galería de imágenes con indicador de posición
312
+
313
+ ```xml
314
+ <!-- En la coleccion padre -->
315
+ <prop name="MAP_SLIDE_ACTUAL" type="N" visible="0" />
316
+
317
+ <prop name="@Galeria" type="Z" viewmode="slideview"
318
+ contents="Galeria" width="100%" height="300p"
319
+ slide-circular="false" forceonchange="true"
320
+ onchange="refresh(@Galeria)" />
321
+ <contents name="Galeria" src="ContentGaleria"
322
+ filter="IDPRODUCTO=##FLD_ID##" />
323
+ ```
324
+
325
+ ```xml
326
+ <!-- En ContentGaleria: al seleccionar actualiza el indicador en el padre -->
327
+ <selecteditem refresh="false" show-wait-dialog="false">
328
+ <action name="runscript">
329
+ <script language="javascript">
330
+ var idx = self.getOwnerCollection().getObjectIndex(self);
331
+ var total = self.getOwnerCollection().count();
332
+ self.getOwnerCollection().getOwnerObject().MAP_SLIDE_ACTUAL = (idx + 1);
333
+ </script>
334
+ </action>
335
+ </selecteditem>
336
+ ```
337
+
338
+ ---
339
+
340
+ ### 7.13f ViewMode: expanview
341
+
342
+ **Cuando usarlo:** árboles de categorías, estructuras padre-hijo, FAQs expandibles, organigramas, menus jerarquicos, cualquier dato con niveles anidados.
343
+
344
+ El expanview muestra una lista donde cada elemento puede expandirse para mostrar sus hijos. Requiere dos colecciones: la **coleccion padre** (nivel raiz) y la **coleccion hija** (elementos anidados). La coleccion hija se define como un `contents` embebido dentro de la coleccion padre.
345
+
346
+ #### Estructura general
347
+
348
+ ```
349
+ prop type="Z" viewmode="expanview"
350
+ └── ContentPadre (coleccion raiz, filter="IDPADRE IS NULL")
351
+ └── prop type="Z" contents="ContentHijo" (embebido en ContentPadre)
352
+ └── ContentHijo (filter="IDPADRE=##FLD_ID##")
353
+ ```
354
+
355
+ #### Paso 1 — Declarar el prop en la pantalla
356
+
357
+ ```xml
358
+ <frame name="frmArbol" width="98%" height="90%"
359
+ framebox="true" border-corner-radius="10" lmargin="1%">
360
+ <prop name="@ContentPadre"
361
+ type="Z"
362
+ viewmode="expanview"
363
+ contents="ContentPadre"
364
+ height="90%"
365
+ visible="1" />
366
+ <contents name="ContentPadre" src="ContentPadre"
367
+ autofocus="true"
368
+ filter="IDPADRE IS NULL" />
369
+ </frame>
370
+ ```
371
+
372
+ > `filter="IDPADRE IS NULL"` carga solo los nodos raiz. Los hijos se cargan dinámicamente al expandir cada nodo.
373
+
374
+ #### Paso 2 — Coleccion padre con contents hijo embebido
375
+
376
+ ```xml
377
+ <coll name="ContentPadre" title="arbol padre"
378
+ sql="SELECT t1.*,
379
+ t1.ICONO AS MAP_ICON,
380
+ (SELECT COUNT(ID) FROM ##PREF##categorias
381
+ WHERE IDPADRE = t1.ID) AS MAP_NUM_HIJOS
382
+ FROM ##PREF##categorias t1"
383
+ objname="categorias" updateobj="categorias"
384
+ progid="ASData.CASBasicDataObj"
385
+ edit-inrow="false" loadall="true" notab="true">
386
+
387
+ <group name="General" id="1">
388
+ <frame name="frmNodoPadre" width="100%" bgcolor="#FFFFFF">
389
+ <prop name="MAP_ICON" type="IMG" visible="4"
390
+ lmargin="20p" tmargin="20p" bmargin="20p"
391
+ width="80p" height="80p" />
392
+ <prop name="NOMBRE" type="T" visible="4"
393
+ textfont-bold="true" class="classgrid"
394
+ align="left|center" width="490p" height="80p"
395
+ newline="false" tmargin="20p" bmargin="20p" />
396
+ <prop name="MAP_NUM_HIJOS" type="T" visible="4"
397
+ text-forecolor="#666666" textfont-size="5"
398
+ class="classgrid" align="left|center"
399
+ width="110p" height="80p" newline="false"
400
+ tmargin="20p" bmargin="20p" />
401
+ </frame>
402
+
403
+ <!-- Contents hijo embebido dentro del padre -->
404
+ <prop name="@ContentHijo" type="Z" visible="1"
405
+ contents="ContentHijo" />
406
+ <contents name="ContentHijo" src="ContentHijo"
407
+ filter="IDPADRE=##FLD_ID##" />
408
+ </group>
409
+
410
+ <!-- onexpand: se ejecuta al expandir un nodo padre -->
411
+ <onexpand refresh="false">
412
+ <action name="runscript">
413
+ <script language="javascript">
414
+ // Refrescar la fila del padre al expandir
415
+ ui.refreshContentRow("ContentPadre",
416
+ self.getOwnerCollection().getObjectIndex(self));
417
+ </script>
418
+ </action>
419
+ </onexpand>
420
+
421
+ <!-- oncollapse: se ejecuta al colapsar un nodo padre -->
422
+ <oncollapse refresh="false">
423
+ <action name="runscript">
424
+ <script language="javascript">
425
+ ui.refreshContentRow("ContentPadre",
426
+ self.getOwnerCollection().getObjectIndex(self));
427
+ </script>
428
+ </action>
429
+ </oncollapse>
430
+ </coll>
431
+ ```
432
+
433
+ > **Los eventos `onexpand` y `oncollapse` son obligatorios** para que el árbol funcione correctamente y se actualice visualmente al abrir y cerrar nodos.
434
+
435
+ #### Paso 3 — Coleccion hija
436
+
437
+ La coleccion hija se define de forma independiente. El campo FK (`IDPADRE`) enlaza con el padre. El filter del `<contents>` usa `##FLD_ID##` para obtener el ID del nodo padre expandido.
438
+
439
+ ```xml
440
+ <coll name="ContentHijo" title="arbol hijo"
441
+ sql="SELECT t1.* FROM ##PREF##categorias t1"
442
+ objname="categorias" updateobj="categorias"
443
+ progid="ASData.CASBasicDataObj"
444
+ loadall="true" notab="true">
445
+
446
+ <group name="General" id="1">
447
+ <frame name="frmNodoHijo" width="640p" lmargin="80p"
448
+ bgcolor="#FFFFFF">
449
+ <prop name="NOMBRE" type="T" visible="4"
450
+ textfont-bold="true" text-forecolor="#666666"
451
+ class="classgrid" lmargin="20p" tmargin="20p" />
452
+ <prop name="DESCRIPCION" type="T" visible="4"
453
+ class="classgrid" lmargin="30p" bmargin="20p"
454
+ text-forecolor="#666666" textfont-size="5"
455
+ lines="2" fixed-lines="true" />
456
+ <!-- FK al padre -->
457
+ <prop name="IDPADRE" type="N" visible="0"
458
+ mapcol="ContentPadre" mapfld="ID" />
459
+ </frame>
460
+ </group>
461
+
462
+ <!-- selecteditem: acción al pulsar un nodo hijo -->
463
+ <selecteditem refresh="false" show-wait-dialog="false">
464
+ <action name="runscript">
465
+ <script language="javascript">
466
+ // Navegar al detalle del elemento seleccionado
467
+ ui.openEditView(self);
468
+ </script>
469
+ </action>
470
+ </selecteditem>
471
+ </coll>
472
+ ```
473
+
474
+ #### Atributos del prop expanview
475
+
476
+ | Atributo | Descripción |
477
+ |----------|-------------|
478
+ | `viewmode="expanview"` | Activa el modo árbol expandible |
479
+ | `autofocus="true"` | En el `<contents>` del nivel raiz — el primer nodo recibe el foco al cargar |
480
+ | `filter="IDPADRE IS NULL"` | En el `<contents>` del nivel raiz — carga solo los nodos sin padre |
481
+ | `filter="IDPADRE=##FLD_ID##"` | En el `<contents>` hijo — filtra los hijos del nodo padre expandido |
482
+
483
+ #### Eventos del expanview (en la coleccion padre)
484
+
485
+ | Evento | Cuando se dispara |
486
+ |--------|-------------------|
487
+ | `onexpand` | El usuario expande un nodo padre para ver sus hijos |
488
+ | `oncollapse` | El usuario colapsa un nodo padre ocultando sus hijos |
489
+
490
+ #### Regla: árboles de más de dos niveles
491
+
492
+ Para árboles de tres o más niveles, la coleccion hija puede a su vez contener otro `<contents>` con su propia coleccion nieta, siguiendo el mismo patron. Cada nivel usa `##FLD_ID##` para filtrar sus hijos respecto al nivel superior.
493
+
494
+ ---
495
+
496
+ ### 7.13g ViewMode: gridview
497
+
498
+ **Cuando usarlo:** galerías de fotos, catálogos de productos con imagen, colecciones de recursos visuales donde se quiere mostrar varios elementos por fila en cuadricula.
499
+
500
+ El `gridview` muestra los registros en una cuadricula de N columnas, similar a la galería de fotos del dispositivo. Se controla el número de columnas con `gallery-columns`.
501
+
502
+ #### Declaración del prop tipo gridview
503
+
504
+ ```xml
505
+ <prop name="@ContentFotos"
506
+ type="Z"
507
+ viewmode="gridview"
508
+ gallery-columns="4"
509
+ contents="ContentFotos"
510
+ width="90%"
511
+ height="-2"
512
+ lmargin="5%"
513
+ locked="true"
514
+ show-no-data="true"
515
+ no-data-text="No hay fotos. Pulse + para añadir."
516
+ no-data-fontsize="8"
517
+ onchange="refresh" />
518
+ <contents name="ContentFotos" src="ContentFotosSrc"
519
+ filter="IDSOLICITUD=##FLD_ID##" />
520
+ ```
521
+
522
+ #### Coleccion de datos del gridview
523
+
524
+ Cada registro ocupa una celda de la cuadricula. Los campos con `visible="4"` se muestran en cada celda.
525
+
526
+ ```xml
527
+ <coll name="ContentFotosSrc" title="fotos"
528
+ sql="SELECT t1.* FROM ##PREF##fotos t1"
529
+ objname="fotos" updateobj="fotos"
530
+ progid="ASData.CASBasicDataObj"
531
+ loadall="true" notab="true">
532
+ <group name="General" id="1">
533
+ <!-- Imagen que se muestra en la celda de la cuadricula -->
534
+ <prop name="FOTO" type="IMG" visible="4"
535
+ width="100%" height="100%"
536
+ labelwidth="0" locked="true"
537
+ keep-aspect-ratio="true" />
538
+ <!-- Etiqueta opcional bajo la imagen -->
539
+ <prop name="NOMBRE" type="T" visible="4"
540
+ labelwidth="0" locked="true"
541
+ text-align="center" textfont-size="5" />
542
+ </group>
543
+ </coll>
544
+ ```
545
+
546
+ #### Atributos del prop gridview
547
+
548
+ | Atributo | Descripción |
549
+ |----------|-------------|
550
+ | `gallery-columns` | Número de columnas de la cuadricula. Ej: `"3"`, `"4"` |
551
+ | `orientation` | `horizontal` (por defecto) o `vertical` |
552
+ | `show-no-data` | `true` muestra un mensaje cuando no hay datos |
553
+ | `no-data-text` | Texto a mostrar cuando el contents esta vacio |
554
+ | `no-data-fontsize` | Tamaño de fuente del texto de sin datos |
555
+
556
+ #### Patron típico — galería con FAB para añadir
557
+
558
+ ```xml
559
+ <!-- Galeria -->
560
+ <prop name="@GaleriaFotos" type="Z" viewmode="gridview"
561
+ gallery-columns="3" contents="GaleriaFotos"
562
+ width="100%" height="-2" locked="true"
563
+ show-no-data="true"
564
+ no-data-text="Pulse + para añadir fotos" />
565
+ <contents name="GaleriaFotos" src="ContentFotosSrc"
566
+ filter="IDREGISTRO=##FLD_ID##" />
567
+
568
+ <!-- Botón flotante para añadir fotos (FAB) -->
569
+ <frame name="frmFAB" floating="true" top="900p" left="610p"
570
+ width="90p" height="90p">
571
+ <prop name="BTN_ADD" type="B" visible="1" labelwidth="0"
572
+ method="ExecuteNode(nuevaFoto)"
573
+ width="75p" img="add.png" imgsel="add_click.png" />
574
+ </frame>
575
+ ```
576
+
577
+ ---
578
+
579
+ ### 7.13h Patron: contentselitem (selecteditem sin navegación)
580
+
581
+ **Cuando usarlo:** listas donde al tocar un elemento se muestran sus datos en la misma pantalla sin abrir una ventana nueva. Útil para paneles maestro-detalle, selectores de elemento activo, listas con preview.
582
+
583
+ Este no es un `viewmode` distinto — es un **patron de uso** del contents normal (grid por defecto) combinado con `<selecteditem>` en la coleccion hija y `cell-selected-bgcolor` para resaltar la fila seleccionada.
584
+
585
+ #### Estructura del patron
586
+
587
+ ```xml
588
+ <!-- En la coleccion padre: campos para mostrar el elemento seleccionado -->
589
+ <prop name="MAP_NOMBRESEL" type="T" visible="1"
590
+ labelwidth="0" class="classTsinborde" />
591
+ <prop name="MAP_LINEASEPARAR" type="B" visible="1"
592
+ disablevisible="MAP_NOMBRESEL=''"
593
+ bgcolor="#333333" labelwidth="0"
594
+ width="300p" height="5p" locked="true" />
595
+
596
+ <!-- Botones de acción flotantes — solo visibles cuando hay selección -->
597
+ <frame name="frmAcciones" floating="true"
598
+ top="75p" left="550p" width="200p" height="120p"
599
+ disablevisible="MAP_NOMBRESEL=''">
600
+ <prop name="BTN_EDITAR" type="B" visible="1" labelwidth="0"
601
+ method="ExecuteNode(editar)" width="75p"
602
+ img="ok.png" imgsel="ok_click.png" />
603
+ <prop name="BTN_BORRAR" type="B" visible="1" labelwidth="0"
604
+ method="ExecuteNode(eliminar)" width="75p"
605
+ img="delete.png" imgsel="delete_click.png"
606
+ newline="false" lmargin="6p" />
607
+ </frame>
608
+
609
+ <!-- Contents con edicion desactivada — el selecteditem gestiona la selección -->
610
+ <prop name="@content" type="Z" contents="content"
611
+ disableedit="1=1"
612
+ height="70%" width="100%"
613
+ bgcolor="#FFFFFF" />
614
+ <contents name="content" src="ContentDatosSelItem" />
615
+ <prop name="MAP_IDSELECCIONADO" visible="0" type="N" />
616
+ ```
617
+
618
+ #### Coleccion hija con selecteditem y resaltado
619
+
620
+ ```xml
621
+ <coll name="ContentDatosSelItem" title="lista"
622
+ sql="SELECT t1.* FROM ##PREF##mapa_datos t1"
623
+ objname="mapa_datos" updateobj="mapa_datos"
624
+ progid="ASData.CASBasicDataObj"
625
+ loadall="true" notab="true"
626
+ cell-even-color="#FFFFFF"
627
+ cell-odd-color="#F2F2F2"
628
+ cell-selected-bgcolor="#C9E5EF">
629
+
630
+ <group name="General" id="1">
631
+ <prop name="IMAGEN" type="IMG" width="115p" height="118p"
632
+ visible="4" tmargin="2p" lmargin="0" />
633
+ <frame name="frm1" newline="false" width="600p"
634
+ lmargin="5p" height="120p">
635
+ <prop name="NOMBRE" type="T" class="classgrid"
636
+ visible="4" locked="true" />
637
+ <prop name="DIRECCION" type="T" class="classgrid"
638
+ text-forecolor="#666666" textfont-size="5"
639
+ visible="4" locked="true"
640
+ lines="2" fixed-lines="true" />
641
+ </frame>
642
+ </group>
643
+
644
+ <!-- selecteditem: en lugar de abrir el objeto, actualiza campos del padre -->
645
+ <selecteditem
646
+ refresh-owner="MAP_NOMBRESEL,MAP_LINEASEPARAR,frmAcciones"
647
+ show-wait-dialog="false">
648
+ <action name="runscript">
649
+ <script language="javascript">
650
+ // getOwnerCollection().getOwnerObject() = objeto padre
651
+ var padre = self.getOwnerCollection().getOwnerObject();
652
+ padre.MAP_NOMBRESEL = self.NOMBRE;
653
+ padre.MAP_IDSELECCIONADO = self.ID;
654
+ // Guardar el indice de la fila seleccionada
655
+ padre.MAP_IDLINEA = self.getOwnerCollection()
656
+ .getObjectIndex(self);
657
+ </script>
658
+ </action>
659
+ </selecteditem>
660
+ </coll>
661
+ ```
662
+
663
+ #### Atributos clave del patron contentselitem
664
+
665
+ | Atributo | Donde | Descripción |
666
+ |----------|-------|-------------|
667
+ | `cell-selected-bgcolor="#C9E5EF"` | En `<coll>` | Color de fondo de la fila seleccionada actualmente |
668
+ | `disableedit="1=1"` | En el `prop type="Z"` | Desactiva la apertura del objeto al tocar — el `selecteditem` lo gestiona todo |
669
+ | `refresh-owner="campo1,campo2"` | En `<selecteditem>` | Lista de campos del padre que se refrescan automáticamente tras la selección |
670
+ | `getOwnerCollection().getOwnerObject()` | En el script | Accede al objeto padre desde dentro del `selecteditem` |
671
+ | `getOwnerCollection().getObjectIndex(self)` | En el script | Obtiene el índice de la fila seleccionada |
672
+
673
+ #### Diferencia con edición directa
674
+
675
+ | Comportamiento | Edición directa (por defecto) | Patron contentselitem |
676
+ |----------------|-------------------------------|----------------------|
677
+ | Al tocar una fila | Abre el objeto en edición | Actualiza campos del padre |
678
+ | `disableedit` | No necesario | `disableedit="1=1"` en el prop Z |
679
+ | `selecteditem` | Opcional | **Obligatorio** con la lógica de actualización |
680
+ | Navegación | Abre nueva pantalla | Todo en la misma pantalla |
681
+