PBToolboxAI v4 ← Site

tab — u_pbt_tab #

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

Pestañas modernas que alojan controles reales de PowerBuilder: banda reposicionable, iconos por pestaña, pestañas que se pueden cerrar, reordenación con el ratón.

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


De un vistazo #

Userobjectu_pbt_tab
Clase de itemsn_pbt_tab_page (una página = una pestaña)
Sirve paraSustituir un tab de PowerBuilder por una banda con tema, conservando sus pantallas existentes como páginas
Opciones opt-inib_reorderable

El argumento clave: una página no es una maqueta HTML, es un dragobject de PowerBuilder: un userobject, una DataWindow, un grupo de controles o incluso otro componente PBToolboxAI. El componente se encarga de la colocación, del redimensionamiento y de mostrar u ocultar al cambiar de pestaña. Consulte Alojar controles reales de PowerBuilder.


Inicio rápido #

// event open de la ventana : cada pagina es un control PB ya puesto en la ventana
uo_tabs.of_add_page(/*key*/ "customers",  /*title*/ "Clientes",  /*page*/ uo_page_customers)
uo_tabs.of_add_page(/*key*/ "invoices", /*title*/ "Facturas", /*page*/ uo_page_invoices, /*closable*/ true)

// Un icono por pestana, puesto sobre el handle de la pagina
uo_tabs.of_page(/*key*/ "customers").is_icon  = "mono:img\customers.svg"
uo_tabs.of_page(/*key*/ "invoices").is_icon = "mono:img\invoice.svg"

// Muestra la primera pestana
uo_tabs.of_select_page(/*key*/ "customers")
// event ue_selection_changed de uo_tabs : (string as_from_key, string as_key)
of_load_page(as_key)

Propiedades #

PropiedadTipoPredeterminadoFunción
is_positionstring"top"Colocación de la banda: top, bottom (banda horizontal), start, end (banda vertical). Constantes POSITION_TOP, POSITION_BOTTOM, POSITION_START, POSITION_END. START/END son lógicas y siguen el sentido de escritura
is_overflow_modestring"menu"Lo que hace una banda demasiado pequeña para sus pestañas. menu (predeterminado) mantiene legible cada pestaña: las que ya no caben salen de la banda y el botón ··· las enumera todas, con la pestaña activa siempre visible. compact las mantiene todas en la banda y las deja reducirse, hasta el espacio que necesita un texto truncado. Constantes OVERFLOW_MENU, OVERFLOW_COMPACT
ib_reorderablebooleanfalseOpt-in: el usuario puede reordenar las pestañas arrastrando su encabezado con el ratón (activa ue_tab_reordered)
ib_veto_selectionbooleanfalsePreguntar antes de que cambie la pestaña activa — un gesto del usuario (clic, teclado, atajo, lista de pestañas) y of_select_page: activa ue_selection_changing, que puede rechazarlo; un of_select_page rechazado devuelve -4. Desactivado de forma predeterminada, como todo evento cancelable: póngalo a true para poder rechazar (trabajo sin guardar). Cada pregunta de un gesto cuesta una ida y vuelta hasta PowerBuilder (~35 ms)
ib_veto_closebooleanfalsePreguntar antes de que el usuario cierre una pestaña (cruz, clic central, menú contextual, Supr): activa ue_tab_closing, que puede rechazarlo. Desactivado de forma predeterminada: póngalo a true para conservar una página con trabajo sin guardar
ib_context_menubooleantrueMenú contextual integrado en el encabezado de una pestaña: Cerrar, Cerrar las demás, Cerrar a la derecha, Cerrar todas, atenuados cuando no tienen objetivo. Activo de forma predeterminada. El clic derecho selecciona primero la pestaña: si la aplicación rechaza el cambio, no se abre ningún menú. Con ib_veto_close, cada cierre pasa por ue_tab_closing, una pregunta por página: la que tiene trabajo sin guardar rechaza por sí sola y permanece abierta mientras sus vecinas se van. A false, el clic derecho en una pestaña la selecciona y luego lanza ue_tab_rclicked: abra ahí su propio menú
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

Propiedades de una página — n_pbt_tab_page #

Obtenidas mediante of_page(id), se modifican en caliente, sin reconstruir la banda.

