PBToolboxAI v1 ← Site

4. Thèmes et apparence #

← Socle commun · Sommaire · Langue et RTL →


4.1 Les thèmes : deux axes #

Un thème se compose d'un style et d'un mode :

AxeValeurs
Style (is_theme_style)fluent · metro · office · office2007 · office2003
Mode (is_theme_mode)light · dark

Soit dix thèmes, nommés <style>-<mode> : fluent-light, fluent-dark, office2007-light, metro-dark


4.2 Le thème par défaut de l'application (recommandé) #

Posez le thème une fois pour toute l'application, avant l'ouverture de la première fenêtre. Il est injecté dans chaque composant avant son premier rendu : aucun flash de style clair sur une application sombre.

// Event open de l'objet application
PBT_SetDefaultTheme("fluent-dark")
PBT_SetDefaultThemeAccent(RGB(0, 120, 212))   // optionnel

Le changement à chaud est possible à tout moment : tous les composants déjà ouverts se re-thèment instantanément.

// Bascule clair / sombre depuis un bouton de l'application
PBT_SetDefaultTheme("fluent-light")
FonctionEffet
PBT_SetDefaultTheme (string as_nom)Thème par défaut du processus (diffusé à tous les composants)
PBT_GetDefaultTheme ( ) → stringThème par défaut courant
PBT_SetDefaultThemeAccent (long al_couleur)Couleur d'accent par défaut (-1 = accent natif du thème)
PBT_GetDefaultThemeAccent ( ) → longAccent par défaut courant

4.3 Le thème d'un composant précis #

Un composant peut s'écarter du thème par défaut :

uo_editeur.is_theme_style = uo_editeur.THEME_STYLE_OFFICE2007
uo_editeur.is_theme_mode  = uo_editeur.THEME_MODE_DARK
uo_editeur.il_theme_accent = RGB(200, 60, 40)     // -1 = accent du theme
PropriétéTypeDéfautRôle
is_theme_stylestringfluentStyle visuel (constantes THEME_STYLE_*)
is_theme_modestringlightVariante claire ou sombre (constantes THEME_MODE_*)
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = accent du thème)

Un of_reset() ramène le composant au thème par défaut du processus.

💡 Le plus soigné reste un seul thème pour toute l'application. Réservez le thème local aux cas particuliers (une zone volontairement contrastée, une prévisualisation de thème).


4.4 Recolorer un composant, un groupe ou un item #

Trois portées, les mêmes propriétés. Rien à nommer, rien à deviner.

// Le composant entier
uo_ruban.il_theme_accent = RGB(0, 120, 90)

// Un groupe : tout ce qu'il contient suit
uo_ruban.of_tab("accueil").of_group("presse-papiers").il_accent = RGB(0, 120, 90)

// Un item
uo_liste.of_item("supprimer").il_text_color = RGB(200, 70, 70)
uo_liste.of_item("supprimer").il_back_color = RGB(255, 235, 235)

// Les memes, sous le pointeur
uo_liste.of_item("supprimer").il_back_color_hover = RGB(255, 220, 220)

// Revenir a la couleur du composant
uo_liste.of_item("supprimer").il_text_color = -1
PropriétéCe qu'elle recolore
il_theme_accentle composantson accent, et tout ce qui en dérive : le texte lisible dessus, le fond applicatif, le souligné d'onglet
il_accentun handle d'item, de groupe, d'onglet, de barrece que cette zone peint à l'accent, descendants compris
il_back_color · il_text_coloridemle fond et le texte de l'item
il_back_color_hover · il_text_color_hoveridemles mêmes, sous le pointeur

-1 remet la couleur que donne le composant, elle-même issue du thème. La couleur d'un item survit à la reconstruction du composant : elle est portée par une règle de style visant l'item, pas par une propriété posée sur l'élément du moment. of_reset() efface tout.

il_accent ne repeint que ce que la zone peint avec l'accent — une sélection, un souligné actif, une barre de progression. Un composant qui n'y touche pas n'en montrera rien : pour « cette entrée en rouge », il_back_color et il_text_color sont les bons outils, lus par tous les composants à items.

La police de toute l'application #

PBT_SetDefaultFont("Segoe UI", 14)

Un seul appel habille chaque composant vivant et ceux créés ensuite — la police leur est injectée avant leur premier affichage. Une famille vide ou une taille de 0 rend cette moitié au thème.


4.5 Le fond du composant remonte à PowerBuilder #

Chaque composant peint son fond selon le thème, puis notifie sa couleur : l'userobject adopte cette couleur (backcolor) et lève ue_bg_color, pour que la fenêtre et les contrôles PowerBuilder voisins s'accordent.

// event ue_bg_color d'un composant
parent.backcolor = al_color
st_titre.backcolor = al_color

C'est ce qui permet de mélanger composants PBToolboxAI et contrôles PowerBuilder natifs sans démarcation visible en thème sombre.


4.6 Les images et les icônes #

Partout où un composant attend un chemin d'image (icône de bouton, tuile, [picture=…]…), quatre formes sont acceptées :

FormeExempleUsage
Fichierimg\logo.pngImage telle quelle (png, jpg, gif, bmp, ico, svg, webp)
Ressource de DLLimg\packimages.dll:RIBBONImage packagée dans une DLL de ressources
mono:mono:img\save.svgAplat à la couleur du thème : seule la forme compte
tint:tint:img\logo_couleur.pngDuotone : le relief interne module la couleur du thème

