PBToolboxAI v4 ← Site

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 #

Userobjectu_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-inib_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 :

FormeExempleUsage
Fichier localimg\logo.pngpng, jpg, jfif, bmp, gif, ico, svg, webp, avif
Adresse webhttps://…/logo.pngImage chargée depuis un serveur (https seulement : une adresse http:// est refusée, voir plus bas)
Données incorporéesdata:image/png;base64,…Image déjà en mémoire, sans fichier intermédiaire
Ressource de DLLimg\packimages.dll:SAMPLEImage 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.


Comment elle est cadrée : is_stretch #

ConstanteEffet
STRETCH_UNIFORMDéfaut. L'image est mise à l'échelle sans déformation, entièrement visible ; des marges peuvent apparaître
STRETCH_UNIFORMTOFILLMise à l'échelle sans déformation, mais le cadre est entièrement rempli ; les débordements sont rognés
STRETCH_FILLL'image est étirée pour occuper exactement le cadre — elle peut être déformée
STRETCH_NONETaille 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 #

ConstanteValeurPour
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_2700 90 180 270ii_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éTypeDéfautRôle
is_sourcestring""L'image à afficher (voir les quatre formes ci-dessus)
is_stretchstring"uniform"Mode de cadrage : STRETCH_NONE, STRETCH_FILL, STRETCH_UNIFORM, STRETCH_UNIFORMTOFILL
is_alignstring"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_valignstringVALIGN_CENTERPlacement 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_enabledbooleantrueÀ 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_badgeinteger0Pastille 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)
il_badge_colorlong-1Fond 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_sizeinteger0Hauteur 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_mousebooleanfalseOpt-in : active ue_mouse_enter / ue_mouse_leave
is_placeholderstring""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_sourcestring""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_rotationinteger0Quarts 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_mirrorbooleanfalseMiroir horizontal à l'écran : l'image est retournée de gauche à droite, quelle que soit ii_rotation
ib_zoomablebooleanfalseOpt-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 0) ; la touche 1 montre l'image à sa taille RÉELLE, un pixel de l'image pour un pixel de l'écran. 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_zoomdouble1.0Facteur 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, ou cette propriété posée par votre code). Nécessite ib_zoomable, posé avant : sans lui le facteur reste 1.0
id_max_zoomdouble8.0Le PLAFOND du zoom, dans l'unité d'id_zoom (1.0 = le cadrage) : la molette, les touches et id_zoom s'y arrêtent. Toute valeur à partir de 1.0 ; en dessous, le défaut revient. La taille RÉELLE reste toujours atteignable — la touche 1 y mène, et un grand scan affiché petit reste lisible pixel pour pixel. Abaissé sous le zoom courant, le zoom y redescend et ue_zoom_changed le dit
ib_allow_dropbooleanfalseOpt-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_heightbooleanfalseOpt-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_textstring""Texte de remplacement : ce qu'un lecteur d'écran dit de l'image. Laissez-le vide pour une image purement décorative
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)
is_tooltipstring""Info-bulle simple affichée au survol du composant
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie

Méthodes #

MéthodeRô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_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énementDéclenché quand
ue_clicked ( )Clic gauche sur l'image. 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
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 +, - et 0, ou id_zoom posé par votre code — rien quand le facteur ne bouge pas. 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 ue_row_changed du datawindow : afficher la photo du client courant
uo_photo.is_source  = "photos\" + ls_customer_code + ".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, string as_reason)
if as_reason = uo_photo.REASON_NOT_FOUND then
    uo_photo.is_source = "img\photo_missing.svg"     // image de remplacement
end if

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 #

// L'image, et l'infobulle montree quand la souris s'y pose
uo_avatar.is_source    = "photos\user.png"
uo_avatar.is_tooltip   = "Mon compte"
// event ue_clicked de uo_avatar
of_open_my_account()

Compteur et grisage #

// Une pastille de notifications sur une icone de messagerie
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 #

// Show the file the user has chosen
uo_preview.is_source = ls_chosen_file
// 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
if al_width < uo_preview.width and al_height < uo_preview.height 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 #

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.

MembresRôleDétaillé dans
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.1 Le moteur de propriétés

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.


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