PropiedadTipoPredeterminadoFunción
is_titlestring""Etiqueta de la pestaña. Admite el texto enriquecido con etiquetas
is_iconstring""Icono de la pestaña (formas admitidas: ruta, mono:, tint:, recurso de una DLL). Vacío = ningún icono
ib_enabledbooleantruefalse atenúa la pestaña: ningún clic, tecla, atajo ni of_select_page la activa, y no tiene aspa de cierre. Desactivar la pestaña activa la deja activa y su página utilizable: desactive la propia página si hace falta (su código sabe si debe seguir editable)
ib_visiblebooleantruefalse oculta la pestaña sin eliminar la página; ocultar la pestaña activa activa su vecina (la de la derecha, si no la de la izquierda); ocultar la última pestaña visible oculta la página y lanza ue_selection_changed con una clave vacía
ib_closablebooleanfalseAspa de cierre en esta pestaña. Rara vez se conoce al añadir la página: pasa a true en cuanto se guarda el documento que contiene, y a false mientras se ejecuta un proceso dentro. Un clic central en una pestaña que se puede cerrar también la cierra, como su aspa
is_shortcutstring""Atajo de teclado que activa esta pestaña: "Ctrl+2", "Alt+F", "F6"… Responde esté donde esté el usuario en la ventana, incluida la página alojada — el atajo lo tiene la DLL, no la barra de pestañas. Seleccionar así es un clic: se plantea ue_selection_changing si ib_veto_selection está activo y ue_selection_changed le sigue; una pestaña desactivada u oculta lo ignora. "" lo quita
is_tooltipstring""Tooltip simple mostrado al pasar el ratón por el item
is_super_tooltip_titlestring""Título del tooltip enriquecido del item (prevalece sobre is_tooltip)
is_super_tooltip_textstring""Texto del tooltip enriquecido del item (se acepta el marcado enriquecido)
is_super_tooltip_imagestring""Imagen del tooltip enriquecido del item

Métodos #

MétodoFunción
of_add_page (string as_key, string as_title, dragobject ado_page)Añade una pestaña que no se puede cerrar, sin icono, y aloja el control. Devuelve 0 una vez aplicado, -5 si la clave está vacía, contiene una / o una `, ya está tomada, o si falta la página o ya está alojada (por esta pestaña con otra clave, o por otro componente): no se añade nada entonces, -2` si el componente no está creado
of_add_page (string as_key, string as_title, dragobject ado_page, boolean ab_closable)Ídem, con aspa de cierre si ab_closable. Devuelve 0 una vez aplicado, -5 si la clave está vacía, contiene una / o una `, ya está tomada, o si falta la página o ya está alojada (por esta pestaña con otra clave, o por otro componente): no se añade nada entonces, -2` si el componente no está creado
of_add_page (string as_key, string as_title, dragobject ado_page, boolean ab_closable, string as_icon)Ídem, con el icono puesto en la misma llamada (la pestaña aparece completa de entrada). Devuelve 0 una vez aplicado, -5 si la clave está vacía, contiene una / o una `, ya está tomada, o si falta la página o ya está alojada (por esta pestaña con otra clave, o por otro componente): no se añade nada entonces, -2` si el componente no está creado
of_insert_page (string as_key, string as_title, dragobject ado_page, integer ai_index)Añade la página y después la desplaza a la posición ai_index (1 = la primera). Devuelve 0 una vez aplicado, -5 por los mismos rechazos que of_add_page, -2 si el componente no está creado
of_insert_page (string as_key, string as_title, dragobject ado_page, boolean ab_closable, string as_icon, integer ai_index)Ídem, diciendo lo que dice of_add_page : si la pestaña se cierra, y su icono. Devuelve 0 una vez aplicado, -5 por los mismos rechazos que of_add_page, -2 si el componente no está creado
of_move_page (string as_key, integer ai_index)Desplaza una pestaña existente a la posición ai_index (1 = la primera); su página alojada y la selección se conservan. Devuelve 0 una vez aplicado, -5 si la clave no designa ninguna página, -2 si el componente no está creado
of_select_page (string as_key)Activa una pestaña, como un clic en ella: con ib_veto_selection activo, primero se plantea ue_selection_changing; después sigue ue_selection_changed, como para un clic (justo después de su script, desde la cola de eventos), y of_selected_key() leído justo después ya devuelve la nueva clave. Pestaña ya activa: no se pregunta ni se lanza nada. Devuelve 0 una vez aplicado (o si ya estaba activa), -4 si su ue_selection_changing lo rechazó (nada se mueve), -5 si la clave no designa ninguna página o la página no puede mostrarse (oculta, desactivada, más allá del límite de la demo) — incluso cuando después ya no queda ninguna página activa, -2 si el componente no está creado
of_remove_page (string as_key)Retira la pestaña y devuelve el control a su ventana de origen, oculto. El control sigue siendo utilizable y se puede alojar en otro sitio. No lanza ue_tab_closed: lo ha hecho su código. Si era la página activa, su vecina pasa a ser la activa. Devuelve 0 una vez aplicado, -5 si la clave no designa ninguna página, -2 si el componente no está creado
of_selected_key ( )Identificador de la pestaña activa, "" si no hay ninguna
of_get_layout ( )Vuelve a leer la disposición actual en JSON: el orden de las pestañas y la visibilidad de cada una. 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 de disposición — usted la ha proporcionado; si oculta la pestaña activa, su vecina pasa a ser la activa y ue_selection_changed lo dice. Devuelve 0 una vez aplicado, -5 si el texto está vacío o no es JSON válido, -2 si el componente no está creado
of_page (string as_key)Handle n_pbt_tab_page de la página (creado en el primer acceso)
of_refresh_page (string as_key)Actualiza la representación de una página construida fuera de pantalla, sin parpadeo. Devuelve 0, -5 si la clave no designa ninguna página, -2 si el componente no está creado
of_relayout ( )Vuelve a publicar la zona de página para que el control alojado se recoloque (útil tras una visualización diferida). Devuelve 0 una vez aplicado, -2 si el componente no está creado
of_preload_icons (string as_icons[])Precalienta un lote de iconos al arrancar: una pestaña abierta más tarde muestra su icono al instante. Devuelve 0 una vez aplicado, -2 si el componente no está creado
of_reset ( )Vacía la banda: cada página alojada se devuelve a su ventana de origen y después el componente vuelve 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 sola 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

