# picture — `u_pbt_picture` #

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

> Affichage d'image : tous les formats courants, modes de cadrage, alignement, grisage automatique et pastille de compteur.

> ▶ Le voir en vrai — Application de démonstration, tuile Picture : l'aperçu, le code qui le produit et cette page, côte à côte.

## En bref #

Userobject | `u_pbt_picture`
Classe d'items | — (composant sans items)
Sert à | Remplacer un `picture` PowerBuilder : formats modernes (SVG, WebP, GIF animé), cadrage maîtrisé, image cliquable, grisage automatique
Options opt-in | `ib_track_mouse`

## Démarrage rapide #

    // event open de la fenetre
    uo_image.is_source  = "img\logo.png"
    uo_image.is_stretch = uo_image.STRETCH_UNIFORM   // adapte sans deformer
    uo_image.is_align   = uo_image.ALIGN_CENTER
    uo_image.is_tooltip = "Logo de la societe"

## D'où vient l'image : `is_source` #

`is_source` accepte quatre formes, toutes interchangeables :

Forme | Exemple | Usage
--- | --- | ---
Fichier local | `img\logo.png` | png, jpg, bmp, gif, ico, svg, webp
Adresse web | `https://…/logo.png` | Image chargée depuis un serveur (`http` ou `https`)
Données incorporées | `data:image/png;base64,…` | Image déjà en mémoire, sans fichier intermédiaire
Ressource de DLL | `img\packimages.dll:SAMPLE` | Image packagée dans une DLL de ressources

