PBToolboxAI v4 ← Site

tilesbox — u_pbt_tilesbox #

← Referencia de componentes · Índice de la guía

Panel de mosaicos agrupados al estilo de una pantalla de inicio: cuatro tamaños de mosaico, colores, distintivos, mosaicos animados, grupos plegables y reorganización con el ratón.

▶ Verlo en vivo — Aplicación de demostración, mosaico Tiles box: la vista previa, el código que lo genera y esta página, uno al lado del otro.


De un vistazo #

Userobjectu_pbt_tilesbox
Clases de itemsn_pbt_tilesbox_group (grupo) → n_pbt_tilesbox_tile (mosaico)
Sirve paraOfrecer una pantalla de inicio o un lanzador de funciones: mosaicos en los que se puede hacer clic, legibles desde lejos, ordenados por tema
Opciones opt-inib_reorderable: mover y redimensionar los mosaicos con el ratón

Inicio rápido #

// event open de la ventana

// Un mosaico se anade en su DIRECCION : el grupo, y luego su propio identificador
uo_tiles.of_add_group(/*key*/ "office", /*title*/ "Gestión")

// Luego sus mosaicos, cada uno con su tamanouo_tiles.of_add_tile(/*keys*/ "office/clients",   /*label*/ "Clientes",   /*icon_file*/ "mono:img\clients.svg",   /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "office/invoices",  /*text*/ "Facturas",  /*image*/ "mono:img\factures.svg",  /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "office/stock",     /*text*/ "Almacén",     /*image*/ "mono:img\stock.svg",     /*size*/ "small")
// event ue_tile_clicked de uo_tiles: (string as_keys)
choose case as_keys
    case "office/clients"  ; open(w_clients)
    case "office/invoices" ; open(w_invoices)
    case "office/stock"    ; open(w_stock)
end choose

El modelo: grupos y mosaicos #

El panel contiene grupos, cada uno con su título y su encabezado plegable. Los mosaicos pertenecen a un grupo: su identificador solo es único dentro de ese grupo. El acceso pasa por tanto siempre por la ruta completa. Las adiciones viven en el componente: un handle solo lleva propiedades.

// Ruta obligatoria: grupo y luego mosaico
uo_tiles.of_tile(/*keys*/ "office/invoices").is_badge = "12"

Los eventos también llevan la dirección completa (as_keys, el grupo y luego el mosaico). Véase Base común · Los items.


Propiedades #