of_add_page devuelve un código negativo si el identificador está vacío, ya se utiliza, o si el control pasado no es válido o ya está alojado.

Cuando hay demasiadas pestañas — se reducen para caber en la banda, pero nunca por debajo de un ancho legible: el icono y la cruz de cierre ocupan su sitio además del título, nunca en su lugar. Las que ya no caben salen de la banda, y en su extremo aparece un botón ···: abre la lista de todas las pestañas visibles, con la activa marcada, y la elección cambia a ella. La pestaña activa siempre permanece visible. La banda no se desplaza — ese botón es el camino hacia las pestañas fuera del marco. Nada que programar, el comportamiento es automático.

Teclado y ratón — Ctrl+Tab y Ctrl+Av Pág pasan a la pestaña siguiente, Ctrl+Mayús+Tab y Ctrl+Re Pág a la anterior: solo cuentan las pestañas que pueden activarse (las ocultas y las atenuadas se saltan), y el recorrido vuelve a empezar. Estas teclas responden cuando el teclado está en la banda de pestañas o en una página que aloja — un control PowerBuilder de la página igual que otro componente colocado en ella; desde un control situado fuera del tab, se quedan en la ventana. Es un gesto del usuario: se plantea ue_selection_changing si ib_veto_selection está activo, y luego sigue ue_selection_changed. Un clic central en una pestaña que se puede cerrar la cierra, exactamente como su aspa: la misma pregunta ue_tab_closing si ib_veto_close está activo, y luego ue_tab_closed; en una pestaña atenuada o que no se puede cerrar no hace nada. Nada que programar.


Eventos #

EventoSe activa cuando
ue_selection_changed (string as_from_key, string as_key)La pestaña activa ha cambiado, por un gesto (un clic, el teclado, incluido Ctrl+Tab, un atajo, la lista de pestañas), por of_select_page (una orden de su código también lo lanza, como SelectTab lanza SelectionChanged) o porque una pestaña se va (cerrada, retirada, oculta). Mismos argumentos que ue_selection_changing: la pregunta y su resultado se leen igual, y as_from_key es la página abandonada — incluso cuando ya no existe. Un as_key vacío significa que ya no se puede mostrar ninguna pestaña: todas las páginas están ocultas
ue_tab_closed (string as_key)El usuario ha cerrado una pestaña: su aspa, un clic central sobre ella, el menú contextual o la tecla Supr. La pestaña ya se ha retirado y la página se ha devuelto a su ventana. of_remove_page nunca lo lanza: lo ha hecho su código
ue_tab_reordered (string as_key, integer ai_index)El usuario ha terminado de arrastrar un encabezado. ai_index es la nueva posición, a partir de 1, como of_move_page
ue_layout_changed (string as_layout_json)La disposición que hay que guardar ha cambiado: el usuario ha arrastrado un encabezado, o su código ha desplazado una pestaña (of_move_page, of_insert_page) o ha ocultado / vuelto a mostrar una (ib_visible). of_set_layout no lo lanza (esa disposición la ha proporcionado usted), ni añadir, cerrar o retirar una pestaña — el orden de las demás no cambia. Lleva la disposición entera, no solo lo que se movió: conservarla es una sola asignación
ue_selection_changing (string as_from_key, string as_key) → booleanCancelable, se plantea antes de que cambie la pestaña activa — un gesto del usuario o of_select_page —, cuando ib_veto_selection está a true (desactivado de forma predeterminada). Devuelva false para quedarse en la página: nada se mueve, y of_select_page devuelve -4
ue_tab_closing (string as_key) → booleanCancelable, se plantea antes de que el usuario cierre una pestaña, cuando ib_veto_close está a true (desactivado de forma predeterminada). Nombrado para hacer pareja con ue_tab_closed: closing / closed. Devuelva false para mantener abierta la pestaña (y su página alojada)
ue_tab_rclicked (string as_key)Clic derecho en el encabezado de una pestaña cuando ib_context_menu está a false: la pestaña se selecciona primero (mediante ue_selection_changing si está armado — una selección rechazada no lanza nada), y luego este event da su clave. Abra aquí su propio menú: PopMenu(PointerX(), PointerY()) de su ventana. Una pestaña desactivada no lanza nada; un solo event por clic derecho
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 #

