# dockcontainer — `u_pbt_dockcontainer` #

← Riferimento dei componenti · Sommario della guida

> Pannelli ancorabili in stile Visual Studio: ancoraggio tramite trascinamento, impilamento in schede, separatori ridimensionabili, finestre mobili, nascondi automaticamente — e salvataggio/ripristino della disposizione.

> ▶ Vederlo dal vivo — Applicazione dimostrativa, riquadro Dock container: l'anteprima, il codice che lo produce e questa pagina, affiancati.

## In breve #

Userobject | `u_pbt_dockcontainer`
Classe degli item | `n_pbt_dock_panel` (un pannello)
Serve per | Dare a una finestra PowerBuilder l'ergonomia di un IDE moderno: l'utente organizza da sé i propri pannelli e ritrova la disposizione alla sessione successiva

Come in tab, ogni pannello ospita un vero controllo PowerBuilder (`dragobject`): userobject, DataWindow o un altro componente PBToolboxAI. Vedere Ospitare veri controlli PowerBuilder.

## Avvio rapido #

    // event open della finestra : i controlli dei pannelli sono gia posati su di essa
    uo_dock.of_add_panel(/*chiave*/ "document", /*posizione*/ "", /*relativo_a*/ "", &
                         /*dimensione*/ 0, /*titolo*/ "Documento", /*contenuto*/ uo_editeur)

    uo_dock.of_add_panel(/*chiave*/ "explorateur", /*posizione*/ uo_dock.POSITION_START, &
                         /*relativo_a*/ "document", /*dimensione*/ 260, &
                         /*titolo*/ "Esplora risorse", /*contenuto*/ uo_arbre)

    uo_dock.of_add_panel(/*chiave*/ "proprietes", /*posizione*/ uo_dock.POSITION_END, &
                         /*relativo_a*/ "document", /*dimensione*/ 300, &
                         /*titolo*/ "Proprieta", /*contenuto*/ uo_props)

    // L'area centrale : dall'ancoraggio non e chiudibile, ne mobile, ne nascondibile
    uo_dock.is_main = "document"

## Proprietà #

