listbar — u_pbt_listbar #
← Referencia de componentes · Índice de la guía
Barra de navegación lateral: secciones plegables en acordeón que contienen entradas con icono, con banda de acento sobre la entrada actual y plegado en riel de iconos.
▶ Verlo en vivo — Aplicación de demostración, mosaico Listbar: la vista previa, el código que lo genera y esta página, uno al lado del otro.
De un vistazo #
| Userobject | u_pbt_listbar |
| Clases de items | n_pbt_listbar_section (sección) → n_pbt_listbar_item (entrada) |
| Sirve para | Sustituir un menú lateral improvisado a base de botones por una navegación estructurada, con tema y plegable |
| Opciones opt-in | ib_auto_width, ib_reorderable |
Es el único componente de la biblioteca que publica ib_auto_width: su anchura natural sí tiene sentido, ya que el riel plegado es bastante más estrecho que la barra desplegada. Además, el caso habitual ya está cubierto sin activar nada — ib_collapsed = true estrecha la barra hasta el riel, y le devuelve su anchura al desplegarla.
Inicio rápido #
// evento open de la ventana
uo_nav.of_add_section(/*key*/ "nav", /*titulo*/ "Navegación")
uo_nav.of_add_item(/*keys*/ "nav/accueil", /*etiqueta*/ "Inicio", /*icono*/ "mono:img\home.svg")
uo_nav.of_add_item(/*keys*/ "nav/documents", /*etiqueta*/ "Documentos", /*icono*/ "mono:img\doc.svg")
uo_nav.of_add_item(/*keys*/ "nav/recherche", /*etiqueta*/ "Búsqueda", /*icono*/ "mono:img\find.svg")
uo_nav.of_add_section(/*key*/ "config", /*titulo*/ "Parámetros")
uo_nav.of_add_item(/*keys*/ "config/preferences", /*etiqueta*/ "Preferencias", /*icono*/ "mono:img\gear.svg")
// La seleccion se aplica a la ENTRADA, por su ruta completa
uo_nav.of_select_item("nav", "accueil")
// evento ue_selection_changed de uo_nav : (string as_from_keys, string as_keys)
choose case as_keys
case "nav/accueil" ; of_ouvrir_accueil()
case "nav/documents" ; of_ouvrir_documents()
case "config/preferences"; of_ouvrir_preferences()
end choose
Dos niveles, una ruta obligatoria #
Un identificador de entrada solo es único dentro de su sección: no existe, por tanto, ningún atajo hacia la entrada. Todo acceso pasa por la sección, lo que hace que la escritura no sea ambigua — véase Jerarquías.
// Componente -> seccion -> entrada -> propiedad
uo_nav .of_section("nav") .of_item("docs") .is_text = "Documents"
Los eventos también llevan la ruta completa, y con ella la entrada abandonada: ue_selection_changed(as_from_keys, as_keys).
Propiedades #
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
ib_collapsed | boolean | false | true pliega la barra en un riel de iconos: las etiquetas desaparecen, los iconos siguen siendo pulsables |
ib_auto_width | boolean | false | Opt-in: lo mismo para la anchura, incluida la desplegada (la barra se ajusta a la etiqueta más larga). El plegado en riel, por su parte, ya se estrecha por sí solo; ue_auto_width lo acompaña en ambos casos |
ib_reorderable | boolean | false | Opt-in: el usuario puede desplazar una entrada con el ratón. El desplazamiento permanece dentro de su sección — un identificador de entrada solo es único allí, así que cruzar arriesgaría dos claves idénticas (activa ue_item_reordered) |
ib_veto_selection | boolean | true | Preguntar antes de que la selección se desplace (activa ue_selection_changing, que puede rechazarla). Activo de forma predeterminada: no programar nada deja pasar siempre. Póngalo a false para suprimir la ida y vuelta hasta PowerBuilder (~35 ms) donde se notaría — navegación por teclado, selección desplazada en bucle |
is_theme_style | string | fluent | Estilo visual del componente (constantes THEME_STYLE_*) |
is_theme_mode | string | light | Variante clara u oscura (constantes THEME_MODE_*) |
il_theme_accent | long | -1 | Color de acento de este componente (-1 = acento del tema) |
is_tooltip | string | "" | Tooltip simple mostrado al pasar el ratón por el componente |
is_super_tooltip_title | string | "" | Título del tooltip enriquecido (prevalece sobre is_tooltip) |
is_super_tooltip_text | string | "" | Texto del tooltip enriquecido (se acepta el marcado enriquecido) |
is_super_tooltip_image | string | "" | Imagen del tooltip enriquecido |
Propiedades de una sección — n_pbt_listbar_section #
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
is_title | string | "" | Título de la sección. Acepta el texto enriquecido con etiquetas. Un título vacío no muestra ninguna fila de encabezado: la sección se convierte en una simple agrupación invisible |
ib_collapsed | boolean | false | Acordeón: true pliega las entradas de esta sección. El encabezado permanece visible y su galón gira |
Propiedades de una entrada — n_pbt_listbar_item #
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
is_text | string | "" | Etiqueta de la entrada, modificable en caliente sin reconstruir la barra. Acepta el texto enriquecido con etiquetas |
is_image | string | "" | Icono, modificable en caliente (formas aceptadas: ruta, mono:, tint:, recurso de DLL) |
ib_enabled | boolean | true | false atenúa la entrada y bloquea su clic |
ib_visible | boolean | true | false oculta la entrada sin retirarla de la barra |
of_is_selected ( ) → boolean | — | — | ¿Es esta entrada la seleccionada? Solo lectura, y a propósito: la selección es un estado de toda la barra, no una marca por entrada. Para ponerla, of_select en el componente — que siempre lanza el evento |
is_tooltip | string | "" | Tooltip simple mostrado al pasar el ratón por el item |
is_super_tooltip_title | string | "" | Título del tooltip enriquecido del item (prevalece sobre is_tooltip) |
is_super_tooltip_text | string | "" | Texto del tooltip enriquecido del item (se acepta el marcado enriquecido) |
is_super_tooltip_image | string | "" | Imagen del tooltip enriquecido del item |
Métodos #
En el componente #
| Método | Función |
|---|---|
of_add_section (string as_key, string as_text) | Añade una sección. Devuelve 0 (-5 ante un argumento no válido, -2 si el componente no está creado), como todo gesto de estructura: el handle viene de of_section("nav") cuando quiere fijar una propiedad |
of_insert_section (string as_key, string as_text, integer ai_index) | Añade una sección en el rango pedido (primera posición = 0) en lugar de al final. El índice cuenta secciones, no filas. Un nombre ya tomado se deja tal cual: dos secciones con un mismo nombre harían ambigua la dirección de cada una de sus entradas. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_move_section (string as_key, integer ai_index) | Mueve una sección al rango ai_index, con sus entradas. Mover solo la cabecera dejaría caer sus entradas en la sección que quede por encima de ellas. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_remove_section (string as_key) | Retira una sección y todo lo que contiene. Vaciarla conservando sus entradas las dejaría huérfanas: llevarían un identificador de sección que ya no nombra nada. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_section (string as_key) | Handle de una sección existente (creado en el primer acceso) |
of_add_item (string as_keys, string as_text, string as_image) | Añade una entrada en su dirección, "nav/accueil": la sección en la que aterriza, y luego su propio identificador. Devuelve 0 (-5 ante un argumento no válido, -2 si el componente no está creado) — -5 si el padre no es una sección. Una sobrecarga omite el icono |
of_item (string as_keys) | Handle de una entrada, por su dirección (creado en el primer acceso) |
of_insert_item (string as_keys, string as_text, integer ai_index) | Inserta una entrada en la posición ai_index dentro de su sección. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_insert_item (string as_keys, string as_text, string as_image, integer ai_index) | Ídem, con el icono de la entrada: of_add_item acepta uno, por lo que insertar también debe poder aceptarlo. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_move_item (string as_keys, integer ai_index) | Desplaza una entrada existente dentro de su sección, conservando su estado. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_remove_item (string as_keys) | Retira una entrada designada por su par sección / identificador. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_clear ( ) | Vacía la barra: todas las secciones y todas las entradas. Devuelve 0 una vez aplicado, -2 si el componente no está creado |
of_select_item (string as_keys) | Selecciona una entrada — estrictamente equivalente a un clic del usuario: primero se plantea ue_selection_changing, luego ue_selection_changed anuncia el desplazamiento. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_get_layout ( ) | Vuelve a leer la disposición actual en JSON: las secciones en orden, cada una con sus entradas en orden y su estado plegado. Guárdela (archivo, base de datos, registro) y devuélvala con of_set_layout en el siguiente arranque. El mismo par lleva los mismos nombres en todos los componentes reorganizables |
of_set_layout (string as_layout_json) | Restaura una disposición leída con of_get_layout o recibida con ue_layout_changed. Lo que la disposición no nombra conserva su lugar al final: una disposición de ayer no debe hacer desaparecer lo añadido desde entonces. Aplicarla no genera ningún event — usted la ha proporcionado. Devuelve 0 una vez aplicado, -5 ante un argumento no válido (clave vacía, dirección errónea), -2 si el componente no está creado |
of_clear_selection ( ) | No deja ninguna entrada seleccionada. Se anuncia como cualquier otro desplazamiento. Devuelve 0 una vez aplicado, -2 si el componente no está creado |
of_selected_key ( ) | Dirección de la entrada seleccionada — "nav/docs", "" si no hay ninguna. Es exactamente lo que ue_selection_changed le entrega: una comparación es una comparación, no un remontaje. Siempre la actual: un clic y of_select_item pasan ambos por el evento |
of_reset ( ) | Vacía la barra y luego devuelve el componente a su estado inicial. Devuelve 0 una vez aplicado, -2 si el componente no está creado |
of_set_redraw (boolean) | Agrupa una ráfaga de modificaciones en una única representación. Devuelve 0 una vez aplicado, -2 si el componente no está creado |
of_save_as_png (string) · of_save_as_jpg (string) | Exporta la representación como imagen. Devuelve 0 una vez escrita la imagen, -4 si la escritura falla, -2 si el componente no está creado |
En una sección — n_pbt_listbar_section #
| Método | Función |
|---|
Eventos #
| Evento | Se activa cuando |
|---|---|
ue_selection_changed (string as_from_keys, string as_keys) | La selección se ha desplazado — por clic o mediante of_select_item. Mismos argumentos que ue_selection_changing: la pregunta y su resultado se leen igual, y el par as_from_* designa la entrada abandonada (vacío si no hay ninguna) |
ue_section_toggled (string as_key, boolean ab_collapsed) | El usuario pliega o despliega una sección desde su encabezado |
ue_item_reordered (string as_keys, integer ai_index) | El usuario ha terminado de arrastrar una entrada. ai_index es su nuevo rango dentro de su sección, a partir de 1. Conserve ese orden para devolver al usuario su barra tal como la dejó |
ue_layout_changed (string as_layout_json) | La disposición ha cambiado — el usuario ha reorganizado algo, o su propio código. Lleva la disposición entera, no solo lo que se movió: conservarla es una sola asignación |
ue_selection_changing (string as_from_keys, string as_keys) → boolean | Cancelable, se plantea antes de que la selección se desplace. Lanzado de forma predeterminada; ib_veto_selection = false lo suprime. Devuelva false para mantener al usuario donde está |
ue_auto_width (long al_width) | El componente ha recalculado su anchura ideal — requiere ib_auto_width = true |
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 #
Menú lateral completo #
uo_nav.of_set_redraw(false)
uo_nav.of_add_section("dossiers", "Carpetas")
uo_nav.of_add_item("dossiers/recents", "Recientes", "mono:img\clock.svg")
uo_nav.of_add_item("dossiers/clients", "Clientes", "mono:img\user.svg")
uo_nav.of_add_item("dossiers/archives", "Archivos", "mono:img\box.svg")
uo_nav.of_add_section("outils", "Herramientas")
uo_nav.of_add_item("outils/import", "Importar", "mono:img\import.svg")
uo_nav.of_add_item("outils/export", "Exportar", "mono:img\export.svg")
uo_nav.of_set_redraw(true)
uo_nav.of_select_item("dossiers", "recents")
Riel plegable que libera espacio #
// Plegar en riel de iconos : la barra se estrecha por si misma (y recupera su
// anchura cuando usted la despliega).
uo_nav.ib_collapsed = true
// evento ue_auto_width de uo_nav : (long al_width)
// La barra acaba de adoptar su anchura ideal : recolocar lo que se encuentra a su derecha.
uo_contenu.x = uo_nav.x + al_width
uo_contenu.width = parent.width - uo_contenu.x
Acordeón: plegar una sección #
// Plegar la seccion de archivos, poco utilizada
uo_nav.of_section("archives").ib_collapsed = true
// evento ue_section_toggled de uo_nav : (string as_keys, boolean ab_collapsed)
of_enregistrer_preference("section_" + as_keys, String(ab_collapsed))
Reaccionar a la navegación #
// evento ue_selection_changed de uo_nav : (string as_from_keys, string as_keys)
// La direccion lleva los dos niveles : dos secciones pueden tener una entrada "liste".
n_pbt_utils lnv_utils // autoinstantiate : nada que crear, nada que destruir
string ls_ids[]
if lnv_utils.of_split_path(as_keys, ls_ids) < 2 then return
choose case ls_ids[1]
case "dossiers" ; of_ouvrir_dossier(ls_ids[2])
case "outils" ; of_lancer_outil(ls_ids[2])
end choose
Rechazar un cambio de selección #
// La pregunta se plantea de forma PREDETERMINADA: nada que activar. Esta linea
// hace lo contrario, la suprime cuando arbitrar no sirve y el coste se notaria.
uo_nav.ib_veto_selection = false
// evento ue_selection_changing de uo_nav :
// (string as_from_keys, string as_keys)
// Devolver FALSE mantiene al usuario en la entrada que abandona.
if of_saisie_en_cours(as_from_keys) then
MessageBox("Entrada", "Termine la ficha en curso antes de navegar.")
return false
end if
return true
Actualizar una entrada en caliente #
n_pbt_listbar_item lnv_entree
// La ruta completa es obligatoria : componente -> seccion -> entrada
lnv_entree = uo_nav.of_section("dossiers").of_item("recents")
lnv_entree.is_text = "Recientes (12)"
lnv_entree.is_image = "mono:img\clock_full.svg"
// Atenuar u ocultar segun los permisos, sin reconstruir la barra
uo_nav.of_section("outils").of_item("import").ib_enabled = of_a_le_droit("import")
uo_nav.of_section("outils").of_item("export").ib_visible = gb_mode_expert
Selección controlada desde el código #
// Colocar la seleccion en otro sitio : la banda de acento la sigue
uo_nav.of_select_item("dossiers", "clients")
// O borrarla por completo
uo_nav.of_clear_selection()
Reconstruir la barra #
// of_clear vacia secciones y entradas ; of_reset anade ademas los valores predeterminados del componente
uo_nav.of_clear()
of_construire_menu_selon_profil()
Buenas prácticas #
- Una entrada se añade por su dirección:
of_add_item("nav/accueil", ...). El handle de sección ya solo sirve para fijar una propiedad, yof_section("nav")lo entrega en el primer acceso. - Utilice
mono:para los iconos: se recolorean con el tema, tanto claro como oscuro, y siguen siendo legibles una vez plegada la barra en riel. - Un título de sección vacío sirve como agrupación discreta: las entradas quedan espaciadas sin que aparezca ninguna fila de encabezado.
ib_collapsedestrecha el userobject hasta el riel, pero no desplaza sus demás controles: trateue_auto_widthpara ocupar el espacio liberado, de lo contrario queda vacío.- En modo riel solo quedan los iconos: indique un tooltip en cada entrada para que las etiquetas sigan siendo accesibles.
- La pregunta se plantea de forma predeterminada: un
ue_selection_changingdejado vacío autoriza siempre el desplazamiento, no tiene nada que hacer. Desactívela conib_veto_selection = falsedonde el clic se repite — navegación por teclado, selección pilotada en bucle — porque cada pregunta cuesta una ida y vuelta hasta PowerBuilder. ib_enabled = falsees preferible aib_visible = falsecuando la entrada vaya a volver a estar disponible: el menú no cambia de forma ante los ojos del usuario.
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.
| Miembros | Función | Detallado en |
|---|---|---|
of_count · of_keys_at · of_has | Recorrer lo que el componente contiene | 3.2 Los items |
of_reset | Poner el componente a cero | 3.6 Poner un componente a cero: of_reset() |
of_register_shortcut · of_clear_shortcuts | Atajos de teclado del componente | 3.5 Los atajos de teclado |
of_is_created · of_is_ready · of_get_last_error | Si ha nacido, si está listo, qué ha fallado | 3.7 Diagnóstico |
of_save_as_png · of_save_as_jpg | Exportar el render como imagen | 3.8 Exportar la representación como imagen |
of_set_redraw | Agrupar los cambios en un solo repintado | 3.10 Buenas prácticas |
of_preload_icons | Iconos mostrados sin retardo | Visualización instantánea: of_icon |
of_set_translation | Traducir una etiqueta del componente | 5.2 Adaptar una etiqueta: of_set_translation |
of_focus_webview | Dar el foco al componente | 6.4 Teclado y foco |
of_print · of_print_to_pdf | Imprimir, o escribir un PDF | 6.9 Imprimir |
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.