# 4. Temi e aspetto #

← Base comune · Sommario · Lingua e RTL →

## 4.1 I temi: due assi #

Un tema si compone di uno stile e di una modalità:

Asse | Valori
--- | ---
Stile (`is_theme_style`) | `fluent` · `metro` · `office` · `office2007` · `office2003`
Modalità (`is_theme_mode`) | `light` · `dark`

In tutto dieci temi, denominati `<style>-<mode>`: `fluent-light`, `fluent-dark`, `office2007-light`, `metro-dark`…

## 4.2 Il tema predefinito dell'applicazione (consigliato) #

Imposti il tema una volta sola per tutta l'applicazione, prima dell'apertura della prima finestra. Viene iniettato in ogni componente prima del suo primo rendering: nessun lampeggio di stile chiaro su un'applicazione scura.

    // Event open dell'oggetto applicazione
    PBT_SetDefaultTheme("fluent-dark")
    PBT_SetDefaultThemeAccent(RGB(0, 120, 212))   // facoltativo

Il cambio a caldo è possibile in qualsiasi momento: tutti i componenti già aperti cambiano tema istantaneamente.

    // Commutazione chiaro / scuro da un pulsante dell'applicazione
    PBT_SetDefaultTheme("fluent-light")

Funzione | Effetto
--- | ---
`PBT_SetDefaultTheme (string as_nom)` | Tema predefinito del processo (diffuso a tutti i componenti)
`PBT_GetDefaultTheme ( )` → string | Tema predefinito corrente
`PBT_SetDefaultThemeAccent (long al_couleur)` | Colore d'accento predefinito (`-1` = accento nativo del tema)
`PBT_GetDefaultThemeAccent ( )` → long | Accento predefinito corrente

## 4.3 Il tema di un componente specifico #

Un componente può discostarsi dal tema predefinito:

    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 = accento del tema