PropiedadTipoPredeterminadoFunción
ib_reorderablebooleanfalsePermite al usuario reorganizar los mosaicos: con el ratón, o desde el teclado con Ctrl+Izquierda/Derecha (un puesto en el grupo, en el sentido de lectura) y Ctrl+Arriba/Abajo (hacia el grupo anterior o siguiente); el clic derecho cambia el tamaño. Ratón y teclado activan el mismo ue_tile_moved
is_scrollstringSCROLL_HORIZONTALSentido de desplazamiento: SCROLL_VERTICAL (los mosaicos pasan a la línea siguiente) o SCROLL_HORIZONTAL (columnas al estilo de una pantalla de inicio)
ib_show_group_headersbooleantruefalse oculta los encabezados de grupo. Resulta útil cuando el panel contiene un solo grupo: no hay nada que nombrar y el encabezado se limita a consumir altura. Sin encabezado ya no hay galón: los grupos se muestran siempre desplegados
ii_anim_durationinteger180Duración en milisegundos de la animación de plegado / desplegado de un grupo; 0 = instantánea
ii_tile_unitinteger0Tamaño base de un mosaico, en píxeles: cada formato (pequeño, mediano, ancho, grande) es un múltiplo suyo, de modo que un valor hace todo el tablero más denso o más aireado. 0 lo devuelve al tema
ii_badge_sizeinteger0Altura de los distintivos de mosaico en píxeles, para toda la caja (0 = el tamaño que viene del tema). El tamaño de la fuente se ajusta solo. El color de un distintivo pertenece al mosaico porque significa algo; su tamaño no
is_theme_stylestring""Estilo visual del componente (constantes THEME_STYLE_*); vacío = el de la aplicación, seguido en cada cambio
is_theme_modestring""Variante clara u oscura (constantes THEME_MODE_*); vacío = la de la aplicación, seguida en cada cambio
il_theme_accentlong-1Color de acento de este componente (-1 = acento de la aplicación, o el del tema)
is_tooltipstring""Tooltip simple mostrado al pasar el ratón por el componente
is_super_tooltip_titlestring""Título del tooltip enriquecido (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto del tooltip enriquecido (se acepta el marcado enriquecido)
is_super_tooltip_imagestring""Imagen del tooltip enriquecido

Métodos #

MétodoFunción
of_group (string as_key) → n_pbt_tilesbox_groupDevuelve el handle de un grupo (creado en el primer acceso). Sobre un grupo que no existe no escribe nada — nunca crea el grupo, lo hace of_add_group; una clave que no puede nombrar un grupo (vacía, con / o ``) da un handle inerte que se relee vacío
of_add_group (string as_key, string as_title) → longAñade un grupo. Devuelve 0 una vez aplicado, -5 si la clave está vacía, contiene un / o un `, o ya está tomada, -2` si el componente no está creado
of_add_tile (string as_keys, string as_text, string as_image, string as_size) → longAñade un mosaico en su dirección, "office/clients": el grupo donde aterriza y luego su propio identificador. Devuelve 0 una vez aplicado, -5 si la dirección no es grupo/mosaico, si el grupo no se añadió con of_add_group, si la clave ya está tomada en ese grupo (o vacía, o contiene un `), -2` si el componente no está creado. Una sobrecarga omite el icono y el tamaño
of_tile (string as_keys) → n_pbt_tilesbox_tileDevuelve el handle de un mosaico, por su dirección (creado en el primer acceso). Una dirección que no es grupo/mosaico da un handle inerte: no escribe nada y se lee vacío
of_add_live_item (string as_keys, string as_text) → longAñade una cara a la banda animada de un mosaico, en su dirección; a partir de dos caras, el mosaico las hace desfilar. La primera cara borra is_live_text; of_tile(dirección).of_count() lee el número de caras. Devuelve 0 una vez aplicado, -5 con un texto vacío o si ningún mosaico vive en esa dirección, -2 si el componente no está creado
of_clear_live_items (string as_keys) → longVacía la banda animada de un mosaico: deja de desfilar y vuelve a su cara simple. Devuelve 0 una vez aplicado, -5 si ningún mosaico vive en esa dirección, -2 si el componente no está creado
of_remove_group (string as_key)Elimina un grupo y todos sus mosaicos. Devuelve 0 una vez aplicado, -5 si no existe tal grupo, -2 si el componente no está creado
of_insert_tile (string as_keys, string as_text, integer ai_index)Inserta un mosaico en una posición precisa dentro de su grupo (posición contada a partir de 1). Devuelve 0 una vez aplicado, -5 por los mismos rechazos que of_add_tile, -2 si el componente no está creado
of_insert_tile (string as_keys, string as_text, string as_image, string as_size, integer ai_index)Ídem, con el icono y el tamaño (small / medium / wide / large): un mosaico es una imagen con una etiqueta debajo, y su tamaño se ve en la cuadrícula. Devuelve 0 una vez aplicado, -5 por los mismos rechazos que of_add_tile, -2 si el componente no está creado
of_move_tile (string as_keys, integer ai_index)Mueve un mosaico existente a otra posición de su grupo, conservando su estado. Devuelve 0 una vez aplicado, -5 si ningún mosaico vive en esa dirección, -2 si el componente no está creado
of_remove_tile (string as_keys)Elimina un solo mosaico, el resto del panel se conserva. Devuelve 0 una vez aplicado, -5 si ningún mosaico vive en esa dirección, -2 si el componente no está creado
of_clear ( )Vacía el panel (grupos y mosaicos); los handles entregados para ellos se liberan. Devuelve 0 una vez aplicado, -2 si el componente no está creado
of_get_layout ( )Relee la disposición actual en JSON: los grupos en su orden, plegados o no, visibles o no, y sus mosaicos en orden con su tamaño y su visibilidad. Un texto opaco: guárdelo tal cual y devuélvalo después a of_set_layout
of_set_layout (string as_state_json)Restaura una disposición leída con of_get_layout o recibida con ue_layout_changed: orden, grupos plegados, tamaños y visibilidad. Un mosaico se encuentra por su grupo y su clave; lo que la disposición no nombra conserva su lugar. No lanza ningún evento. Devuelve 0 una vez aplicado, -5 ante un texto vacío o que no es JSON, -2 si el componente no está creado
of_reset ( )Vacía el contenido y devuelve las propiedades a sus valores predeterminados. Devuelve 0 una vez aplicado, -2 si el componente no está creado

En un grupo — n_pbt_tilesbox_group #

MiembroTipoPredeterminadoFunción
is_titlestringla claveTítulo mostrado en el encabezado, se acepta texto enriquecido con etiquetas
ib_collapsedbooleanfalseGrupo plegado: sus mosaicos quedan ocultos bajo el encabezado. Fijarlo lanza ue_group_toggled cuando el estado cambia, como un clic en el encabezado
ib_enabledbooleantrueGrupo entero atenuado e inerte: su encabezado ya no lo pliega, sus mosaicos ya no responden, ningún mosaico puede soltarse en él
ib_visiblebooleantrueGrupo oculto, sin eliminarlo del modelo
il_back_color · il_text_color · il_back_color_hover · il_text_color_hover · il_accentlong-1Colores del encabezado del grupo — fondo, título, ambos bajo el puntero, y un filete de acento bajo el encabezado. No bajan a los mosaicos, que conservan los suyos

En un mosaico — n_pbt_tilesbox_tile #

MiembroTipoPredeterminadoFunción
is_titlestring""Texto mostrado en la ficha. Puesto por of_add_tile; escribirlo aquí lo cambia, leerlo dice lo que la ficha muestra ahora
is_imagestring""Icono de la ficha (ruta de disco o resources.dll:nombre). Una cadena vacía quita el icono
is_sizestringSIZE_MEDIUMTamaño: SIZE_SMALL, SIZE_MEDIUM, SIZE_WIDE, SIZE_LARGE
il_back_color · il_text_colorlong-1Fondo y texto de este mosaico, como RGB(r,g,b) (-1 = lo que da el tema)
il_back_color_hover · il_text_color_hoverlong-1Los dos mismos, pero bajo el puntero
is_badgestring""Distintivo mostrado en la esquina del mosaico (un contador, un estado breve)
il_badge_colorlong-1Fondo del distintivo, en RGB de PowerBuilder (-1 = el color que viene del tema; 0 es el negro)
is_live_textstring""Texto fijo superpuesto al mosaico; la primera cara de of_add_live_item lo borra (se relee entonces vacío), se acepta texto enriquecido con etiquetas
ib_enabledbooleantrueMosaico atenuado y no clicable
ib_visiblebooleantrueMosaico oculto, sin retirarlo de su grupo

Los iconos aceptan todas las formas reconocidas por la biblioteca: ruta, mono:, tint:, recurso de DLL. En un mosaico grande, es preferible una imagen nítida en alta definición o un SVG.


Los cuatro tamaños #

TamañoEspacio ocupadoUso habitual
small1 casillaAcceso directo secundario; la etiqueta no se muestra, el tooltip toma el relevo
medium2 × 2 casillasTamaño de referencia: icono y etiqueta
wide4 × 2 casillasMosaico alargado, ideal para un texto animado
large4 × 4 casillasMosaico protagonista de la pantalla

Eventos #

EventoSe activa cuando
ue_tile_clicked (string as_keys)Se hace clic en un mosaico
ue_tile_moved (string as_keys, string as_to_key, long al_index)El usuario ha movido un mosaico, con el ratón o con Ctrl+flechas (of_move_tile no activa nada): as_keys es la dirección de partida, as_to_key el grupo de destino, al_index la nueva posición
ue_group_toggled (string as_key, boolean ab_collapsed)Un grupo se pliega o se despliega: desde su encabezado, o por su ib_collapsed fijado por su código (nada cuando ya está en ese estado)
ue_tile_context (string as_keys)Clic derecho en un mosaico
ue_tile_resized (string as_keys, string as_size)El usuario dio otro tamaño a un mosaico desde su menú del clic derecho (solo se muestra mientras ib_reorderable vale true); as_size lleva el nuevo tamaño
ue_layout_changed (string as_layout_json)El usuario cambió la disposición: un mosaico movido, un mosaico redimensionado desde su menú, un grupo plegado o desplegado desde su encabezado. Lleva la disposición entera, el mismo texto que of_get_layout. Lo que la aplicación cambia por código no lo lanza (el ib_collapsed de un grupo solo lanza ue_group_toggled)
ue_ready ( )El componente ha terminado de cargarse; todo lo enviado antes se ha reproducido
ue_runtime_missing ( )El runtime WebView2 está ausente: el componente permanece vacío
ue_bg_color (long al_color)El componente ha calculado el color de fondo de su tema; el userobject ya lo ha adoptado (backcolor)

Ejemplos #

Tamaños mezclados en un mismo grupo #

// Partir de una caja vacia, con un grupo
uo_tiles.of_clear()
uo_tiles.of_add_group(/*key*/ "home", /*title*/ "Inicio")

// Cuatro mosaicos, de cuatro tamanos
uo_tiles.of_add_tile(/*keys*/ "home/dashboard", /*text*/ "Cuadro de mando", /*image*/ "mono:img\chart.svg",  /*size*/ "large")
uo_tiles.of_add_tile(/*keys*/ "home/clients", /*text*/ "Clientes",         /*image*/ "mono:img\users.svg",  /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "home/agenda",  /*text*/ "Agenda",          /*image*/ "mono:img\cal.svg",    /*size*/ "wide")
uo_tiles.of_add_tile(/*keys*/ "home/help",    /*text*/ "Ayuda",            /*image*/ "mono:img\help.svg",   /*size*/ "small")

Distintivo, color y mosaico animado #

// Local variables
n_pbt_tilesbox_tile lnv_tile

// Un distintivo senala un numero de elementos pendientes
uo_tiles.of_tile(/*keys*/ "home/clients").is_badge = String(ll_new_count)

// Rojo cuando el retraso pasa a ser critico, color del tema en caso contrario (-1)
if ll_new_count > 50 then
    uo_tiles.of_tile(/*keys*/ "home/clients").il_badge_color = RGB(/*red*/ 200, /*green*/ 30, /*blue*/ 30)
else
    uo_tiles.of_tile(/*keys*/ "home/clients").il_badge_color = -1
end if

// Un color propio destaca un mosaico : fondo, texto y lo que cada uno
// pasa a ser bajo el puntero
lnv_tile = uo_tiles.of_tile(/*keys*/ "home/dashboard")
lnv_tile.il_back_color = RGB(/*red*/ 0, /*green*/ 103, /*blue*/ 192)
lnv_tile.il_back_color_hover = RGB(/*red*/ 0, /*green*/ 80, /*blue*/ 150)
lnv_tile.il_text_color = RGB(/*red*/ 255, /*green*/ 255, /*blue*/ 255)

// Mosaico ANIMADO: cada cara anadida desfila por turno sobre el mosaico. Una
// cara se anade desde el COMPONENTE, en la direccion del mosaico
uo_tiles.of_clear_live_items(/*keys*/ "home/agenda")
uo_tiles.of_add_live_item(/*keys*/ "home/agenda", /*text*/ "3 citas hoy")
uo_tiles.of_add_live_item(/*keys*/ "home/agenda", /*text*/ "Reunión de equipo a las 14:00")
uo_tiles.of_add_live_item(/*keys*/ "home/agenda", /*text*/ "2 avisos con retraso")

Un texto fijo en lugar de un desplazamiento #

// is_live_text pone UN texto permanente sobre el mosaico (se acepta texto enriquecido con etiquetas)
uo_tiles.of_tile(/*keys*/ "home/dashboard").is_live_text = "[b]48[/b] pedidos del día"

Grupos plegables #

// Local variables
n_pbt_tilesbox_group lnv_admin

// Un grupo y sus dos mosaicos, y luego un handle del grupo
uo_tiles.of_add_group(/*key*/ "admin", /*title*/ "Administración")
uo_tiles.of_add_tile(/*keys*/ "admin/users",  /*text*/ "Usuarios", /*image*/ "mono:img\users.svg", /*size*/ "medium")
uo_tiles.of_add_tile(/*keys*/ "admin/params", /*text*/ "Parámetros", /*image*/ "mono:img\gear.svg",  /*size*/ "medium")
lnv_admin = uo_tiles.of_group(/*key*/ "admin")

// Este grupo arranca plegado: el usuario lo abre si lo necesita
lnv_admin.ib_collapsed = true

// Un grupo entero tambien puede atenuarse segun los permisos
lnv_admin.ib_enabled = (is_profile = "ADMIN")
// event ue_group_toggled de uo_tiles
if as_key = "admin" and not ab_collapsed then of_trace("Apertura del panel de administración")

Un panel de grupo único, sin encabezado #

// Un solo grupo no tiene nada que nombrar : su encabezado solo consume altura.
// Sin encabezado, tampoco hay galon : los mosaicos permanecen siempre visibles.
uo_tiles.ib_show_group_headers = false
uo_tiles.of_add_group(/*key*/ "all", /*title*/ "")

Mover un mosaico entre dos grupos #

Con ib_reorderable = true, el usuario arrastra un mosaico a donde quiere, incluso de un grupo a otro. El evento ue_tile_moved entrega los dos grupos y la nueva posición. Desde el teclado, el mosaico con el foco avanza o retrocede un puesto con Ctrl+Izquierda/Derecha (en el sentido de lectura: invertido de derecha a izquierda) y pasa al grupo anterior o siguiente con Ctrl+Arriba/Abajo — el mismo ue_tile_moved, los mismos rechazos (clave ya ocupada, grupo desactivado o plegado). La tecla Tab solo se detiene una vez por grupo: las flechas recorren los mosaicos.

// Dejar que el usuario reordene los mosaicos : false por defecto, hay que pedirlo
uo_tiles.ib_reorderable = true
// event ue_tile_moved de uo_tiles
// as_keys = de donde viene, as_to_key = adonde va, al_index = posicion
n_pbt_utils lnv_utils   // autoinstantiate : nada que crear, nada que destruir
if lnv_utils.of_parent(/*keys*/ as_keys) <> as_to_key then
    of_trace("Mosaico " + lnv_utils.of_leaf(/*keys*/ as_keys) + " movido de " + lnv_utils.of_parent(/*keys*/ as_keys) + " a " + as_to_key)
end if
// event ue_layout_changed de uo_tiles: conservar la disposicion elegida
is_layout_json = as_layout_json
// En la siguiente apertura: restituir la pantalla tal como el usuario la habia ordenado
if is_layout_json <> "" then uo_tiles.of_set_layout(/*state_json*/ is_layout_json)

Para fijar la pantalla, basta con desactivar la reorganización:

// Freeze the screen : the tiles stay where they are
uo_tiles.ib_reorderable = false

Reorganizar desde el código #

// Colocar el mosaico "help" al principio de su grupo (posiciones contadas a partir de 1)
uo_tiles.of_move_tile(/*keys*/ "home/help", /*index*/ 1)

// Insertar un nuevo mosaico en segunda posicion
uo_tiles.of_insert_tile(/*keys*/ "home/quotes", /*text*/ "Presupuestos", /*index*/ 2)

// Retirar un mosaico sin tocar el resto
uo_tiles.of_remove_tile(/*keys*/ "home/help")

// Cada llamada devuelve -5 si la direccion no nombra nada (o, al insertar, una clave ya tomada)

Reaccionar al clic derecho #

// event ue_tile_context de uo_tiles: (as_keys)
// Retener el mosaico afectado y abrir despues su propio menu contextual
n_pbt_utils lnv_utils   // autoinstantiate : nada que crear, nada que destruir

// Una sola direccion : dividirla si hacen falta las dos mitades.
is_target_group = lnv_utils.of_parent(/*keys*/ as_keys)
is_target_tile = lnv_utils.of_leaf(/*keys*/ as_keys)
of_open_tile_menu(PointerX(), PointerY())

Buenas prácticas #

Heredado de la base común #

Estos miembros existen en todos los componentes visuales — no son propios de este. Se detallan una sola vez, en los capítulos transversales; esta tabla solo dice dónde leerlos.

MiembrosFunciónDetallado en
of_count · of_keys_at · of_hasRecorrer lo que el componente contiene3.2 Los items
of_resetPoner el componente a cero3.6 Poner un componente a cero: of_reset()
of_register_shortcut · of_clear_shortcutsAtajos de teclado del componente3.5 Los atajos de teclado
of_is_created · of_is_ready · of_get_last_errorSi ha nacido, si está listo, qué ha fallado3.7 Diagnóstico
of_save_as_png · of_save_as_jpgExportar el render como imagen3.8 Exportar la representación como imagen
of_set_redrawAgrupar los cambios en un solo repintado3.10 Buenas prácticas
of_preload_iconsIconos mostrados sin retardoVisualización instantánea: of_icon
of_set_translationTraducir una etiqueta del componente5.2 Adaptar una etiqueta: of_set_translation
of_focus_webviewDar el foco al componente6.4 Teclado y foco
of_print · of_print_to_pdfImprimir, o escribir un PDF6.9 Imprimir
of_set_property · of_get_property · of_component_nameControlar una propiedad por su nombre3.1 El motor de propiedades

Dos ayudas no se heredan: of_icon y of_escape_markup viven en n_pbt_utils. Declare uno — n_pbt_utils lnv_utils, nada que crear — y llámelas sobre él.

← Referencia de componentes · Índice de la guía