Un préfixe `anim:` peut être posé devant un GIF pour signaler explicitement une animation (les GIF s'animent de toute façon).

Quand le même nom existe sous plusieurs types de ressource dans une DLL, précisez le type : `img\packimages.dll:PNG/SAMPLE`, `SVG/SAMPLE`, `ICON/APP`, `RCDATA/BLOB`. Voir Images et icônes pour les préfixes `mono:` et `tint:`, qui recolorent un glyphe selon le thème.

## Comment elle est cadrée : `is_stretch` #

Constante | Effet
--- | ---
`STRETCH_UNIFORM` | Défaut. L'image est mise à l'échelle sans déformation, entièrement visible ; des marges peuvent apparaître
`STRETCH_UNIFORMTOFILL` | Mise à l'échelle sans déformation, mais le cadre est entièrement rempli ; les débordements sont rognés
`STRETCH_FILL` | L'image est étirée pour occuper exactement le cadre — elle peut être déformée
`STRETCH_NONE` | Taille d'origine, sans mise à l'échelle

`is_align` décide de la position horizontale de l'image lorsqu'elle est plus petite que le contrôle : `ALIGN_CENTER` (défaut), `ALIGN_START`, `ALIGN_END`. L'axe vertical a sa propre propriété, `is_valign`.

## Constantes #

Constante | Valeur | Pour
--- | --- | ---
`STRETCH_NONE` · `STRETCH_FILL` · `STRETCH_UNIFORM` · `STRETCH_UNIFORMTOFILL` | `"none"` `"fill"` `"uniform"` `"uniformtofill"` | `is_stretch`
`ALIGN_CENTER` · `ALIGN_START` · `ALIGN_END` | `"center"` `"start"` `"end"` | `is_align`
`VALIGN_TOP` · `VALIGN_CENTER` · `VALIGN_BOTTOM` | `"top"` `"center"` `"bottom"` | `is_valign`
`is_valign` | string | `VALIGN_CENTER` | Placement vertical quand l image est plus petite que le contrôle : `VALIGN_TOP`, `VALIGN_CENTER`, `VALIGN_BOTTOM`. Les deux axes sont indépendants — `is_align` donne la colonne, celle-ci la ligne — ce qui rend un coin atteignable
`ROTATION_NONE` · `ROTATION_90` · `ROTATION_180` · `ROTATION_270` | `0` `90` `180` `270` | `ii_rotation`

`ALIGN_START` et `ALIGN_END` sont logiques : ils suivent le sens d'écriture (Langue et RTL). Les valeurs physiques `left` et `right` restent acceptées comme alias.

## Propriétés #

Propriété | Type | Défaut | Rôle
--- | --- | --- | ---
`is_source` | string | `""` | L'image à afficher (voir les quatre formes ci-dessus)
`is_stretch` | string | `"uniform"` | Mode de cadrage : `STRETCH_NONE`, `STRETCH_FILL`, `STRETCH_UNIFORM`, `STRETCH_UNIFORMTOFILL`
`is_align` | string | `"center"` | Placement horizontal quand l'image est plus petite que le contrôle : `ALIGN_CENTER`, `ALIGN_START`, `ALIGN_END`. L'axe vertical est `is_valign`
`ib_enabled` | boolean | `true` | À `false`, l'image est affichée en niveaux de gris
`ii_badge` | integer | `0` | Pastille de compteur en angle supérieur droit (`0` = aucune)
`il_badge_color` | long | `0` | Fond de la pastille, en RGB PowerBuilder (`0` = la couleur qui vient du thème). La couleur du texte est choisie automatiquement pour que le compteur reste lisible
`ii_badge_size` | integer | `0` | Hauteur de la pastille en pixels (`0` = la taille qui vient du thème). La taille de la police suit toute seule : le compteur reste centré quelle que soit la dimension
`ib_track_mouse` | boolean | `false` | Opt-in : active `ue_mouse_enter` / `ue_mouse_leave`
`is_placeholder` | string | `""` | Image d attente, affichée tant que `is_source` est vide (un cadre « ajouter une photo », une silhouette). Présentée estompée : un substitut n est pas le contenu, et il n est jamais annoncé comme une image chargée. Accepte le préfixe `mono:`, qui recolore un pictogramme monochrome avec le thème
`is_error_source` | string | `""` | Image de repli quand la source échoue au chargement. Laissez-la vide et le composant affiche son propre pictogramme d erreur — jamais une boîte vide, qui ne dit rien à l utilisateur alors que `ue_error` ne part que vers votre code. Accepte le préfixe `mono:`
`ii_rotation` | integer | `0` | Quarts de tour, pour les scans et les photos qui arrivent couchés : `ROTATION_NONE`, `ROTATION_90`, `ROTATION_180`, `ROTATION_270` (toute autre valeur vaut 0). Un quart de tour échange aussi les axes de cadrage, de sorte que l'image garde ses proportions au lieu d'être écrasée
`ib_mirror` | boolean | `false` | Miroir horizontal, appliqué par-dessus la rotation
`ib_zoomable` | boolean | `false` | Opt-in : l'utilisateur peut se rapprocher (molette), se déplacer (glisser) et revenir au cadrage (double-clic). Pour un plan, un scan, une photo — là où quatre modes de cadrage figés ne suffisent pas
`id_zoom` | double | `1.0` | Facteur de zoom : `1.0` = l'image entière tient, jusqu'à `8.0`. La relire donne le facteur courant, molette comprise (`ue_zoom_changed` vous prévient à chaque cran). Nécessite `ib_zoomable`
`ib_allow_drop` | boolean | `false` | Opt-in : accepte les fichiers déposés depuis l'Explorateur Windows. Le cadre montre qu'il est armé, et les chemins complets arrivent par `ue_drop_files` — les charger dans `is_source` reste à votre application
`ib_auto_height` | boolean | `false` | Opt-in : l'userobject prend la hauteur qui respecte les proportions de l'image à sa largeur courante. Pour une image cette hauteur se déduit : inutile de la calculer soi-même à partir des dimensions de `ue_loaded`
`is_theme_style` | string | `fluent` | Style visuel du composant (constantes `THEME_STYLE_*`)
`is_theme_mode` | string | `light` | Variante claire ou sombre (constantes `THEME_MODE_*`)
`il_theme_accent` | long | `-1` | Couleur d'accent de ce composant (`-1` = accent 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

## Méthodes #

Méthode | Rôle
--- | ---
`of_reset ( )` | Remet toutes les propriétés à leur défaut et retire l'image
`of_set_redraw (boolean)` | Regroupe une rafale de modifications en un seul rendu
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Exporte le rendu en image

## Événements #

Événement | Déclenché quand
--- | ---
`ue_clicked ( )` | Clic gauche sur l'image
`ue_loaded (long al_width, long al_height)` | L'image est chargée ; les paramètres portent ses dimensions d'origine en pixels
`ue_error (string as_message)` | L'image n'a pas pu être chargée (fichier absent, adresse injoignable, format refusé)
`ue_rclicked ( )` | Clic droit sur l'image
`ue_double_clicked ( )` | Double-clic sur l'image. Les clics simples qui le précèdent sont émis aussi, dans le même ordre. Quand `ib_zoomable` est actif, le double-clic ramène également au cadrage : l'événement part dans les deux cas, à vous de décider ce qu'il signifie
`ue_zoom_changed (double ad_zoom)` | Le facteur de zoom a changé, à la molette comme par `id_zoom`. `1.0` signifie que l'image entière tient de nouveau
`ue_auto_height (long al_height)` | Le composant s'est arrêté sur une nouvelle hauteur ; l'userobject est déjà redimensionné quand l'événement part. Nécessite `ib_auto_height`
`ue_drop_files (string as_files[])` | Des fichiers ont été déposés depuis l'Explorateur : chemins complets, une entrée par fichier. Nécessite `ib_allow_drop`
`ue_drag_enter ( )` | Un glissement de fichiers entre sur le composant (`ib_allow_drop`)
`ue_drag_leave ( )` | Le glissement de fichiers quitte le composant
`ue_mouse_enter ( )` | La souris entre — nécessite `ib_track_mouse = true`
`ue_mouse_leave ( )` | La souris sort — nécessite `ib_track_mouse = true`
`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`)