Proprietà | Tipo | Predefinito | Ruolo
--- | --- | --- | ---
`is_theme_style` | string | `fluent` | Stile visivo (costanti `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Variante chiara o scura (costanti `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Colore d'accento di questo componente (`-1` = accento del tema)

Un `of_reset()` riporta il componente al tema predefinito del processo.

> 💡 La soluzione più curata resta un unico tema per tutta l'applicazione. Riservi il tema locale ai casi particolari (un'area volutamente contrastata, un'anteprima di tema).

## 4.4 Ricolorare un componente, un gruppo o un elemento #

Tre portate, le stesse proprietà. Niente da nominare, niente da indovinare.

    // Il componente intero
    uo_ruban.il_theme_accent = RGB(0, 120, 90)

    // Un gruppo : tutto cio che contiene segue
    uo_ruban.of_tab("accueil").of_group("presse-papiers").il_accent = RGB(0, 120, 90)

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

    // Gli stessi due, sotto il puntatore
    uo_liste.of_item("supprimer").il_back_color_hover = RGB(255, 220, 220)

    // Tornare al colore del componente
    uo_liste.of_item("supprimer").il_text_color = -1

Proprietà | Dove | Che cosa ricolora
--- | --- | ---
`il_theme_accent` | il componente | il suo accento e tutto ciò che ne deriva: il testo leggibile sopra, lo sfondo applicativo, la sottolineatura di scheda
`il_accent` | un handle di elemento, gruppo, scheda o barra | ciò che quella zona dipinge con l'accento, discendenti compresi
`il_back_color` · `il_text_color` | idem | lo sfondo e il testo dell'elemento
`il_back_color_hover` · `il_text_color_hover` | idem | gli stessi due, sotto il puntatore

`-1` ripristina il colore che dà il componente, a sua volta preso dal tema. Il colore di un elemento sopravvive alla ricostruzione del componente: è portato da una regola di stile che mira all'elemento, non da una proprietà posata sul nodo del momento. `of_reset()` azzera tutto.

`il_accent` ridipinge soltanto ciò che la zona dipinge con l'accento — una selezione, una sottolineatura attiva, una barra di avanzamento. Un componente che non lo usa non ne mostrerà nulla: per «questa voce in rosso», `il_back_color` e `il_text_color` sono gli strumenti giusti, letti da ogni componente con elementi.

### Il carattere di tutta l'applicazione #

    PBT_SetDefaultFont("Segoe UI", 14)

Una sola chiamata veste ogni componente vivo e quelli creati in seguito — il carattere è iniettato prima del loro primo disegno. Una famiglia vuota o una dimensione di `0` restituisce quella metà al tema.

## 4.5 Lo sfondo del componente viene segnalato a PowerBuilder #

Ogni componente dipinge il proprio sfondo in base al tema, poi ne notifica il colore: l'userobject adotta questo colore (`backcolor`) e attiva `ue_bg_color`, affinché la finestra e i controlli PowerBuilder adiacenti si accordino.

    // event ue_bg_color di un componente
    parent.backcolor = al_color
    st_titre.backcolor = al_color

È ciò che consente di mescolare componenti PBToolboxAI e controlli PowerBuilder nativi senza alcuna demarcazione visibile in tema scuro.

## 4.6 Immagini e icone #

Ovunque un componente si attenda un percorso di immagine (icona di un pulsante, riquadro, `[picture=…]`…), sono accettate quattro forme:

Forma | Esempio | Utilizzo
--- | --- | ---
File | `img\logo.png` | Immagine così com'è (png, jpg, gif, bmp, ico, svg, webp)
Risorsa di DLL | `img\packimages.dll:RIBBON` | Immagine inclusa in una DLL di risorse
`mono:` | `mono:img\save.svg` | Tinta unita nel colore del tema: conta solo la forma
`tint:` | `tint:img\logo_couleur.png` | Duotone: il rilievo interno modula il colore del tema

- `mono:` si utilizza per tutti i glifi monocromatici (icone bianche o nere): si ricolorano automaticamente sia in chiaro sia in scuro.
- `tint:` armonizza un'icona a colori con il tema conservandone le sfumature. Da non utilizzare mai su un glifo bianco (resterebbe bianco).
- Senza prefisso, l'immagine multicolore viene lasciata intatta.

La forma `percorso.dll:nome` carica una risorsa da una DLL di immagini (in stile `packimages.dll`), aperta in sola lettura (`LOAD_LIBRARY_AS_DATAFILE`, nessun codice eseguito). Questo evita di distribuire centinaia di file sparsi.

### Visualizzazione istantanea: `of_icon` #

Un piccolo glifo passato tramite `of_icon()` viene incorporato nel comando (nessun andirivieni di caricamento): compare fin dal primo rendering, senza lo sfarfallio di un'icona caricata in un secondo momento.

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

Trasparente all'uso: oltre una certa dimensione, `of_icon` restituisce il percorso originale (l'immagine viene allora caricata e memorizzata nella cache normalmente).

## 4.7 Il testo formattato con tag #

Qualsiasi etichetta di qualsiasi componente accetta una formattazione in stile BBCode: titolo di una scheda, etichetta di un pulsante, testo della barra di stato, messaggio di toast, titolo di un pannello, testo di un tooltip…

Le voci dei menu integrati seguono la stessa regola — menu contestuale di una scheda, elenco `···` delle schede che non entrano più, menu di colonna di una griglia: l'etichetta mostrata dal menu è quella del controllo, marcatura compresa.

Il testo viene renderizzato in nodi di testo e `<span>`: nessuna iniezione HTML è possibile.

