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_zoomable · ib_clickable · ib_allow_drop · ib_auto_height · 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, jfif, bmp, gif, ico, svg, webp, avif — and tif, tiff, wmf, emf, rle, converted on the fly |
| Adresse web | https://…/logo.png | Image chargée depuis un serveur (https seulement : une adresse http:// est refusée, voir plus bas) |
| 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.
Une adresse http:// est refusée : la page du composant est sécurisée, et le moteur basculerait l'image en https:// sans rien dire — sur un serveur intranet sans TLS, elle échouerait avec un message trompeur. Le composant la refuse donc d'emblée : pictogramme d'erreur et ue_error avec REASON_INSECURE. Pour une image d'un serveur non chiffré, téléchargez-la d'abord avec n_pbt_restclient.of_download dans un dossier temporaire, puis affichez ce chemin. Réaffecter le même chemin relit le fichier : une image que votre application vient de réécrire (photo, scan, recadrage) s'affiche, comme avec le Picture natif. Une image du disque ne dépasse pas 32 Mo.
Les formats du Picture natif que le moteur ne lit pas — TIFF (scans, télécopies), WMF, EMF et RLE — sont convertis à la volée : une application reprise de PowerBuilder garde ses images. Les blancs autour d'un chemin sont ignorés : une colonne CHAR lue par GetItemString arrive complétée d'espaces, et Windows les ignore aussi ; is_source se relit tel que vous l'avez écrit. Une image recolorée (mono:, tint:) servie par un autre site en https n'est dessinée que si ce serveur autorise les requêtes d'une autre origine (en-tête Access-Control-Allow-Origin) ; sinon ue_error le dit (REASON_FAILED). Les fichiers du poste, les ressources de DLL et les data: ne sont pas concernés.
Une image en mémoire — une photo stockée en base et lue par SelectBlob — s'affiche par of_set_picture(blob), comme SetPicture du Picture natif : ni fichier temporaire, ni base64. Le format est reconnu aux octets ; ue_loaded ou ue_error suivent, comme pour is_source.
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. Le placement se lit à l'écran : ALIGN_START reste sur le bord de début quels que soient ii_rotation et ib_mirror. Une valeur inconnue se relit center.
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 |
ROTATION_NONE · ROTATION_90 · ROTATION_180 · ROTATION_270 | 0 90 180 270 | ii_rotation |
REASON_NOT_FOUND · REASON_TOO_LARGE · REASON_INSECURE · REASON_UNSUPPORTED · REASON_FAILED | "notfound" "toolarge" "insecure" "unsupported" "failed" | ue_error (as_reason) |
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 |
is_valign | string | "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 |
ib_enabled | boolean | true | À false, l'image est affichée en niveaux de gris et ne répond plus à rien : clics, molette, clavier et dépôts de fichiers |
ii_badge | integer | 0 | Pastille de compteur dans l'angle supérieur de fin de ligne : à droite en lecture de gauche à droite, à gauche en lecture de droite à gauche (0 = aucune). Au-delà de 99, elle affiche 99+ ; un lecteur d'écran l'entend avec l'image (« Messagerie, 5 nouveautés ») |
il_badge_color | long | -1 | Fond de la pastille, en RGB PowerBuilder (-1 = non posée : la couleur qui vient du thème ; 0 est le noir, comme pour toute autre couleur). 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 à l'écran : l'image est retournée de gauche à droite, quelle que soit ii_rotation |
ib_zoomable | boolean | false | Opt-in : l'utilisateur peut se rapprocher (molette, vers le pointeur, ou touches + et -), se déplacer (glisser, ou flèches — inversées en lecture de droite à gauche) et revenir au cadrage (double-clic, ou la touche marquée 0, quelle que soit la disposition du clavier) ; la touche 1 montre l'image à sa taille RÉELLE, un pixel de l'image pour un pixel de l'écran. Avec Ctrl ou Alt enfoncé, ces touches sont laissées à votre application. Plus grande que son cadre, l'image le couvre toujours : un glisser ne découvre jamais de bande vide ; plus petite, elle reste où is_align et is_valign la placent. Seul le bouton gauche la déplace. 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 = le cadrage choisi par is_stretch, jusqu'à id_max_zoom (8.0 par défaut). La relire donne le facteur courant, molette et clavier compris (ue_zoom_changed vous prévient de chaque changement : un geste de l'utilisateur, cette propriété posée par votre code, ou une nouvelle source qui le ramène à 1.0). Nécessite ib_zoomable, posé avant : sans lui le facteur reste 1.0. Posez-la après is_source : une nouvelle image repart du cadrage |
id_max_zoom | double | 8.0 | Le PLAFOND du zoom, dans l'unité d'id_zoom (1.0 = le cadrage) : la molette, la touche + et id_zoom s'y arrêtent, quelle que soit la taille de l'image. Toute valeur à partir de 1.0 ; en dessous, le défaut revient. Seule la touche 1 va au-delà, jusqu'à la taille RÉELLE — un grand scan affiché petit reste lisible pixel pour pixel ; de là, + ne fait rien et - redescend. Abaissé sous le zoom courant, le zoom y redescend et ue_zoom_changed le dit |
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. Une image désactivée (ib_enabled = false) refuse tout dépôt, et ib_allow_drop se relit tel que posé |
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_alt_text | string | "" | Texte de remplacement : ce qu'un lecteur d'écran dit de l'image, suivi du nombre de la pastille, ou de « Image indisponible » quand la source a échoué. Laissez-le vide pour une image purement décorative |
ib_clickable | boolean | false | Opt-in : l'image est un BOUTON — dans l'ordre de tabulation, avec un anneau de focus visible, et Entrée ou Espace lèvent ue_clicked comme un clic (le bouton par défaut de la fenêtre ne répond pas alors). Désactivée, elle quitte l'ordre de tabulation. Un lecteur d'écran annonce un bouton nommé par is_alt_text. Sans elle, une image est une image : Entrée part à la fenêtre |
is_theme_style | string | "" | Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement |
is_theme_mode | string | "" | Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement |
il_theme_accent | long | -1 | Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui 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. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé |
of_set_picture (blob ablb_image) | Affiche une image tenue en mémoire — une photo lue en base par SelectBlob —, comme SetPicture du Picture natif : ni fichier temporaire, ni base64. Le format est reconnu aux octets (tif, wmf et emf convertis) ; is_source relit ensuite l'adresse où l'image est servie, et ue_loaded ou ue_error suivent. Renvoie 0 une fois l'image remise, -5 si le blob est vide ou n'est pas une image, -4 au-delà de 32 Mo, -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énement | Déclenché quand |
|---|---|
ue_clicked ( ) | Clic gauche sur l'image — ou Entrée / Espace avec ib_clickable. Déplacer l'image zoomée n'est pas un clic, et un double-clic n'en lève qu'un, comme le Picture natif |
ue_loaded (long al_width, long al_height) | L'image est chargée ; les paramètres portent ses dimensions d'origine en pixels. Pour un SVG, ce sont les dimensions qu'il déclare (width, height) ; un SVG dessiné à 100 % n'en déclare aucune, et le moteur lui donne une boîte par défaut (150 pixels de haut, aux proportions de son dessin) : le rapport est juste, la taille ne veut rien dire |
ue_error (string as_message, string as_reason) | L'image n'a pas pu être chargée. as_message nomme la source (image load failed : <source>), as_reason dit pourquoi : REASON_NOT_FOUND (fichier absent), REASON_TOO_LARGE (plus de 32 Mo), REASON_INSECURE (adresse http://, refusée), REASON_UNSUPPORTED (format que le composant n'affiche pas), REASON_FAILED (tout le reste : fichier qui ne se décode pas, serveur qui ne répond pas) |
ue_rclicked ( ) | Clic droit sur l'image |
ue_double_clicked ( ) | Double-clic sur l'image. Un seul ue_clicked le précède, jamais deux — comme le Picture natif. 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é : molette, double-clic, touches +, -, 0 et 1, id_zoom ou un id_max_zoom plus bas posés par votre code, une nouvelle is_source ou ib_zoomable coupé (retour à 1.0) — rien quand le facteur ne bouge pas, ni sur of_reset. 1.0 signifie le retour au cadrage de is_stretch |
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 rowfocuschanged de dw_customer : afficher la photo du client courant
// Local variables
string ls_customer_code
// Le code du client de la nouvelle ligne
if currentrow < 1 then return
ls_customer_code = this.GetItemString(currentrow, "customer_code")
// La photo remplit son cadre ; les espaces d'une colonne CHAR sont ignores
uo_photo.is_source = "photos\" + ls_customer_code + ".jpg"
uo_photo.is_stretch = uo_photo.STRETCH_UNIFORMTOFILL
// Une fois, dans l'event open de la fenetre : l'image montree quand une photo manque
uo_photo.is_error_source = "img\photo_missing.svg"
// event ue_error de uo_photo : (string as_message, string as_reason)
// L'image de remplacement est deja affichee : ici, seulement compter les photos manquantes
if as_reason = uo_photo.REASON_NOT_FOUND then
il_missing_photos = il_missing_photos + 1
end if
is_error_source est la bonne façon de gérer une photo manquante : inutile de tester l'existence du fichier avant de l'affecter. Ne réaffectez jamais is_source depuis ue_error : si l'image de remplacement manquait à son tour, l'échec relancerait le chargement sans fin.
Afficher une photo stockée en base #
// Local variables
blob lb_photo
// La photo de l'employe, stockee dans une colonne de la base
SELECTBLOB photo INTO :lb_photo FROM employee WHERE emp_id = 4152 USING SQLCA;
// Affichee directement depuis la memoire : 0 = remise, -5 = pas une image
if uo_photo.of_set_picture(/*image*/ lb_photo) <> 0 then
uo_photo.is_source = ""
end if
Une image cliquable, façon bouton #
// L'image, son nom pour le clavier et les lecteurs d'ecran, et son infobulle
uo_avatar.is_source = "photos\user.png"
uo_avatar.is_alt_text = "Mon compte"
uo_avatar.is_tooltip = "Mon compte"
// Un bouton pour le clavier aussi : Tab l'atteint, Entree ou Espace levent ue_clicked
uo_avatar.ib_clickable = true
// event ue_clicked de uo_avatar
of_open_my_account()
Compteur et grisage #
// Local variables
long ll_unread
// Une pastille de notifications sur une icone de messagerie
ll_unread = 7
uo_mail.is_source = "img\packimages.dll:SVG/MAIL"
uo_mail.ii_badge = ll_unread // 0 fait disparaitre la pastille
// Pastille rouge au-dela d'un seuil, couleur du theme sinon (-1)
if ll_unread > 20 then
uo_mail.il_badge_color = RGB(/*red*/ 200, /*green*/ 30, /*blue*/ 30)
else
uo_mail.il_badge_color = -1
end if
// Fonction indisponible : l'image passe en niveaux de gris, sans autre image a fournir
uo_mail.ib_enabled = ib_mail_allowed
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 #
// Local variables
string ls_chosen_file, ls_name
// Show the file the user has chosen
if GetFileOpenName("Picture", ls_chosen_file, ls_name, "jpg", "Pictures (*.jpg;*.png),*.jpg;*.png", /*initdir*/ "", OFN_EXPLORER + OFN_NOCHANGEDIR) = 1 then
uo_preview.is_source = ls_chosen_file
end if
// event ue_loaded de uo_preview : (long al_width, long al_height)
uo_status.of_panel(/*key*/ "main").is_text = String(al_width) + " x " + String(al_height) + " px"
// Une image plus petite que le cadre : ne pas l'agrandir inutilement. La taille de l'image
// est en PIXELS, celle du userobject en unites PowerBuilder : les comparer dans la meme unite
if al_width < UnitsToPixels(uo_preview.width, XUnitsToPixels!) and al_height < UnitsToPixels(uo_preview.height, YUnitsToPixels!) then
uo_preview.is_stretch = uo_preview.STRETCH_NONE
end if
Une bannière pleine largeur #
// L'image de la banniere, qui remplit sa bande
uo_banner.is_source = "img\banniere.jpg"
uo_banner.is_stretch = uo_banner.STRETCH_UNIFORMTOFILL // remplit toute la bande, sans deformer
uo_banner.is_valign = uo_banner.VALIGN_TOP // garde le haut de l'image visible
Bonnes pratiques #
STRETCH_UNIFORMest le mode sûr : il ne déforme jamais. RéservezSTRETCH_FILLaux fonds décoratifs où la déformation est sans conséquence.- Pour une photo dans un cadre fixe (trombinoscope, vignette),
STRETCH_UNIFORMTOFILLdonne 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/NOMlè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). - Donnez un
is_error_sourceà toute image dont la source dépend des données, et réservezue_errorà votre journal : n'y réaffectez jamaisis_source. - Posez
id_zoomaprèsis_source: une nouvelle image repart du cadrage. - 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.
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.
| Membres | Rôle | Détaillé dans |
|---|---|---|
of_reset | Remettre le composant à zéro | 3.6 Remettre un composant à zéro : of_reset() |
of_register_shortcut · of_clear_shortcuts | Raccourcis clavier du composant | 3.5 Les raccourcis clavier |
of_is_created · of_is_ready · of_get_last_error | S'il est né, s'il est prêt, ce qui a échoué | 3.7 Diagnostic |
of_save_as_png · of_save_as_jpg | Exporter le rendu en image | 3.8 Exporter le rendu en image |
of_set_redraw | Grouper les modifications en un seul repaint | 3.10 Bonnes pratiques |
of_preload_icons | Icônes affichées sans délai | Affichage instantané : of_icon |
of_set_translation | Traduire un libellé du composant | 5.2 Adapter un libellé : of_set_translation |
of_focus_webview | Donner le focus au composant | 6.4 Clavier et focus |
of_print · of_print_to_pdf | Imprimer, ou écrire un PDF | 6.9 Imprimer |
of_set_property · of_get_property · of_component_name | Piloter une propriété par son nom | 3.1 Le moteur de propriétés |
is_accessible_name · is_accessible_description | Le nom et la description que dit un lecteur d'écran | 3.4 Propriétés et events optionnels |
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.