Proprietà | Tipo | Predefinito | Ruolo
--- | --- | --- | ---
`is_main` | string | `""` | Chiave del pannello principale: l'area di documento centrale, che non può essere né nascosta né staccata. Il pannello deve già esistere
`is_theme_style` | string | `fluent` | Stile visivo del componente (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)
`is_tooltip` | string | `""` | Tooltip semplice mostrato al passaggio del mouse sul componente
`is_super_tooltip_title` | string | `""` | Titolo del tooltip avanzato (prevale su `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Testo del tooltip avanzato (markup avanzato accettato)
`is_super_tooltip_image` | string | `""` | Immagine del tooltip avanzato

### Posizioni di ancoraggio #

Le costanti del componente alimentano `as_position` in `of_add_panel` e `of_move_panel`:

Costante | Valore | Effetto
--- | --- | ---
`POSITION_START` | `"start"` | Il nuovo pannello si ancora sul lato di inizio lettura del pannello di riferimento (a sinistra con scrittura da sinistra a destra)
`POSITION_END` | `"end"` | … sul lato di fine lettura
`POSITION_TOP` | `"top"` | … al di sopra
`POSITION_BOTTOM` | `"bottom"` | … al di sotto
`POSITION_STACK` | `"stack"` | Il pannello viene impilato come scheda sul pannello di riferimento. Valore adottato se `as_position` è vuoto

### Proprietà di un pannello — `n_pbt_dock_panel` #

Ottenute tramite `of_item(chiave)`.

Proprietà | Tipo | Predefinito | Ruolo
--- | --- | --- | ---
`is_title` | string | `""` | Titolo visualizzato sulla scheda del pannello. Accetta il testo formattato con tag
`is_short_title` | string | `""` | Forma breve del titolo, per i punti in cui lo spazio manca: la barra di bordo di un pannello appuntato (sempre — è una striscia sottile) e la scheda di una pila, ma solo quando il titolo completo non ci sta più, cosa che viene misurata e non indovinata. L'intestazione del pannello conserva il titolo completo. `""` = nessuna forma breve
`ib_visible` | boolean | `true` | Mostra o nasconde questo pannello
`ib_pinned` | boolean | `true` | `true` = bloccato in posizione; `false` = il pannello si ripiega a linguetta sul bordo e si apre solo al passaggio del mouse (nascondi automaticamente)
`is_header_color` | string | `""` | Colore dell'intestazione di questo pannello. Vuoto = decide il tema; `HEADER_COLOR_ACCENT` segue l'accento del tema (e continua a seguirlo dopo un cambio di tema, cosa che un codice fisso non farebbe); altrimenti un `#rrggbb`. Il colore di testo leggibile viene calcolato
`is_border_color` | string | `""` | Colore del bordo di questo pannello, stessa grammatica. Contorna la cornice e l'intestazione, che hanno ciascuna il proprio: colorarne una sola lascia una giunzione visibile. Segue il pannello nel suo riquadro a scomparsa
`is_tooltip` | string | `""` | Tooltip semplice mostrato al passaggio del mouse sull'item
`is_super_tooltip_title` | string | `""` | Titolo del tooltip avanzato dell'item (prevale su `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Testo del tooltip avanzato dell'item (markup avanzato accettato)
`is_super_tooltip_image` | string | `""` | Immagine del tooltip avanzato dell'item

## Metodi #

Metodo | Ruolo
--- | ---
`of_add_panel (string as_key, string as_position, string as_relative_to, integer ai_size, string as_title, dragobject ado_content)` | Aggiunge un pannello chiudibile e ospita il controllo. `as_relative_to` = chiave del pannello contro cui si ancora (vuoto = la radice); `ai_size` = dimensione iniziale in pixel (`0` = automatica)
`of_add_panel (…, boolean ab_closable)` | Idem, con `ab_closable = false` per un pannello senza pulsante di chiusura
`of_select_panel (string as_key)` | Porta un pannello in primo piano nel suo gruppo di schede
`of_move_panel (string as_key, string as_target, string as_position)` | Riorganizza dal codice, esattamente come se l'utente avesse trascinato la scheda
`of_move_panel (string as_key, string as_target, string as_position, integer ai_index)` | Lo stesso, indicando il rango del pannello nella pila della destinazione (0 = primo, `-1` = ultimo). Solo una pila è un elenco ordinato: l'indice viene ignorato per `POSITION_START` / `END` / `TOP` / `BOTTOM`
`of_float_panel (string as_key)` | Stacca il pannello in una vera finestra mobile spostabile e ridimensionabile. Chiudendola il pannello si riancora (`ue_panel_docked`)
`of_notify_panel (string as_key)` | Segnala contenuti nuovi: se il pannello non è visibile, la sua scheda mostra un contatore di elementi non visti, azzerato alla selezione
`of_clear_notify (string as_key)` | Azzera quel contatore senza mostrare il pannello. Selezionare la scheda era l unico altro modo, il che è sbagliato quando il Suo codice sa che il contenuto stesso è sparito
`of_remove_panel (string as_key)` | Rimuove il pannello e restituisce il controllo alla sua finestra d'origine
`of_get_layout ( )` | Restituisce la disposizione corrente (albero delle suddivisioni, rapporti, schede, visibilità) sotto forma di stringa, da memorizzare in un file, in una base dati o nel registro
`of_set_layout (string as_json)` | Ripristina una disposizione ottenuta con `of_get_layout`. I pannelli devono essere stati ricreati prima della chiamata; quelli assenti dalla disposizione vengono agganciati al primo gruppo
`of_item (string as_id)` | Handle `n_pbt_dock_panel` del pannello (creato al primo accesso)
`of_refresh_panel (string as_key)` | Aggiorna il rendering di un pannello costruito fuori schermo, senza sfarfallio
`of_relayout ( )` | Ricalcola e ripubblica tutte le aree affinché i controlli ospitati vengano riposizionati
`of_reset ( )` | Svuota il contenitore: ogni controllo ospitato viene restituito alla sua finestra d'origine, gli handle dei pannelli vengono liberati, la disposizione memorizzata viene cancellata
`of_set_redraw (boolean)` | Raggruppa una raffica di modifiche in un unico rendering
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Esporta il rendering come immagine

## Event #

Event | Attivato quando
--- | ---
`ue_panel_selected (string as_key)` | Un pannello diventa il pannello attivo del suo gruppo
`ue_panel_closed (string as_key)` | L'utente chiude un pannello
`ue_panel_pinned (string as_key, boolean ab_pinned)` | Un pannello viene bloccato (`true`) o sbloccato in nascondi automaticamente (`false`)
`ue_panel_floated (string as_key)` | Un pannello viene staccato in finestra mobile
`ue_panel_docked (string as_key)` | Un pannello mobile viene riancorato
`ue_layout_changed (string as_json)` | La disposizione è cambiata (trascinamento, ridimensionamento, ancoraggio). Il parametro porta la nuova disposizione, pronta per essere salvata
`ue_ready ( )` | Il componente ha terminato il caricamento; tutto ciò che è stato inviato prima è stato riprodotto
`ue_runtime_missing ( )` | Il runtime WebView2 è assente: il componente resta vuoto
`ue_bg_color (long al_color)` | Il componente ha calcolato il colore di sfondo del proprio tema; l'userobject lo ha già adottato (`backcolor`)

## Da tastiera #

Il contenuto di un pannello è un vero controllo PowerBuilder: lì la tastiera appartiene al suo codice, come in qualunque finestra. Ciò di cui si occupa il componente è la propria cornice — intestazioni, schede, splitter:

Tasto | Effetto
--- | ---
Frecce su una scheda | Passano al pannello precedente / successivo del gruppo e lo selezionano. Una barra di schede è un solo arresto di tabulazione
Inizio / Fine su una scheda | Primo / ultimo pannello del gruppo
Frecce su uno splitter | Spostano la separazione del 2 %, solo lungo l'asse dello splitter
Pag su / Pag giù su uno splitter | Lo stesso, a passi del 10 %
Esc | Richiude il pannello scorrevole aperto da un pulsante di bordo

Uno splitter è un `separator` focalizzabile che annuncia la propria posizione; i pulsanti dell'intestazione (staccare, nascondere, chiudere) portano un nome, e il pannello attivo di un gruppo è contrassegnato con `aria-selected`. Uno spostamento da tastiera risale in `ue_layout_changed` esattamente come un trascinamento con il mouse.

## Esempi #

### Una finestra in stile IDE #

    // event open : ogni contenuto e un vero controllo PB posato sulla finestra
    uo_dock.of_add_panel("document", "", "", 0, "Documento", uo_editeur)
    uo_dock.of_add_panel("explorateur", uo_dock.POSITION_START,   "document", 260, "Esplora risorse", uo_arbre)
    uo_dock.of_add_panel("proprietes",  uo_dock.POSITION_END,  "document", 300, "Proprieta",  uo_props)
    uo_dock.of_add_panel("sortie",      uo_dock.POSITION_BOTTOM, "document", 200, "Output",      uo_console)

    // Un secondo pannello impilato come scheda su "proprietes"
    uo_dock.of_add_panel("aide", uo_dock.POSITION_STACK, "proprietes", 0, "Guida", uo_aide)

    uo_dock.is_main = "document"

### Memorizzare e ripristinare la disposizione dell'utente #

    // event close della finestra : salvare cio che l'utente ha organizzato
    string ls_disposition
    ls_disposition = uo_dock.of_get_layout()
    of_enregistrer_preference("dock_principal", ls_disposition)

    // event open : RICREARE prima i pannelli, ripristinare poi
    string ls_disposition

    of_creer_les_panneaux()          // le chiamate of_add_panel qui sopra

    ls_disposition = of_lire_preference("dock_principal")
    if ls_disposition <> "" then uo_dock.of_set_layout(ls_disposition)

> L'ordine è tassativo: `of_set_layout` non crea alcun pannello, si limita a ricollocare quelli già esistenti.

### Seguire le modifiche in continuo #

    // event ue_layout_changed di uo_dock : (string as_json)
    // Salvataggio immediato, senza attendere la chiusura della finestra.
    of_enregistrer_preference("dock_principal", as_json)

### Pilotare un pannello tramite il suo handle #

    n_pbt_dock_panel lnv_panneau

    lnv_panneau = uo_dock.of_item("proprietes")
    lnv_panneau.is_title  = "Proprietà (3 modificate)"
    lnv_panneau.ib_pinned = false        // si ripiega a linguetta sul bordo

    // Nascondere un pannello riservato agli amministratori
    uo_dock.of_item("audit").ib_visible = gb_administrateur

### Attirare l'attenzione su un pannello in secondo piano #

    // Un'elaborazione in background ha scritto nella console : segnalare senza rubare il focus
    uo_dock.of_notify_panel("sortie")

### Riorganizzare dal codice #

    // Spostare un pannello come se l'utente avesse trascinato la sua scheda
    uo_dock.of_move_panel(/*chiave*/ "sortie", /*destinazione*/ "document", /*posizione*/ "bottom")

    // Impilarlo come scheda su un altro pannello
    uo_dock.of_move_panel(/*chiave*/ "aide", /*destinazione*/ "proprietes", /*posizione*/ "stack")

### Staccare un pannello su un secondo schermo #

    // Finestra mobile nativa : l'utente puo posarla su un altro schermo
    uo_dock.of_float_panel("proprietes")

    // event ue_panel_docked di uo_dock : (string as_key)
    // L'utente ha richiuso la finestra mobile : il pannello e tornato.
    of_journaliser("Pannello riancorato : " + as_key)

### Chiudere correttamente un pannello #

    // event ue_panel_closed di uo_dock : (string as_key)
    // Rimuovere anche il pannello dal contenitore per liberare il controllo ospitato.
    uo_dock.of_remove_panel(as_key)

## Buone pratiche #

- Designi sempre un pannello principale con `is_main`: senza area centrale, l'utente può nascondere tutto e ritrovarsi davanti a una finestra vuota.
- Salvi la disposizione su `ue_layout_changed` anziché alla sola chiusura: così una chiusura anomala non fa perdere nulla.
- `of_set_layout` viene dopo le chiamate `of_add_panel`, mai prima.
- Utilizzi `of_notify_panel` per le elaborazioni in background: è meno invadente di una finestra di dialogo e l'informazione resta visibile.
- Un controllo ospitato è una finestra nativa: si disegna al di sopra dello strato web, nessun effetto visivo del componente può passargli sopra.
- `of_reset()` prima di ogni ricostruzione: senza di esso, i controlli precedentemente ospitati restano riagganciati nel contenitore svuotato e il riutilizzo di una chiave non riesce.
- Per semplici pagine esclusive, senza ancoraggio né finestre mobili, tab è più leggero.

← Riferimento dei componenti · Sommario della guida