menubar — u_pbt_menubar #
← Référence des composants · Sommaire du guide
Barre de menus d'application : menus, sous-menus, entrées cochables, séparateurs, icônes et raccourcis — le tout dessiné par la bibliothèque, sans menu Windows.
▶ Le voir en vrai — Application de démonstration, tuile Menu bar : l'aperçu, le code qui le produit et cette page, côte à côte.
En bref #
| Userobject | u_pbt_menubar |
| Classe d'items | n_pbt_menubar_item (une entrée) · n_pbt_menubar_menu (un menu de la barre) |
| Sert à | Donner à votre fenêtre la barre de menus de l'application, thémée comme le reste |
| Principe | Vous déclarez les menus, puis leurs entrées ; chaque entrée se retrouve par son adresse menu/id |
Démarrage rapide #
// event open de la fenetre
uo_menus.of_add_menu(/*key*/ "file", /*text*/ "Fichier")
uo_menus.of_add_item(/*keys*/ "file/open", /*text*/ "Ouvrir")
uo_menus.of_add_item(/*keys*/ "file/save", /*text*/ "Enregistrer")
// event ue_item_selected : (string as_keys)
choose case as_keys
case "file/open"; of_open_document()
case "file/save"; of_save_document()
end choose
Le modèle : trois niveaux, une clé par niveau #
Une barre de menus a trois niveaux, et chacun se désigne par sa clé :
| Niveau | Posé par | Clé |
|---|---|---|
| Le menu de la barre | of_add_menu | sa clé, file |
| L'entrée d'un menu | of_add_item | l'adresse menu/entree, file/open |
| La sous-entrée d'une entrée | of_add_item | l'adresse menu/entree/sous-entree, file/export/pdf — aussi profond qu'il le faut |
Une clé n'est unique que sous son parent : c'est pourquoi une entrée se désigne toujours par son adresse complète, le menu d'abord — jamais par sa clé seule. Deux menus peuvent donc avoir chacun leur entrée open, et deux sous-menus leur pdf (file/export/pdf, file/print/pdf), sans se gêner. Une clé ne contient ni / ni |, n'est pas vide et ne commence pas par __ : les ajouts la refusent (-5), comme une adresse déjà prise ou un parent jamais ajouté.
Un séparateur n'a pas de clé :
of_add_separatorpose un trait à la fin d'un menu (file) ou de la cascade d'une entrée (file/export), et il n'y a rien à en relire ensuite.
Propriétés #
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_theme_style | string | "" | Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement |
is_theme_mode | string | "" | Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement |
il_theme_accent | long | -1 | Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui 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 |
ib_wrap | boolean | false | false (défaut) : la barre reste sur une ligne ; les titres qui ne tiennent pas, depuis la fin, passent dans le déroulant d'un chevron à son bout (leurs entrées en cascade), et la hauteur ne change plus. true : la barre revient à la ligne et annonce sa nouvelle hauteur (ue_auto_height) — ce qu'elle faisait avant la 4.0 |
ib_track_hover | boolean | false | Abonnement à ue_item_hover : sans lui, les déroulants ne rapportent même pas l'entrée survolée — un événement levé à chaque mouvement du pointeur n'est envoyé qu'à une application qui l'a demandé |
Propriétés d'une entrée — n_pbt_menubar_item #
Obtenues par of_item(adresse) — of_item("file/export/pdf"). Une adresse d'un seul niveau désigne un menu, pas une entrée : sa poignée ne change rien, passez par of_menu.
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_text | string | — | Change le libellé de l'entrée, à chaud |
ib_enabled | boolean | true | Entrée active ; une entrée grisée ne réagit plus au clic |
ib_visible | boolean | true | Entrée retirée de la liste sans être supprimée — sous-menu et raccourci endormis avec elle ; elle garde sa clé et revient telle quelle. Un raccourci endormi garde sa combinaison : elle ne parvient pas non plus à votre application ; is_shortcut = "" la lui rend |
is_shortcut | string | "" | L'accélérateur affiché à droite de l'entrée (Ctrl+S) — et armé : la combinaison lève ue_item_selected pour cette entrée, où que soit le focus. Un menu est l'endroit où l'on apprend les raccourcis d'une application ; une touche affichée qui ne fait rien apprend le contraire. Touches : lettre, chiffre, F1 à F24, Enter, Esc, Del, Insert, Home, End, PageUp, PageDown, et avec Ctrl ou Alt aussi +, -, ,, ., les flèches (Left…), Space, Tab, Backspace (Ctrl++ pour le zoom). Un raccourci se pose sur une feuille : sur une entrée qui ouvre une cascade, il n'est ni affiché ni déclenché. La chaîne vide retire les deux |
ib_checked | boolean | false | Coche affichée devant l'entrée — pour une option qui s'active et se désactive |
is_image | string | "" | L'icône de l'entrée, changée à chaud : l'entrée garde sa place dans la liste. Mêmes chemins qu'of_add_item (mono:, tint:, fichier.dll:NOM) ; la chaîne vide la retire |
is_group | string | "" | Fait de l'entrée une entrée radio : les entrées d'un même groupe sous le même parent s'excluent — en cocher une (ib_checked = true, ou le choix de l'utilisateur) décoche les autres, et une puce ronde remplace la coche. ue_item_selected dit toujours laquelle a été choisie. La chaîne vide en refait une entrée ordinaire |
il_accent | long | -1 | Accent de cette entrée : sa coche, et son bord quand elle est pointée (-1 = celui du thème) |
il_back_color | long | -1 | Fond de cette entrée dans le déroulant, au repos |
il_text_color | long | -1 | Couleur du texte de cette entrée |
il_back_color_hover | long | -1 | Fond de cette entrée quand elle est pointée |
il_text_color_hover | long | -1 | Couleur du texte de cette entrée quand elle est pointée |
is_tooltip | string | "" | Gardée et relue, mais une entrée du déroulant n'affiche aucune info-bulle : le déroulant natif n'en a pas. Seuls les titres des menus affichent la leur (of_menu) |
is_super_tooltip_title | string | "" | Titre de son info-bulle enrichie — gardé, pas affiché (voir is_tooltip) |
is_super_tooltip_text | string | "" | Texte de son info-bulle enrichie — gardé, pas affiché |
is_super_tooltip_image | string | "" | Image de son info-bulle enrichie — gardée, pas affichée |
Propriétés d'un menu — n_pbt_menubar_menu #
Obtenues par of_menu(cle) — of_menu("file"). Couleurs et info-bulle s'affichent sur le titre du menu dans la barre.
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_text | string | — | Libellé du menu, & compris (mnémonique), changé sans reconstruire la barre |
ib_enabled | boolean | true | Menu grisé : il ne s'ouvre plus, ses entrées et leurs raccourcis avec lui ; le clavier le saute |
ib_visible | boolean | true | Le menu quitte la barre — entrées et raccourcis endormis avec lui — et y revient tel quel. Les raccourcis endormis gardent leur combinaison : elle ne parvient pas non plus à votre application |
is_align | string | "start" | u_pbt_menubar.ALIGN_END cale le menu au bout de la barre, comme Aide — avec ceux qui le suivent dans le même alignement, après lui ; ALIGN_START (défaut) le remet parmi les autres. Logique : le bout est à gauche dans une mise en page de droite à gauche. Avec le chevron, les titres du bout se replient les premiers |
il_accent | long | -1 | Accent de ce menu : un trait sous son titre tant que son déroulant est ouvert (-1 = aucun) |
il_back_color | long | -1 | Fond de son titre, au repos |
il_text_color | long | -1 | Couleur du texte de son titre, au repos |
il_back_color_hover | long | -1 | Fond de son titre survolé ou ouvert |
il_text_color_hover | long | -1 | Couleur du texte de son titre survolé ou ouvert |
is_tooltip | string | "" | Info-bulle affichée au survol de son titre |
is_super_tooltip_title | string | "" | Titre de l'info-bulle enrichie de son titre |
is_super_tooltip_text | string | "" | Texte de cette info-bulle enrichie (balisage riche accepté) |
is_super_tooltip_image | string | "" | Image de cette info-bulle enrichie |
Méthodes #
| Méthode | Rôle |
|---|---|
of_add_menu (string as_key, string as_text) | Ajoute un menu à la barre. Renvoie 0 une fois appliqué, -5 si la clé est refusée (vide, avec / ou une barre verticale, commençant par __, ou déjà prise), -2 si le composant n'est pas créé |
of_add_item (string as_keys, string as_text) | Ajoute une entrée à son adresse : file/open dans le menu File, file/export/pdf sous l'entrée Export, aussi profond qu'il le faut. Renvoie 0 une fois appliqué, -5 si l'adresse est refusée : moins de deux niveaux, un niveau vide, une clé avec / ou une barre verticale ou commençant par __, un menu ou une entrée parente jamais ajoutés, ou une adresse déjà prise. -2 si le composant n'est pas créé |
of_add_item (string as_keys, string as_text, string as_image, boolean ab_checked) | Même chose, avec l'icône et la coche. Pour griser l'entrée, maintenant ou plus tard, passez par sa poignée : of_item(adresse).ib_enabled = false. Renvoie 0 une fois appliqué, -5 si l'adresse est refusée : moins de deux niveaux, un niveau vide, une clé avec / ou une barre verticale ou commençant par __, un menu ou une entrée parente jamais ajoutés, ou une adresse déjà prise. -2 si le composant n'est pas créé |
of_add_separator (string as_keys) | Pose un trait de séparation à la fin d'un menu (file) ou de la cascade d'une entrée (file/export). Renvoie 0 une fois appliqué, -5 si rien n'a été ajouté à cette adresse, -2 si le composant n'est pas créé |
of_add_header (string as_keys, string as_text) → long | Pose un en-tête de section à la fin d'un menu (view) ou de la cascade d'une entrée (view/panels) : une ligne de titre au-dessus des entrées qui le suivent, jusqu'au prochain en-tête ou séparateur. Ce n'est pas une entrée — jamais choisie, jamais comptée par of_count, ni dans le plafond de démonstration — et il n'est pas dessiné quand toutes les entrées qu'il coiffe sont masquées. Renvoie 0 une fois ajouté, -5 si rien n'a été créé à cette adresse, -2 si le composant n'est pas créé |
of_item (string as_keys) → n_pbt_menubar_item | Handle d'une entrée, par son adresse — of_item("file/export/pdf") —, pour lire ou poser ses propriétés. C'est exactement ce que rend ue_item_selected : l'argument se redonne tel quel ici. Jamais la clé seule : deux sous-menus peuvent chacun avoir leur pdf, et seule l'adresse les distingue. Une adresse d'un seul niveau désigne un menu : sa poignée ne change rien, passez par of_menu |
of_menu (string as_key) → n_pbt_menubar_menu | Handle d'un menu de premier niveau, pour le renommer ou l'éteindre. of_add_menu ne pouvait le faire qu'à la création : griser Admin à la déconnexion demandait de reconstruire toute la barre ; ib_visible le retire de la barre, entrées et raccourcis endormis avec lui |
of_remove_item (string as_keys) → long | Retire une entrée, à son adresse (file/open, file/export/pdf) — sa cascade avec elle ; les autres restent. Ses poignées sont libérées et son raccourci désarmé : la touche revient à votre application. Sans elle il n'y avait qu'of_clear, qui vide tout — le menu dynamique le plus courant, une liste de fichiers récents, imposait de raser la barre entière à chaque document ouvert. Renvoie 0 une fois appliqué, -5 si aucune entrée ne vit à cette adresse, -2 si le composant n'est pas créé |
of_remove_menu (string as_key) → long | Retire un menu de premier niveau, ses entrées avec lui — poignées libérées, raccourcis désarmés. La barre est redessinée et sa hauteur ré-annoncée. Renvoie 0 une fois appliqué, -5 pour un menu jamais ajouté, -2 si le composant n'est pas créé |
of_clear ( ) | Vide la barre — menus et entrées ; leurs poignées sont libérées et les raccourcis des entrées désarmés. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
of_reset ( ) | Vide la barre et remet toutes les propriétés à leur défaut. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
of_set_redraw (boolean) | Regroupe une rafale de modifications en un seul rendu. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
of_save_as_png (string) · of_save_as_jpg (string) | Exporte le rendu en image. Renvoie 0 une fois l'image écrite, -4 si l'écriture échoue, -2 si le composant n'est pas créé |
Événements #
| Événement | Déclenché quand |
|---|---|
ue_menu_opening (string as_key) | Levé quand un menu de premier niveau va s'ouvrir — et le déroulant attend : il ne s'ouvre qu'une fois l'événement revenu. Activez, grisez ou remplissez ses entrées ici : le changement se voit à cette ouverture, pas à la suivante. Sans lui, il fallait tenir toute la barre en cohérence avec l'état de l'application en permanence, ou afficher des entrées qui mentent |
ue_menu_closed (string as_key) | Le déroulant d'un menu de premier niveau s'est refermé sans choix : par l'utilisateur (clic dehors, Échap, ou glissement vers le menu voisin), ou par votre code qui retire, vide, masque ou grise le menu ouvert (of_remove_menu, of_clear, ib_visible, ib_enabled) — un ordre le lève aussi. Défaites ici ce que ue_menu_opening avait préparé (un aperçu, une sélection). Un choix lève ue_item_selected à la place, et of_reset ne lève rien |
ue_item_selected (string as_keys) | L'utilisateur a choisi une entrée, ou pressé son raccourci. as_keys est son adresse, le menu d'abord — file/open, file/export/pdf : la clé seule ne dit pas de quel sous-menu elle sort, et deux sous-menus peuvent chacun avoir la leur. Ce même texte se redonne tel quel à of_item. Une entrée grisée, masquée ou retirée pendant que son déroulant était ouvert ne lève rien |
ue_item_hover (string as_keys) | Avec ib_track_hover = true : l'entrée sous le pointeur ou le clavier dans un déroulant ouvert, par son adresse (file/export/pdf) — une entrée grisée aussi, son aide peut dire pourquoi. Levé une fois par entrée, puis avec une adresse vide à la fermeture du déroulant (avant ue_item_selected sur un choix) : écrivez le texte d'aide d'une barre d'état, puis videz-le |
ue_auto_height (long al_height) | La barre annonce la hauteur qu'il lui faut — repositionnez ce qui se trouve dessous |
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) |
Une ligne, par défaut. Les titres qui ne tiennent pas passent dans le chevron au bout de la barre (
ib_wrap = false, le défaut) : la hauteur reste celle d'une ligne etue_auto_heightne part qu'une fois. Avecib_wrap = true, la barre revient à la ligne : elle ne défile jamais, sa hauteur suit les rangées etue_auto_heightvous dit de combien à chaque changement de largeur.
Au clavier #
| Touche | Effet |
|---|---|
| Alt · F10 | Donne le clavier à la barre et souligne les lettres des menus, comme dans n'importe quelle application Windows ; un second appui le rend |
| » | Le chevron des titres qui ne tiennent pas : les flèches s'y arrêtent comme sur un titre, Entrée ou Bas ouvre la liste des menus cachés, et Alt + la lettre d'un menu caché ouvre ce menu depuis le chevron |
| Alt + lettre | Ouvre le menu de cette lettre (&Fichier) depuis n'importe quel contrôle de la fenêtre — un champ, un DataWindow. Un raccourci Alt+lettre que votre application a enregistré passe avant. Deux menus sur la même lettre : la bande passe de l'un à l'autre, Entrée ouvre. Une lettre accentuée ou non latine se tape comme sur le clavier (&Édition : Alt + la touche du É) |
| Flèches | Parcourent les menus et leurs entrées, en sautant les menus grisés ; la droite ouvre une sous-entrée, la gauche remonte. En écriture de droite à gauche (RTL), tout se retourne : sur la barre, dans le déroulant (calé sur le bord droit de son titre) et dans les cascades, qui s'ouvrent à gauche — la gauche ouvre, la droite remonte |
| Entrée | Dans un déroulant : choisit l'entrée en surbrillance (ue_item_selected). Sur un titre de la barre, Entrée, Espace ou Flèche bas ouvrent le menu. Espace ne choisit pas une entrée — c'est aussi la règle de Windows |
| Échap | Referme le menu ouvert, puis rend le focus au contrôle qui l'avait |
Une barre de menus ne garde jamais le focus. Un clic sur un titre, puis un choix à la souris : le clavier revient au contrôle où l'on tapait avant que
ue_item_selectedne parte.Edition > Collercolle donc dans le champ en saisie, etGetFocus()le nomme dans l'événement.
Exemples #
Une barre de menus complète #
// Geler le dessin pendant la construction
uo_menus.of_set_redraw(/*on*/ false)
// Le menu Fichier, avec une icone sur Ouvrir et un trait avant Quitter
uo_menus.of_add_menu(/*key*/ "file", /*text*/ "&Fichier")
uo_menus.of_add_item(/*keys*/ "file/open", /*text*/ "&Ouvrir...", /*image*/ "mono:img\packimages.dll:svg/samples/folder-open", /*checked*/ false)
uo_menus.of_add_separator(/*keys*/ "file")
uo_menus.of_add_item(/*keys*/ "file/quit", /*text*/ "&Quitter")
// Un sous-menu : Exporter, puis ses deux formats
uo_menus.of_add_item(/*keys*/ "file/export", /*text*/ "&Exporter")
uo_menus.of_add_item(/*keys*/ "file/export/csv", /*text*/ "CSV")
uo_menus.of_add_item(/*keys*/ "file/export/pdf", /*text*/ "PDF")
// Le menu Affichage : une option qui se coche
uo_menus.of_add_menu(/*key*/ "view", /*text*/ "&Affichage")
uo_menus.of_add_item(/*keys*/ "view/grid", /*text*/ "&Grille", /*image*/ "", /*checked*/ true)
// Un seul dessin, avec tout
uo_menus.of_set_redraw(/*on*/ true)
Cocher, décocher, griser #
// L'utilisateur a bascule l'affichage de la grille
uo_menus.of_item(/*keys*/ "view/grid").ib_checked = not uo_menus.of_item(/*keys*/ "view/grid").ib_checked
// Une entree qui n'a plus de sens se grise, elle ne disparait pas :
// l'utilisateur doit pouvoir voir qu'elle existe
uo_menus.of_item(/*keys*/ "file/save").ib_enabled = false
Des entrées radio et un raccourci de zoom #
// Deux entrees RADIO : en cocher une decoche l'autre, une puce ronde remplace la coche
uo_menus.of_add_item(/*keys*/ "view/small", /*text*/ "&Petites icones")
uo_menus.of_add_item(/*keys*/ "view/large", /*text*/ "&Grandes icones")
uo_menus.of_item(/*keys*/ "view/small").is_group = "size"
uo_menus.of_item(/*keys*/ "view/large").is_group = "size"
uo_menus.of_item(/*keys*/ "view/large").ib_checked = true
// Le zoom : Ctrl++ est affiche ET arme, ou que soit le focus
uo_menus.of_add_item(/*keys*/ "view/zoomin", /*text*/ "&Zoom avant")
uo_menus.of_item(/*keys*/ "view/zoomin").is_shortcut = "Ctrl++"
Reconstruire la barre #
// Changer d'espace de travail : on vide et on repose
// of_set_redraw evite de repeindre a chaque ligne
uo_menus.of_set_redraw(/*on*/ false)
uo_menus.of_clear()
uo_menus.of_add_menu(/*key*/ "tools", /*text*/ "&Outils")
uo_menus.of_set_redraw(/*on*/ true)
Une barre étroite, Aide au bout, une aide dans la barre d'état #
// Help at the end of the bar ; what does not fit goes into the chevron
uo_menubar.of_menu(/*key*/ "help").is_align = u_pbt_menubar.ALIGN_END
// Section headers in View
uo_menubar.of_add_header(/*keys*/ "view", /*text*/ "Panels")
uo_menubar.of_add_item(/*keys*/ "view/tree", /*text*/ "Tree")
uo_menubar.of_add_item(/*keys*/ "view/output", /*text*/ "Output")
// A help text in the status bar for the pointed entry
uo_menubar.ib_track_hover = true
// ue_item_hover (string as_keys) of uo_menubar
choose case as_keys
case "file/save"
st_status.Text = "Saves the document"
case ""
st_status.Text = ""
end choose
Bonnes pratiques #
- Donnez une clé métier stable à chaque niveau (
file,save) :ue_item_selectedrend l'adressefile/save, jamais le libellé — elle ne change pas avec la langue. - Grisez plutôt que de retirer : une entrée absente laisse l'utilisateur chercher, une entrée grisée lui dit qu'elle existe et qu'il lui manque quelque chose.
- Encadrez la construction par
of_set_redraw(false)/of_set_redraw(true): une barre complète, c'est vite trente appels. - Repositionnez ce qui est sous la barre dans
ue_auto_height— la hauteur dépend du thème et de la taille de police, elle n'est pas la même partout. - Les libellés sont les vôtres : traduisez-les avant
of_add_item, ou changez-les à chaud parof_item(...).is_text/of_menu(...).is_text.of_set_translationne traduit que les textes propres à un composant, et la barre de menus n'en a aucun. - Écrivez un
&dans chaque titre (&Fichier) : Alt + la lettre ouvre le menu de partout, comme dans toute application Windows.
Hérité du socle commun #
Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.
| Membres | Rôle | Détaillé dans |
|---|---|---|
of_count · of_keys_at · of_has | Parcourir ce que le composant contient | 3.2 Les items |
of_reset | Remettre le composant à zéro | 3.6 Remettre un composant à zéro : of_reset() |
of_register_shortcut · of_clear_shortcuts | Raccourcis clavier du composant | 3.5 Les raccourcis clavier |
of_is_created · of_is_ready · of_get_last_error | S'il est né, s'il est prêt, ce qui a échoué | 3.7 Diagnostic |
of_save_as_png · of_save_as_jpg | Exporter le rendu en image | 3.8 Exporter le rendu en image |
of_set_redraw | Grouper les modifications en un seul repaint | 3.10 Bonnes pratiques |
of_preload_icons | Icônes affichées sans délai | Affichage instantané : of_icon |
of_set_translation | Traduire un libellé du composant | 5.2 Adapter un libellé : of_set_translation |
of_focus_webview | Donner le focus au composant | 6.4 Clavier et focus |
of_print · of_print_to_pdf | Imprimer, ou écrire un PDF | 6.9 Imprimer |
of_set_property · of_get_property · of_component_name | Piloter une propriété par son nom | 3.1 Le moteur de propriétés |
Deux aides ne sont pas héritées : of_icon et of_escape_markup vivent sur n_pbt_utils. Déclarez-en une — n_pbt_utils lnv_utils, rien à créer — et appelez-les dessus.