Un archivador de páginas de negocio #

// event open : los userobjects de pagina ya estan puestos en la ventana
uo_tabs.of_set_redraw(/*on*/ false)

// Una pestana por cada userobject de pagina
uo_tabs.of_add_page(/*key*/ "identity", /*title*/ "Identidad",  /*page*/ uo_identity)
uo_tabs.of_add_page(/*key*/ "addresses", /*title*/ "Direcciones",  /*page*/ uo_addresses)
uo_tabs.of_add_page(/*key*/ "accounting",   /*title*/ "Contabilidad", /*page*/ uo_accounting)

// Un icono por pestana, puesto en el handle de la pagina
uo_tabs.of_page(/*key*/ "identity").is_icon = "mono:img\user.svg"
uo_tabs.of_page(/*key*/ "addresses").is_icon = "mono:img\map.svg"
uo_tabs.of_page(/*key*/ "accounting").is_icon   = "mono:img\euro.svg"

// Un solo renderizado para todo y luego se muestra la primera pestana
uo_tabs.of_set_redraw(/*on*/ true)
uo_tabs.of_select_page(/*key*/ "identity")

Documentos que se pueden cerrar, abiertos bajo demanda #

// Abrir un documento en una nueva pestana que se pueda cerrar
uo_tabs.of_add_page(/*key*/ ls_key, /*title*/ ls_label, /*page*/ uo_editor, /*closable*/ true, /*icon*/ "mono:img\doc.svg")
uo_tabs.of_select_page(/*key*/ ls_key)
// event ue_tab_closed de uo_tabs : (string as_key)
// La pestana ya se ha retirado ; solo queda liberar sus datos de negocio.
of_free_document(as_key)

Reordenación con el ratón #

// The user may drag a tab to a new place
uo_tabs.ib_reorderable = true
// event ue_tab_reordered de uo_tabs : (string as_key, integer ai_index)
// ai_index = nueva posicion, a partir de 1 (como of_move_page) : se memoriza el orden elegido.
of_save_order(as_key, ai_index)

Banda vertical #

// Banda de pestanas en el lado izquierdo, util cuando las etiquetas son largas
uo_tabs.is_position = uo_tabs.POSITION_START

Atenuar u ocultar una pestaña según los permisos #

// El camino pasa siempre por el handle de la pagina
uo_tabs.of_page(/*key*/ "accounting").ib_enabled = of_is_allowed("accounting")
uo_tabs.of_page(/*key*/ "audit").ib_visible  = gb_expert_mode

Reaccionar a la selección #

// event ue_selection_changed de uo_tabs : (string as_from_key, string as_key)
choose case as_key
    case "identity" ; uo_identity.of_refresh()
    case "addresses" ; uo_addresses.of_refresh()
    case "accounting"   ; uo_accounting.of_refresh()
end choose

Rechazar un cambio de pestaña o un cierre #

// Las dos preguntas hay que ACTIVARLAS: sin estas lineas el componente no
// pregunta nada y cambia de pagina o cierra de inmediato.
uo_tabs.ib_veto_selection = true
uo_tabs.ib_veto_close     = true
// event ue_selection_changing de uo_tabs : (string as_from_key, string as_key)
// Devolver FALSE mantiene al usuario en la pagina que abandona.
if of_page_modified(as_from_key) then
    if MessageBox("Modificaciones", "¿Salir sin guardar?", Question!, YesNo!) = 2 then
        return false
    end if
end if
return true
// event ue_tab_closing de uo_tabs : (string as_key)
// Devolver FALSE mantiene abiertos la pestana y su pagina alojada.
return not of_page_modified(as_key)

Volver a empezar con una banda vacía #

// of_reset devuelve CADA pagina alojada a su ventana de origen antes de vaciar
uo_tabs.of_reset()
uo_tabs.of_add_page(/*key*/ "home", /*title*/ "Inicio", /*page*/ uo_home)

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