PBToolboxAI v4 ← Site

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 #

Userobjectu_pbt_menubar
Classe d'itemsn_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
PrincipeVous 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é :

NiveauPosé parClé
Le menu de la barreof_add_menusa clé, file
L'entrée d'un menuof_add_iteml'adresse menu/entree, file/open
La sous-entrée d'une entréeof_add_iteml'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_separator pose 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éTypeDéfautRôle
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)
is_tooltipstring""Info-bulle simple affichée au survol du composant
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie
ib_wrapbooleanfalsefalse (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_hoverbooleanfalseAbonnement à 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éTypeDéfautRôle
is_textstring—Change le libellé de l'entrée, à chaud
ib_enabledbooleantrueEntrée active ; une entrée grisée ne réagit plus au clic
ib_visiblebooleantrueEntré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_shortcutstring""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_checkedbooleanfalseCoche affichée devant l'entrée — pour une option qui s'active et se désactive
is_imagestring""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_groupstring""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_accentlong-1Accent de cette entrée : sa coche, et son bord quand elle est pointée (-1 = celui du thème)
il_back_colorlong-1Fond de cette entrée dans le déroulant, au repos
il_text_colorlong-1Couleur du texte de cette entrée
il_back_color_hoverlong-1Fond de cette entrée quand elle est pointée
il_text_color_hoverlong-1Couleur du texte de cette entrée quand elle est pointée
is_tooltipstring""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_titlestring""Titre de son info-bulle enrichie — gardé, pas affiché (voir is_tooltip)
is_super_tooltip_textstring""Texte de son info-bulle enrichie — gardé, pas affiché
is_super_tooltip_imagestring""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éTypeDéfautRôle
is_textstring—Libellé du menu, & compris (mnémonique), changé sans reconstruire la barre
ib_enabledbooleantrueMenu grisé : il ne s'ouvre plus, ses entrées et leurs raccourcis avec lui ; le clavier le saute
ib_visiblebooleantrueLe 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_alignstring"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_accentlong-1Accent de ce menu : un trait sous son titre tant que son déroulant est ouvert (-1 = aucun)
il_back_colorlong-1Fond de son titre, au repos
il_text_colorlong-1Couleur du texte de son titre, au repos
il_back_color_hoverlong-1Fond de son titre survolé ou ouvert
il_text_color_hoverlong-1Couleur du texte de son titre survolé ou ouvert
is_tooltipstring""Info-bulle affichée au survol de son titre
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie de son titre
is_super_tooltip_textstring""Texte de cette info-bulle enrichie (balisage riche accepté)
is_super_tooltip_imagestring""Image de cette info-bulle enrichie

Méthodes #

MéthodeRô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) → longPose 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_itemHandle 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_menuHandle 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) → longRetire 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) → longRetire 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énementDé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 et ue_auto_height ne part qu'une fois. Avec ib_wrap = true, la barre revient à la ligne : elle ne défile jamais, sa hauteur suit les rangées et ue_auto_height vous dit de combien à chaque changement de largeur.


Au clavier #

ToucheEffet
Alt · F10Donne 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 + lettreOuvre 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èchesParcourent 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éeDans 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
ÉchapReferme 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_selected ne parte. Edition > Coller colle donc dans le champ en saisie, et GetFocus() 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 #

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.

MembresRôleDétaillé dans
of_count · of_keys_at · of_hasParcourir ce que le composant contient3.2 Les items
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.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.


← Référence des composants · Sommaire du guide