Tag | Effetto
--- | ---
`[b] [i] [u] [s]` / `[strike]` | Grassetto, corsivo, sottolineato, barrato
`[sub] [super]` | Pedice, apice
`[red]…[/red]` (colori denominati) | Colore del testo (`red`, `green`, `blue`, `orange`, `teal`…)
`[accent]…[/accent]` | Colore d'accento del tema corrente
`[color=#rrggbb]` / `[color=accent]` | Colore del testo
`[bk=#rrggbb]` / `[backcolor=accent]` | Colore di sfondo
`[font=Consolas]` | Carattere
`[size=14]` | Dimensione assoluta, in punti (da 6 a 200)
`[size+=30]` / `[size-=20]` | Dimensione relativa in % (20 % per impostazione predefinita)
`[picture=percorso]` / `[picture=percorso,largh,alt]` | Immagine in linea
`[br]` / `[linebreak]` / `[br:3]` | Interruzione di riga (o n interruzioni)
`[separator]` | Filetto orizzontale
`[hyperlink=url]…[/hyperlink]` | Area cliccabile: il collegamento si apre sempre nel browser dell'utente, in tutti i componenti. L'event `ue_hyperlink(as_url)` viene sollevato in più, per i componenti che lo espongono
`[action=id]…[/action]` | Area cliccabile → event `ue_action(as_id)`, presentata come un collegamento
`[invisibleaction=id]…[/invisibleaction]` | Area cliccabile → `ue_action`, senza lo stile del collegamento
`[bullet]…[/bullet]` | Punto elenco: voce di elenco le cui righe successive si allineano alla prima invece di tornare sotto il marcatore (rientro sporgente). `[bullet=-]` cambia il marcatore
`[foldarea:Titolo]…[/foldarea]` | Blocco comprimibile: intestazione cliccabile (`−` / `+`) sopra un contenuto rientrato. Il titolo accetta i tag
`[foldarea-closed:Titolo]…[/foldarea]` | Lo stesso blocco, compresso alla visualizzazione
`[[` / `]]` | Escape: `[[b]]` visualizza `[b]` senza interpretarlo

    uo_texte.is_text = "Benvenuto in [b][accent]PBToolboxAI[/accent][/b] [size-=20]v1.0[/size-=20]" &
                       + "[br]Consulti la [hyperlink=https://pbtoolboxai.net]documentazione[/hyperlink]."

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

    uo_st.is_text = "Il tag [[b]] mette in [b]grassetto[/b]"   // visualizza: Il tag [b] mette in grassetto

Mostrare un dato tale e quale. Un valore che viene dalla sua base può contenere parentesi quadre: verrebbe interpretato. `of_escape_markup()`, disponibile su ogni componente, le raddoppia al posto suo — avvolga il dato, mai la marcatura che scrive lei stesso.

    // Un dato applicativo puo contenere parentesi quadre : senza escape viene
    // INTERPRETATO e il testo fra parentesi sparisce.
    ls_libelle = "Saldo [netto]"
    uo_st.is_text = "Conto : " + ls_libelle                          // mostra : Conto :
    uo_st.is_text = "Conto : " + uo_st.of_escape_markup(ls_libelle)  // mostra : Conto : Saldo [netto]

Un testo privo di tag non comporta alcun sovraccosto (percorso rapido). I tag sconosciuti vengono ignorati e il loro contenuto conservato. Un `[hyperlink]` si apre ovunque — etichetta, titolo di scheda, pannello della barra di stato, toast, finestra di dialogo: se ne occupa il nucleo. L'event `ue_action`, invece, viene emesso solo dai componenti di testo interattivi (`statictext`); altrove, `[action]` serve unicamente alla formattazione.

Vengono aperti solo `http`, `https` e `mailto`. Un'etichetta trasporta spesso un dato che viene dalla Sua base: affidare al sistema uno schema qualunque trasformerebbe un'etichetta in un lanciatore di programmi.

Un `[foldarea]` è un blocco: occupa tutta la larghezza e si comprime con un clic sulla sua intestazione, senza alcun passaggio da PowerBuilder. I blocchi si annidano e, se il componente segue l'altezza del proprio contenuto (`ib_auto_height`), tale altezza viene notificata di nuovo a ogni compressione. Anche il titolo è testo con tag: nulla viene messo in grassetto al posto vostro, ci pensa `[foldarea:[b]Total[/b]]`.

← Base comune · Sommario · Lingua e RTL →