dockcontainer — u_pbt_dockcontainer #
← Référence des composants · Sommaire du guide
Panneaux dockables façon Visual Studio : docking par glisser-déposer, empilement en onglets, séparateurs redimensionnables, fenêtres flottantes, masquage automatique — et sauvegarde/restauration de la disposition.
▶ Le voir en vrai — Application de démonstration, tuile Dock container : l'aperçu, le code qui le produit et cette page, côte à côte.
En bref #
| Userobject | u_pbt_dockcontainer |
| Classe d'items | n_pbt_dock_panel (un panneau) |
| Sert à | Donner à une fenêtre PowerBuilder l'ergonomie d'un IDE moderne : l'utilisateur organise lui-même ses panneaux, et la disposition se retrouve à la session suivante |
Comme tab, chaque panneau héberge un vrai contrôle PowerBuilder (dragobject) : userobject, DataWindow, ou un autre composant PBToolboxAI. Voir Héberger de vrais contrôles PowerBuilder.
Démarrage rapide #
// event open de la fenetre : les controles de panneau sont deja poses dessus
uo_dock.of_add_panel(/*cle*/ "document", /*position*/ "", /*relatif_a*/ "", &
/*taille*/ 0, /*titre*/ "Document", /*contenu*/ uo_editeur)
uo_dock.of_add_panel(/*cle*/ "explorateur", /*position*/ uo_dock.POSITION_START, &
/*relatif_a*/ "document", /*taille*/ 260, &
/*titre*/ "Explorateur", /*contenu*/ uo_arbre)
uo_dock.of_add_panel(/*cle*/ "proprietes", /*position*/ uo_dock.POSITION_END, &
/*relatif_a*/ "document", /*taille*/ 300, &
/*titre*/ "Proprietes", /*contenu*/ uo_props)
// La zone centrale : ni fermable par le docking, ni flottante, ni masquable
uo_dock.is_main = "document"
Propriétés #
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_main | string | "" | Clé du panneau principal : la zone de document centrale, qui ne peut être ni masquée ni détachée. Le panneau doit déjà exister |
is_theme_style | string | fluent | Style visuel du composant (constantes THEME_STYLE_*) |
is_theme_mode | string | light | Variante claire ou sombre (constantes THEME_MODE_*) |
il_theme_accent | long | -1 | Couleur d'accent de ce composant (-1 = accent du thème) |
is_tooltip | string | "" | Info-bulle simple affichée au survol du composant |
is_super_tooltip_title | string | "" | Titre de l'info-bulle enrichie (prend le pas sur is_tooltip) |
is_super_tooltip_text | string | "" | Texte de l'info-bulle enrichie (balisage riche accepté) |
is_super_tooltip_image | string | "" | Image de l'info-bulle enrichie |
Positions de docking #
Les constantes du composant alimentent as_position dans of_add_panel et of_move_panel :
| Constante | Valeur | Effet |
|---|---|---|
POSITION_START | "start" | Le nouveau panneau se docke du côté début de lecture du panneau de référence (à gauche en écriture de gauche à droite) |
POSITION_END | "end" | … du côté fin de lecture |
POSITION_TOP | "top" | … au-dessus |
POSITION_BOTTOM | "bottom" | … en dessous |
POSITION_STACK | "stack" | Le panneau est empilé en onglet sur le panneau de référence. Valeur retenue si as_position est vide |
Propriétés d'un panneau — n_pbt_dock_panel #
Obtenues par of_item(cle).
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_title | string | "" | Titre affiché sur l'onglet du panneau. Accepte le balisage riche |
is_short_title | string | "" | Forme courte du titre, pour les endroits où la place manque : le rail d'un panneau épinglé (toujours — c'est un liseré) et l'onglet d'une pile, mais seulement une fois que le titre complet n'y tient plus, ce qui est mesuré et non deviné. L'en-tête du panneau garde le titre complet. "" = pas de forme courte |
ib_visible | boolean | true | Affiche ou masque ce panneau |
ib_pinned | boolean | true | true = épinglé en place ; false = le panneau se replie en languette sur le bord et ne se déploie qu'au survol (masquage automatique) |
is_header_color | string | "" | Couleur de l'en-tête de ce panneau. Vide = le thème décide ; HEADER_COLOR_ACCENT suit l'accent du thème (et le suit encore après un changement de thème, ce qu'un code fixe ne ferait pas) ; sinon un #rrggbb. La couleur de texte lisible est calculée avec |
is_border_color | string | "" | Couleur de la bordure de ce panneau, même grammaire. Elle encadre le cadre et l'en-tête, qui portent chacun la leur : n'en colorer qu'une laisse une couture visible. Elle suit le panneau dans son volet glissant |
is_tooltip | string | "" | Info-bulle simple affichée au survol de l'item |
is_super_tooltip_title | string | "" | Titre de l'info-bulle enrichie de l'item (prend le pas sur is_tooltip) |
is_super_tooltip_text | string | "" | Texte de l'info-bulle enrichie de l'item (balisage riche accepté) |
is_super_tooltip_image | string | "" | Image de l'info-bulle enrichie de l'item |
Méthodes #
| Méthode | Rôle |
|---|---|
of_add_panel (string as_key, string as_position, string as_relative_to, integer ai_size, string as_title, dragobject ado_content) | Ajoute un panneau fermable et héberge le contrôle. as_relative_to = clé du panneau contre lequel il se docke (vide = la racine) ; ai_size = taille initiale en pixels (0 = automatique) |
of_add_panel (…, boolean ab_closable) | Idem, avec ab_closable = false pour un panneau sans bouton de fermeture |
of_select_panel (string as_key) | Met un panneau au premier plan de son groupe d'onglets |
of_move_panel (string as_key, string as_target, string as_position) | Réorganise depuis le code, exactement comme si l'utilisateur avait fait glisser l'onglet |
of_move_panel (string as_key, string as_target, string as_position, integer ai_index) | Même chose, en donnant le rang du panneau dans la pile de la cible (0 = premier, -1 = dernier). Seule une pile est une liste ordonnée : l'index est ignoré pour POSITION_START / END / TOP / BOTTOM |
of_float_panel (string as_key) | Détache le panneau dans une vraie fenêtre flottante déplaçable et redimensionnable. La refermer le re-docke (ue_panel_docked) |
of_notify_panel (string as_key) | Signale du contenu nouveau : si le panneau n'est pas visible, son onglet affiche un compteur d'éléments non vus, effacé à la sélection |
of_clear_notify (string as_key) | Efface ce compteur sans afficher le panneau. Sélectionner l onglet était le seul autre moyen, ce qui est faux quand votre code sait que le contenu lui-même a disparu |
of_remove_panel (string as_key) | Retire le panneau et rend le contrôle à sa fenêtre d'origine |
of_get_layout ( ) | Renvoie la disposition courante (arbre des découpes, ratios, onglets, visibilité) sous forme de chaîne, à stocker en fichier, base ou registre |
of_set_layout (string as_json) | Restaure une disposition obtenue par of_get_layout. Les panneaux doivent avoir été recréés avant l'appel ; ceux absents de la disposition sont rattachés au premier groupe |
of_item (string as_id) | Handle n_pbt_dock_panel du panneau (créé au premier accès) |
of_refresh_panel (string as_key) | Rafraîchit le rendu d'un panneau construit hors écran, sans scintillement |
of_relayout ( ) | Recalcule et republie toutes les zones pour que les contrôles hébergés soient repositionnés |
of_reset ( ) | Vide le conteneur : chaque contrôle hébergé est rendu à sa fenêtre d'origine, les handles de panneaux sont libérés, la disposition mémorisée est effacée |
of_set_redraw (boolean) | Regroupe une rafale de modifications en un seul rendu |
of_save_as_png (string) · of_save_as_jpg (string) | Exporte le rendu en image |
Événements #
| Événement | Déclenché quand |
|---|---|
ue_panel_selected (string as_key) | Un panneau devient le panneau actif de son groupe |
ue_panel_closed (string as_key) | L'utilisateur ferme un panneau |
ue_panel_pinned (string as_key, boolean ab_pinned) | Un panneau est épinglé (true) ou dépunaisé en masquage automatique (false) |
ue_panel_floated (string as_key) | Un panneau est détaché en fenêtre flottante |
ue_panel_docked (string as_key) | Un panneau flottant est re-docké |
ue_layout_changed (string as_json) | La disposition a changé (glissement, redimensionnement, docking). Le paramètre porte la nouvelle disposition, prête à être enregistrée |
ue_ready ( ) | Le composant a fini de charger ; tout ce qui a été envoyé avant a été rejoué |
ue_runtime_missing ( ) | Le runtime WebView2 est absent : le composant reste vide |
ue_bg_color (long al_color) | Le composant a calculé sa couleur de fond de thème ; l'userobject l'a déjà adoptée (backcolor) |
Au clavier #
Le contenu d'un panneau est un vrai contrôle PowerBuilder : le clavier y appartient à votre code, comme dans n'importe quelle fenêtre. Ce que le composant prend en charge, c'est son propre habillage — en-têtes, onglets, splitters :
| Touche | Effet |
|---|---|
| Flèches sur un onglet | Passent au panneau précédent / suivant du groupe, et le sélectionnent. Un bandeau d'onglets est un seul arrêt de tabulation |
| Début / Fin sur un onglet | Premier / dernier panneau du groupe |
| Flèches sur un splitter | Déplacent la séparation de 2 %, dans l'axe du splitter seulement |
| Page haut / Page bas sur un splitter | Même chose, par pas de 10 % |
| Échap | Referme le panneau glissant ouvert depuis un bouton de bord |
Un splitter est un separator focalisable qui annonce sa position ; les boutons d'en-tête (détacher, masquer, fermer) portent un nom, et le panneau actif d'un groupe est marqué aria-selected. Un déplacement au clavier remonte dans ue_layout_changed exactement comme un glissement à la souris.
Exemples #
Une fenêtre façon IDE #
// event open : chaque contenu est un vrai controle PB pose sur la fenetre
uo_dock.of_add_panel("document", "", "", 0, "Document", uo_editeur)
uo_dock.of_add_panel("explorateur", uo_dock.POSITION_START, "document", 260, "Explorateur", uo_arbre)
uo_dock.of_add_panel("proprietes", uo_dock.POSITION_END, "document", 300, "Proprietes", uo_props)
uo_dock.of_add_panel("sortie", uo_dock.POSITION_BOTTOM, "document", 200, "Sortie", uo_console)
// Un second panneau empile en onglet sur "proprietes"
uo_dock.of_add_panel("aide", uo_dock.POSITION_STACK, "proprietes", 0, "Aide", uo_aide)
uo_dock.is_main = "document"
Mémoriser et restaurer la disposition de l'utilisateur #
// event close de la fenetre : enregistrer ce que l'utilisateur a organise
string ls_disposition
ls_disposition = uo_dock.of_get_layout()
of_enregistrer_preference("dock_principal", ls_disposition)
// event open : RECREER les panneaux d'abord, restaurer ensuite
string ls_disposition
of_creer_les_panneaux() // les of_add_panel ci-dessus
ls_disposition = of_lire_preference("dock_principal")
if ls_disposition <> "" then uo_dock.of_set_layout(ls_disposition)
L'ordre est impératif :
of_set_layoutne crée aucun panneau, il ne fait que replacer ceux qui existent déjà.
Suivre les changements en continu #
// event ue_layout_changed de uo_dock : (string as_json)
// Enregistrement immediat, sans attendre la fermeture de la fenetre.
of_enregistrer_preference("dock_principal", as_json)
Piloter un panneau par son handle #
n_pbt_dock_panel lnv_panneau
lnv_panneau = uo_dock.of_item("proprietes")
lnv_panneau.is_title = "Proprietes (3 modifiees)"
lnv_panneau.ib_pinned = false // se replie en languette sur le bord
// Masquer un panneau reserve aux administrateurs
uo_dock.of_item("audit").ib_visible = gb_administrateur
Attirer l'attention sur un panneau en arrière-plan #
// Un traitement de fond a ecrit dans la console : signaler sans voler le focus
uo_dock.of_notify_panel("sortie")
Réorganiser depuis le code #
// Deplacer un panneau comme si l'utilisateur avait fait glisser son onglet
uo_dock.of_move_panel(/*cle*/ "sortie", /*cible*/ "document", /*position*/ "bottom")
// L'empiler en onglet sur un autre panneau
uo_dock.of_move_panel(/*cle*/ "aide", /*cible*/ "proprietes", /*position*/ "stack")
Détacher un panneau sur un second écran #
// Fenetre flottante native : l'utilisateur peut la poser sur un autre ecran
uo_dock.of_float_panel("proprietes")
// event ue_panel_docked de uo_dock : (string as_key)
// L'utilisateur a referme la fenetre flottante : le panneau est revenu.
of_journaliser("Panneau re-docke : " + as_key)
Fermer proprement un panneau #
// event ue_panel_closed de uo_dock : (string as_key)
// Retirer aussi le panneau du conteneur pour liberer le controle heberge.
uo_dock.of_remove_panel(as_key)
Bonnes pratiques #
- Désignez toujours un panneau principal avec
is_main: sans zone centrale, l'utilisateur peut tout masquer et se retrouver devant une fenêtre vide. - Enregistrez la disposition sur
ue_layout_changedplutôt qu'à la seule fermeture : une fermeture anormale ne perd alors rien. of_set_layoutvient après lesof_add_panel, jamais avant.- Utilisez
of_notify_panelpour les traitements de fond : c'est moins intrusif qu'une boîte de dialogue et l'information reste visible. - Un contrôle hébergé est une fenêtre native : il se dessine au-dessus de la couche web, aucun effet visuel du composant ne passe par-dessus lui.
of_reset()avant toute reconstruction : sans lui, les contrôles précédemment hébergés restent reparentés dans le conteneur vidé et réutiliser une clé échoue.- Pour de simples pages exclusives, sans docking ni flottement, tab est plus léger.