La forme chemin.dll:nom charge une ressource d'une DLL d'images (façon packimages.dll), ouverte en lecture seule (LOAD_LIBRARY_AS_DATAFILE, aucun code exécuté). Cela évite d'expédier des centaines de fichiers en vrac.

Affichage instantané : of_icon #

Un petit glyphe passé par of_icon() est incorporé dans la commande (aucun aller-retour de chargement) : il apparaît dès le premier rendu, sans le clignotement d'une icône chargée après coup.

lnv_bar.of_add_button("save", "Enregistrer", uo_toolbar.of_icon("mono:img\save.svg"))

Transparent à l'usage : au-delà d'une certaine taille, of_icon renvoie le chemin d'origine (l'image est alors chargée puis mise en cache normalement).


4.7 Le texte riche à balises #

N'importe quel libellé de n'importe quel composant accepte un balisage façon BBCode : titre d'onglet, libellé de bouton, texte de barre d'état, message de toast, titre de panneau, texte d'info-bulle…

Les entrées des menus intégrés suivent la même règle — menu contextuel d'un onglet, liste ··· des onglets qui ne tiennent plus, menus de colonne d'une grille : le libellé qu'affiche le menu est celui du contrôle, balises comprises.

Le texte est rendu en nœuds de texte et en <span> : aucune injection HTML n'est possible.

BaliseEffet
[b] [i] [u] [s] / [strike]Gras, italique, souligné, barré
[sub] [super]Indice, exposant
[red]…[/red] (couleurs nommées)Couleur de texte (red, green, blue, orange, teal…)
[accent]…[/accent]Couleur d'accent du thème courant
[color=#rrggbb] / [color=accent]Couleur de texte
[bk=#rrggbb] / [backcolor=accent]Couleur de fond
[font=Consolas]Police
[size=14]Taille absolue, en points (6 à 200)
[size+=30] / [size-=20]Taille relative en % (20 % par défaut)
[picture=chemin] / [picture=chemin,larg,haut]Image en ligne
[br] / [linebreak] / [br:3]Saut de ligne (ou n sauts)
[separator]Filet horizontal
[hyperlink=url]…[/hyperlink]Zone cliquable : le lien s'ouvre toujours dans le navigateur de l'utilisateur, dans tous les composants. L'event ue_hyperlink(as_url) est levé en plus, pour les composants qui l'exposent
[action=id]…[/action]Zone cliquable → event ue_action(as_id), présentée comme un lien
[invisibleaction=id]…[/invisibleaction]Zone cliquable → ue_action, sans le style lien
[bullet]…[/bullet]Puce : élément de liste dont les lignes suivantes s'alignent sur la première, et non sous le marqueur (retrait pendant). [bullet=-] change le marqueur
[foldarea:Titre]…[/foldarea]Bloc repliable : en-tête cliquable ( / +) au-dessus d'un contenu indenté. Le titre accepte les balises
[foldarea-closed:Titre]…[/foldarea]Le même bloc, replié à l'affichage
[[ / ]]Échappement : [[b]] affiche [b] sans l'interpréter
uo_texte.is_text = "Bienvenue sur [b][accent]PBToolboxAI[/accent][/b] [size-=20]v1.0[/size-=20]" &
                   + "[br]Consultez la [hyperlink=https://pbtoolboxai.net]documentation[/hyperlink]."

uo_tab.of_add_page("clients", "[b]Clients[/b] [size-=20](128)[/size-=20]", uo_clients)

uo_st.is_text = "La balise [[b]] met en [b]gras[/b]"   // affiche : La balise [b] met en gras

Afficher une donnée telle quelle. Une valeur venue de votre base peut contenir des crochets : elle serait interprétée. of_escape_markup(), disponible sur tout composant, les double pour vous — enveloppez la donnée, jamais le balisage que vous écrivez vous-même.

// Une donnee metier peut contenir des crochets : sans echappement, elle est
// INTERPRETEE et le texte entre crochets disparait.
ls_libelle = "Solde [net]"
uo_st.is_text = "Compte : " + ls_libelle                          // affiche : Compte :
uo_st.is_text = "Compte : " + uo_st.of_escape_markup(ls_libelle)  // affiche : Compte : Solde [net]

Un texte sans balise n'a aucun surcoût (chemin rapide). Les balises inconnues sont ignorées et leur contenu conservé. Un [hyperlink] s'ouvre partout — libellé, titre d'onglet, panneau de barre d'état, toast, boîte de dialogue : c'est le socle qui s'en charge. L'event ue_action, lui, n'est émis que par les composants de texte interactifs (statictext) ; ailleurs, [action] sert au seul formatage.

Seuls http, https et mailto sont ouverts. Un libellé transporte souvent une donnée venue de votre base : confier un schéma quelconque au système transformerait un libellé en lanceur de programmes.

Un [foldarea] est un bloc : il occupe toute la largeur et se replie d'un clic sur son en-tête, sans aller-retour avec PowerBuilder. Les blocs s'imbriquent, et lorsque le composant suit la hauteur de son contenu (ib_auto_height), cette hauteur est renotifiée à chaque repli. Le titre est lui-même du texte à balises : rien n'est mis en gras à votre place, [foldarea:[b]Total[/b]] s'en charge.


← Socle commun · Sommaire · Langue et RTL →