## Exemples #

### Afficher la photo d'une fiche #

    // event ue_row_changed du datawindow : afficher la photo du client courant
    uo_photo.is_source  = "photos\" + ls_code_client + ".jpg"
    uo_photo.is_stretch = uo_photo.STRETCH_UNIFORMTOFILL   // remplit le cadre, le debordement est rogne
    uo_photo.is_align   = uo_photo.ALIGN_CENTER

    // event ue_error de uo_photo : (string as_message)
    uo_photo.is_source = "img\photo_absente.svg"     // image de remplacement

Traiter `ue_error` est la bonne façon de gérer une photo manquante : inutile de tester l'existence du fichier avant de l'affecter.

### Une image cliquable, façon bouton #

    uo_avatar.is_source    = "photos\utilisateur.png"
    uo_avatar.is_tooltip   = "Mon compte"

    // event ue_clicked de uo_avatar
    of_ouvrir_mon_compte()

### Compteur et grisage #

    // Une pastille de notifications sur une icone de messagerie
    uo_messagerie.is_source = "img\packimages.dll:SVG/MAIL"
    uo_messagerie.ii_badge  = ll_non_lus       // 0 fait disparaitre la pastille

    // Pastille rouge au-dela d'un seuil, couleur du theme sinon (0)
    if ll_non_lus > 20 then
        uo_messagerie.il_badge_color = RGB(200, 30, 30)
    else
        uo_messagerie.il_badge_color = 0
    end if

    // Fonction indisponible : l'image passe en niveaux de gris, sans autre image a fournir
    uo_messagerie.ib_enabled = ib_droit_messagerie

Le grisage est calculé automatiquement : vous n'avez pas à fournir une seconde image « désactivée ».

### Connaître les dimensions réelles de l'image #

    uo_apercu.is_source = ls_fichier_choisi

    // event ue_loaded de uo_apercu : (long al_width, long al_height)
    uo_statut.of_item("main").is_text = String(al_width) + " x " + String(al_height) + " px"

    // Une image plus petite que le cadre : ne pas l'agrandir inutilement
    if al_width < uo_apercu.width and al_height < uo_apercu.height then
        uo_apercu.is_stretch = uo_apercu.STRETCH_NONE
    end if

### Une bannière pleine largeur #

    uo_banniere.is_source  = "img\banniere.jpg"
    uo_banniere.is_stretch = uo_banniere.STRETCH_UNIFORMTOFILL   // remplit toute la bande, sans deformer
    uo_banniere.is_valign   = uo_banniere.VALIGN_TOP               // garde le haut de l'image visible

## Bonnes pratiques #

- `STRETCH_UNIFORM` est le mode sûr : il ne déforme jamais. Réservez `STRETCH_FILL` aux fonds décoratifs où la déformation est sans conséquence.
- Pour une photo dans un cadre fixe (trombinoscope, vignette), `STRETCH_UNIFORMTOFILL` donne un rendu régulier, sans marges disgracieuses.
- Regroupez vos icônes dans une DLL de ressources plutôt que de livrer des centaines de fichiers ; la forme `pack.dll:TYPE/NOM` lève toute ambiguïté.
- Pour un glyphe monochrome qui doit suivre le thème clair et sombre, utilisez le préfixe `mono:` (Images et icônes).
- Scriptez `ue_error` sur toute image dont la source dépend des données : c'est votre seul filet en cas de fichier manquant.
- Appelez `of_reset()` avant de réutiliser le composant pour une image de nature différente : sans cela, le mode de cadrage, la pastille ou l'état grisé précédents restent en place.

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