PBToolboxAI v5 ← Site

carousel — u_pbt_carousel #

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

carousel fait défiler des éléments dont un seul est devant : le Cover Flow d'iTunes — l'élément courant de face, ses voisins inclinés en perspective qui se recouvrent, un reflet sous eux —, une bande plate où plusieurs éléments se voient entiers, une pile de cartes, ou un bandeau plein cadre qui montre un élément à la fois. Chaque élément est une image, un texte riche ou une carte (image, titre, sous-titre, corps écrit par un modèle, étiquettes, badge). L'utilisateur clique un voisin, balaie avec inertie, tourne la molette, tape les premières lettres d'un titre ou se sert du clavier ; ue_current_changed vous dit qui est devant. Le carrousel se remplit à la main ou depuis un DataStore, et peut avancer seul, avec un bouton PAUSE.

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


En bref #

Userobjectu_pbt_carousel
Classe d'itemsn_pbt_carousel_item (of_item(key))
Sert àFeuilleter des pochettes, des produits, des photos, des fiches, des nouvelles ou des étapes d'accueil
PrincipeUn élément a une clé unique ; un seul est devant à la fois, et il se dessine en image, en texte ou en carte
Options opt-inib_veto_changes, ib_loop, ib_reflection, il_autoplay_ms
Limite en mode démoLes 6 premiers éléments visibles dessinés — voir le mode démo

Démarrage rapide #

// Three album covers : a key, a title, a picture
uo_covers.of_add_item(/*key*/ "c1", /*title*/ "Northern Lights", /*image*/ "img\packimages.dll:SVG/COVERS/COVER-01")
uo_covers.of_add_item(/*key*/ "c2", /*title*/ "Blue Hour", /*image*/ "img\packimages.dll:SVG/COVERS/COVER-02")
uo_covers.of_add_item(/*key*/ "c3", /*title*/ "Evergreen", /*image*/ "img\packimages.dll:SVG/COVERS/COVER-03")

// A reflection under the covers, as on a glossy floor
uo_covers.ib_reflection = true
// event ue_current_changed of uo_covers : (string as_from_key, string as_key)
// The album now in front, in the title of the window ("" : the carousel is empty)
if as_key <> "" then Parent.Title = this.of_item(/*key*/ as_key).is_title

Quatre dispositions, trois faces #

is_style choisit la disposition : STYLE_COVERFLOW (par défaut) met l'élément courant de face et incline ses voisins en perspective, qui se recouvrent, s'étalent sur la largeur disponible et s'assombrissent avec la distance (ii_angle, ii_spacing, ib_shade) ; STYLE_CAROUSEL aligne une bande plate où plusieurs éléments se voient entiers ; STYLE_STACK empile des cartes — le courant devant, les suivants derrière lui, les précédents partis sur le côté ; STYLE_HERO montre un seul élément sur toute la surface, le suivant glissant ou se fondant (is_transition) : le bandeau d'un tableau de bord. Une tuile garde une proportion (is_item_ratio ; vide : 1:1 pour des images, 3:4 pour des cartes, 16:9 pour des textes) et le contenu d'une carte ou d'un texte suit sa taille, entre un plancher lisible et un plafond. ib_reflection pose un reflet sous les éléments, ii_item_width et ii_item_height fixent la taille au pixel près.

Pourquoi des faces plutôt que des composants dans le carrousel ? Chaque composant de la bibliothèque est un contrôle à part entière, avec sa propre page web (un WebView2) : il ne peut pas se loger dans la page d'un autre. Le carrousel dessine donc lui-même ce que montreraient une image, un statictext ou une carte du kanban — ce sont les trois faces d'un même élément, et mille éléments ne coûtent qu'un seul contrôle. is_item_style choisit la face de tous les éléments, is_style d'un élément choisit la sienne (vide : il suit le carrousel). Avec ITEM_AUTO (par défaut), la face se déduit de ce que l'élément porte :

of_item(key).of_face() dit la face retenue. Une image est un fichier du poste, une ressource fichier.dll:nom, un glyphe mono: ou tint: dessiné au thème, ou une adresse https:// ; une adresse http:// est refusée et lève ue_image_failed avec REASON_INSECURE, un fichier absent avec REASON_NOT_FOUND.

// The covers as a pile of cards, the whole picture in each tile
uo_covers.is_style = u_pbt_carousel.STYLE_STACK
uo_covers.is_fit = u_pbt_carousel.FIT_CONTAIN

// This item is a card, whatever it holds
uo_covers.of_item(/*key*/ "c2").is_style = u_pbt_carousel.ITEM_CARD

Une rangée alignée au début #

Sur une bande plate (STYLE_CAROUSEL), is_align = ALIGN_START donne la rangée d'un service vidéo : les éléments partent du bord de début (à droite en lecture de droite à gauche), tous entiers et à plat, et le dernier écran est plein — aucun vide après le dernier élément ; un élément coupé par un bord invite à défiler. L'élément courant n'est plus au milieu : c'est celui que l'utilisateur a choisi, toujours entier à l'écran. Les flèches et Page préc. / Page suiv. avancent d'un écran (les éléments qu'il montre entiers) et l'élément courant devient le premier que l'écran a amené ; les touches fléchées avancent d'un élément et ne font défiler que ce qu'il faut pour le garder entier ; la molette et le glisser défilent et se posent sur un élément entier, l'élément courant ne suivant que s'il allait sortir ; un clic sur un élément entier le rend courant et lève ue_item_clicked. Les flèches vivent dans les marges, ne se montrent que sous le pointeur ou au clavier, et disparaissent à un bout. Les points comptent les écrans (un point est un endroit où la bande peut se poser) ; le compteur compte toujours les éléments. La lecture automatique avance d'un écran et, au bout, le premier écran revient par le côté. Avec ib_loop, la rangée tourne quand elle est assez longue pour faire le tour de l'écran (environ trois éléments de plus qu'il n'en montre). ALIGN_START n'a aucun effet sur les autres dispositions.

// The row of a video service : the covers from the start edge, a screen at a time
uo_covers.is_style = u_pbt_carousel.STYLE_CAROUSEL
uo_covers.is_align = u_pbt_carousel.ALIGN_START

// Small covers : the row holds several screens
uo_covers.ii_item_height = 150

L'élément devant #

L'élément courant est celui qui est devant ; of_current_key() lit sa clé en direct. Un clic sur un voisin l'amène devant ; un clic sur l'élément devant lève ue_item_clicked, un double-clic (ou Entrée) ue_item_opened. Un changement de l'utilisateur — clic, clavier, molette, balayage, point, flèche, lecture automatique — et un changement de votre code (of_select_item, of_next, of_previous) lèvent le même ue_current_changed, comme SelectItem lève l'événement du clic. Avec ib_veto_changes, ue_current_changing est posé avant, aux deux : renvoyer FALSE laisse l'élément devant, et of_select_item rend alors -4. ue_current_changed part aussi quand l'élément devant s'en va (masqué, retiré : le plus proche prend sa place) et quand le premier élément arrive dans un carrousel vide (as_from_key vide). Un ordre de votre code dans ue_current_changing (un autre élément sélectionné) l'emporte : la réponse qui suit ne change plus rien. of_select_row amène devant l'élément d'une ligne et of_current_row lit la ligne de l'élément devant ; avec ib_sync_row, le DataWindow donné à of_from_datastore suit l'élément devant — le maître-détail d'un DataWindow.

Un élément grisé (ib_enabled = false) reste à sa place, mais l'utilisateur ne peut ni l'amener devant ni le cliquer : le clavier, la molette, Page préc. / Page suiv., la barre de défilement et un lancer le sautent ; votre code le sélectionne quand même. Un élément masqué (ib_visible = false) sort du carrousel en gardant sa clé et sa place. Avec ib_loop (trois éléments au moins), le premier suit le dernier. Un double-clic sur un voisin l'amène devant et s'arrête là : ni ue_item_clicked ni ue_item_opened. il_autoplay_ms fait avancer le carrousel seul, tous les tant de millisecondes (500 au moins) : un bouton PAUSE / LECTURE se montre sous lui (ib_autoplay_button) et la pause de l'utilisateur tient jusqu'à LECTURE (of_pause, of_play, ue_autoplay_changed) ; la lecture s'interrompt aussi sous le pointeur, quand le clavier est dans le composant et quand le carrousel est caché. Au bout d'un carrousel qui ne boucle pas, le premier élément revient par le côté. Chaque pas passe par ue_current_changing comme un geste : un élément refusé est sauté, le suivant est demandé. Un lecteur d'écran n'est pas prévenu de chaque pas pendant la lecture.


Cartes et légende écrites par modèle #

Une carte montre son image en haut, son titre (is_title), son sous-titre (is_subtitle), son corps (is_text), ses étiquettes (is_tags, séparées par des virgules, colorées par is_tag_tones : New=success|Sale=danger) et un badge (is_badge). Le corps de toutes les cartes peut s'écrire par un modèle, is_card_template, et la légende sous le carrousel par is_caption_template : du balisage riche où {price} est un champ de l'élément — un des vôtres (of_set_field), une colonne du DataStore d'où il vient, ou un champ intégré (key, title, subtitle, text, image, badge, tags, position, count). {position} et {count} comptent les éléments dessinés, comme le compteur. {sold:dd/mm/yyyy hh:mm} écrit une date ou une date-heure, {price:#,##0.00} un nombre : les formats d'affichage d'une colonne de DataWindow (mm après une heure = les minutes, [shortdate], [longdate], [time], sections positif;négatif;zéro), dans la langue d'affichage — une valeur que le format ne sait pas écrire s'affiche telle quelle. {?x}…{/x} garde un morceau quand le champ dit quelque chose, {!x}…{/x} quand il ne dit rien, {{ }} sont des accolades. Une valeur est affichée telle quelle, jamais lue comme balisage ; {x:raw} la garde comme balisage — réservez-le à vos propres champs : sur une colonne de base de données, il lirait la donnée comme du balisage, zones d'action comprises. {title}, {subtitle}, {text} et {badge} écrits par votre code sont du balisage, comme dans la légende ; lus dans une colonne, du texte.

// A price, a field of our own, then the body of every card
uo_shop.of_set_field(/*key*/ "p1", /*field*/ "price", /*value*/ "$12.90")
uo_shop.is_card_template = "{?price}From [b]{price}[/b]{/price}{!price}Price on request{/price}"

// Under the carousel : the place of the item in front, then its title
uo_shop.is_caption_template = "{position} / {count} - [b]{title}[/b]"

Depuis un DataStore #

of_from_datastore fait un élément de chaque ligne d'un DataStore, d'un DataWindow ou d'un DataWindowChild — l'appel est le même. Sa clé est le RowID de la ligne — il nomme sa ligne tant que le DataStore n'est ni vidé ni relu (Reset, Retrieve et ImportString redonnent les RowID 1, 2, 3), et of_item(key).of_row() la retrouve — ou la valeur de la colonne ROLE_KEY, la clé à donner dès que vous rafraîchissez. Une ligne dont la clé est vide, invalide, déjà vue ou tenue par un élément ajouté à la main n'est pas chargée : l'appel rend 0 et of_get_last_error la nomme — donnez à vos éléments à la main des clés qui ne sont pas des nombres. Une colonne joue un rôle quand elle en porte le nom (key, title, subtitle, text, image, badge, tags, color) ou quand of_map le dit ; la colonne ROLE_COLOR (un RGB() ou #rrggbb) peint la bande d'une carte. of_map et of_reload_row mettent les éléments à jour en place (drapeaux, champs, poignée et place restent). Un second chargement aussi, avec ROLE_KEY : un élément dont la clé revient garde ses drapeaux, ses champs et sa poignée. Sans ROLE_KEY, un second chargement est une nouvelle époque : un RowID qui revient peut nommer un autre enregistrement, chaque élément des lignes est refait (rien n'est hérité, les poignées des anciens sont libérées) et, si la clé devant revient, ue_current_changed le dit avec as_from_key = as_key. Dans tous les cas, les éléments prennent l'ordre des lignes (un of_move_item ne survit pas à un chargement), ceux des lignes parties s'en vont, ceux ajoutés à la main restent, après les lignes ; un élément de ligne retiré par of_remove_item revient avec sa ligne — masquez-le plutôt (ib_visible). Les dates sont lues dans l'ordre régional du poste, les nombres s'écrivent avec un point, les valeurs CHAR sans leur remplissage, au chargement comme après of_reload_row. Ce qu'une colonne donne est du texte, jamais du balisage — un [action=x] venu de la base n'est pas cliquable —, et une image d'une colonne ne va jamais chercher un chemin réseau (\\serveur\partage : ue_image_failed avec REASON_UNC). Quand la colonne ROLE_KEY d'une ligne relue change, l'élément prend la nouvelle clé : la poignée de l'ancienne est libérée. Toutes les colonnes sont des champs des modèles.

// The rows of the albums : columns named title and subtitle play their role
ids_albums.Retrieve()

// The picture is in a column with another name
uo_covers.of_map(/*role*/ u_pbt_carousel.ROLE_IMAGE, /*column*/ "cover_file")

// One item per row, its key the RowID of the row
uo_covers.of_from_datastore(/*ads*/ ids_albums)
// Master-detail : the DataWindow follows the item in front, and the carousel reads its rows
uo_covers.ib_sync_row = true
uo_covers.of_from_datastore(/*adw*/ dw_albums)

// event rowfocuschanged of dw_albums : the item of the row comes in front
uo_covers.of_select_row(/*row*/ currentrow)

Propriétés #

PropriétéTypeDéfautRôle
is_stylestringSTYLE_COVERFLOWLa disposition : STYLE_COVERFLOW (le courant de face, ses voisins inclinés en perspective), STYLE_CAROUSEL (une bande plate, plusieurs éléments entiers), STYLE_STACK (une pile de cartes), STYLE_HERO (un seul élément sur toute la surface, un bandeau). Une autre valeur est refusée : l'ancienne reste, of_get_last_error dit pourquoi
is_item_stylestringITEM_AUTOLa face de chaque élément qui n'en choisit pas une lui-même : ITEM_AUTO (d'après ce qu'il porte, voir plus haut), ITEM_IMAGE, ITEM_TEXT, ITEM_CARD. Une autre valeur est refusée
is_fitstringFIT_COVERComment une image remplit sa tuile : FIT_COVER (la tuile est pleine, l'image rognée) ou FIT_CONTAIN (l'image entière). Une autre valeur est refusée
ib_reflectionbooleanfalseUn reflet sous les éléments, comme sur un sol brillant
ib_loopbooleanfalseAprès le dernier élément vient le premier (et avant le premier, le dernier). Il faut trois éléments au moins
il_autoplay_mslong0Lecture automatique : l'élément suivant vient devant toutes les il_autoplay_ms millisecondes (500 au moins, une valeur plus petite y est ramenée) ; 0 l'arrête. Un bouton PAUSE / LECTURE se montre sous le carrousel (ib_autoplay_button) ; la lecture s'interrompt aussi sous le pointeur, quand le clavier est dans le composant et quand le carrousel est caché. Au bout d'un carrousel qui ne boucle pas, le premier revient par le côté ; un élément que ue_current_changing refuse est sauté
ib_show_captionbooleantrueLa légende de l'élément devant : son titre (et son sous-titre), souligné de l'accent, ou ce qu'écrit is_caption_template ; elle se tient juste sous lui ou sur son pied (is_caption_position)
is_caption_positionstringCAPTION_AUTOOù se tient la légende : CAPTION_BELOW (juste sous l'élément devant, sous son reflet s'il en a un), CAPTION_OVERLAY (sur son pied, en blanc sur un voile sombre), CAPTION_AUTO (sous une image — sur son pied dans un bandeau —, et aucune sous des cartes ou des textes qui écrivent déjà leur titre, sauf si is_caption_template dit quoi écrire). Une autre valeur est refusée
ib_autoplay_buttonbooleantrueUn bouton PAUSE / LECTURE sous le carrousel tant que il_autoplay_ms tourne, et une fine barre qui se remplit jusqu'au prochain élément : qui lit peut arrêter ce qui bouge. La pause de l'utilisateur tient jusqu'à LECTURE ; ue_autoplay_changed le dit. false : pas de bouton
is_indicatorstringINDICATOR_AUTOCe qui montre où l'on est, sous la légende : INDICATOR_AUTO (des points jusqu'à 12 éléments, une barre de défilement au-delà), INDICATOR_DOTS (des points cliquables, jusqu'à 48 éléments : au-delà, la barre), INDICATOR_SCROLLBAR (une barre qu'on clique et qu'on glisse), INDICATOR_COUNTER (3 / 12), INDICATOR_NONE. Une autre valeur est refusée
ib_arrowsbooleantrueLes deux boutons fléchés sur les côtés : celui de gauche va toujours vers la gauche
ii_item_widthinteger0La largeur d'une tuile, en pixels (24 à 4000, une valeur hors bornes y est ramenée) ; 0 : d'après la taille du composant et is_item_ratio. Une largeur posée avec une hauteur 0 : la hauteur suit la proportion. Sans effet sur STYLE_HERO : son élément prend toute la surface
ii_item_heightinteger0La hauteur d'une tuile, en pixels (24 à 4000) ; 0 : d'après la taille du composant, en laissant voir les voisins et la légende. Une hauteur posée avec une largeur 0 : la largeur suit la proportion. Sans effet sur STYLE_HERO
is_item_ratiostring""La proportion d'une tuile, largeur:hauteur : "1:1", "3:4", "16:9"… La tuile la garde quelle que soit la taille du composant. Vide : d'après la face de la plupart des éléments — 1:1 pour des images, 3:4 pour des cartes, 16:9 pour des textes. Une valeur qui n'est pas deux nombres positifs joints par : est refusée. Sans effet sur STYLE_HERO
ii_angleinteger62Le pivotement des pochettes sur les côtés du Cover Flow, en degrés, de 0 (à plat) à 80 ; 62 est celui d'iTunes
ii_spacinginteger100L'écart des pochettes du Cover Flow et des tuiles d'une bande, en pourcentage de ce que le carrousel calcule : 100 étale les pochettes sur la largeur disponible, de 25 à 300 les resserre ou les écarte
ib_shadebooleantrueLes pochettes sur les côtés s'assombrissent avec leur distance, pour que l'élément devant attire l'œil ; les cartes qui attendent derrière une pile aussi
is_transitionstringTRANSITION_SLIDEComment un bandeau (STYLE_HERO) change d'élément : TRANSITION_SLIDE (le suivant glisse du côté) ou TRANSITION_FADE (il apparaît en fondu). Une autre valeur est refusée
is_alignstringALIGN_CENTEROù se tient l'élément courant sur une bande (STYLE_CAROUSEL) : ALIGN_CENTER (au milieu) ou ALIGN_START (la rangée d'un service vidéo, alignée au bord de début, qui avance d'un écran : voir plus haut). Sans effet sur les autres dispositions. Une autre valeur est refusée
is_card_templatestring""Le corps de chaque carte, écrit par un modèle (voir plus haut). Poser un modèle fait de chaque élément ITEM_AUTO une carte. Vide : le texte de l'élément (is_text)
is_caption_templatestring""La légende sous le carrousel, écrite par un modèle (les mêmes champs). Vide : le titre, et le sous-titre dessous
is_tag_tonesstring""Le ton de chaque étiquette, étiquette=ton joints par ` : New=successSale=danger. Tons : TONE_SUCCESS, TONE_WARN, TONE_DANGER, TONE_INFO (l'accent), TONE_NEUTRAL`. Une étiquette absente, ou un ton inconnu, est neutre
is_badge_formatstring""Le format d'affichage des badges qui sont un nombre ou une date — une colonne ROLE_BADGE du DataStore, ou une valeur que votre code écrit : "$#,##0.00", "dd/mm/yyyy", le format d'une colonne de DataWindow, dans la langue d'affichage. Un badge qui n'en est pas un (du balisage, un mot) s'affiche tel quel. Vide : chaque badge tel quel
ib_sync_rowbooleanfalseMaître-détail : le DataWindow (ou DataWindowChild) donné à of_from_datastore suit l'élément devant — ScrollToRow sur sa ligne à chaque changement, geste ou code. Dans l'autre sens, appelez of_select_row depuis son RowFocusChanged. Un DataStore n'a pas de ligne à montrer : rien ne bouge ; un élément ajouté à la main n'a pas de ligne
ib_veto_changesbooleanfalseOpt-in : demander ue_current_changing avant chaque changement de l'élément devant, de l'utilisateur, de la lecture automatique comme de of_select_item. La lecture automatique saute un élément refusé ; le clavier reste sur place — un élément toujours refusé gagne à être grisé. Un ordre de votre code dans ue_current_changing l'emporte : la réponse qui suit ne change rien. Désactivé par défaut, comme tout événement annulable de la bibliothèque
ib_animatedbooleantrueLes éléments glissent jusqu'à leur nouvelle place. Un poste réglé pour réduire les animations saute directement, sauf si l'application insiste (PBT_SetAnimationPolicy)
ii_anim_durationinteger450Durée d'un mouvement, en millisecondes (0 à 5000)
is_anim_easingstringEASING_EASE_OUTLa courbe du mouvement : EASING_LINEAR, EASING_EASE_OUT, EASING_BACK_OUT (dépasse un peu puis revient), EASING_BOUNCE_OUT (rebondit), EASING_ELASTIC_OUT (oscille)
ib_enabledbooleantruefalse grise le carrousel : les éléments restent affichés, plus rien ne répond à l'utilisateur (clic, clavier, molette, balayage, lecture automatique)
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

Sa poignée, par of_item(key). Une lecture demande au carrousel ce qu'il en est maintenant.

PropriétéTypeDéfautRôle
is_titlestring""Titre de l'élément : la légende quand il est devant, et la première ligne d'une carte. Accepte le balisage riche. Vide, l'élément montre sa clé
is_subtitlestring""La seconde ligne, sous le titre d'une carte et de la légende (balisage accepté). Une image avec un sous-titre reste une image : le sous-titre va dans sa légende
is_textstring""Le texte (balisage accepté) : toute la face d'un élément texte, le corps d'une carte tant que is_card_template est vide. Une zone [action=x] lève ue_action_clicked sur l'élément devant
is_imagestring""L'image : un fichier du poste, une ressource fichier.dll:nom, un glyphe mono: / tint: dessiné au thème, une adresse https://. http:// est refusé (ue_image_failed, REASON_INSECURE), un chemin réseau venu d'une colonne de DataStore aussi (REASON_UNC). Un squelette au thème se montre tant que l'image arrive
is_badgestring""Petit badge (balisage accepté) : un prix, un nombre, dans l'accent — en haut à droite d'une carte, sur le coin d'une image. Une image avec un badge reste une image
is_tagsstring""Étiquettes d'une carte, séparées par des virgules : Vinyl, Sale. Chacune est une pastille colorée par is_tag_tones du carrousel
is_stylestring""La face de cet élément (ITEM_* de u_pbt_carousel) ; vide : il suit is_item_style du carrousel. Une autre valeur est refusée : l'ancienne reste, of_get_last_error du carrousel dit pourquoi
ib_visiblebooleantruefalse retire l'élément du carrousel ; il garde sa clé et sa place. S'il était devant, le plus proche prend sa place (ue_current_changed)
ib_enabledbooleantruefalse grise l'élément : l'utilisateur ne peut ni l'amener devant ni le cliquer, le clavier et la molette le sautent. Votre code le sélectionne quand même
of_position ( ) → long——Rend la place de l'élément dans le carrousel maintenant, à partir de 1 (éléments masqués compris) ; 0 quand le carrousel ne le contient pas
of_row ( ) → long——Rend le numéro de ligne d'aujourd'hui, dans les lignes données à of_from_datastore, de la ligne d'où vient l'élément — après un tri, un filtre ou la suppression d'autres lignes, tant que le DataStore n'est ni vidé ni relu ; 0 pour un élément ajouté à la main ou dont la ligne est partie
of_face ( ) → string——La face avec laquelle l'élément est dessiné maintenant : "image", "text" ou "card" (ITEM_IMAGE, ITEM_TEXT, ITEM_CARD) — ce qu'a choisi is_style ou ce qu'ITEM_AUTO a déduit ; vide quand le carrousel ne le contient pas
is_tooltipstring""Info-bulle simple affichée au survol de l'item
is_super_tooltip_titlestring""Titre de l'info-bulle enrichie de l'item (prend le pas sur is_tooltip)
is_super_tooltip_textstring""Texte de l'info-bulle enrichie de l'item (balisage riche accepté)
is_super_tooltip_imagestring""Image de l'info-bulle enrichie de l'item
il_accentlong-1Accent de l'élément : la bande en haut d'une carte (qu'il fait apparaître) et d'un panneau de texte, et le badge, le prennent ; il passe avant la couleur d'une colonne ROLE_COLOR. Les points et la légende gardent l'accent du composant. -1 = celui du composant
il_back_colorlong-1Fond d'une face texte ou carte, en RGB(r,v,b) (-1 = ce que donne le thème). Une face image n'a pas de fond
il_text_colorlong-1Couleur du texte d'une face texte ou carte (-1 = ce que donne le thème)
il_back_color_hoverlong-1Fond d'une face texte ou carte sous le pointeur, en RGB(r,g,b) (-1 = son fond ordinaire). Rien ne bouge au survol : seule la couleur change
il_text_color_hoverlong-1Couleur du texte d'une face texte ou carte sous le pointeur (-1 = sa couleur ordinaire)

Trois lectures de la poignée, en lecture seule : of_position() rend la place de l'élément à partir de 1, of_row() le numéro de sa ligne dans le DataStore (0 pour un élément ajouté à la main), of_face() la face retenue. Un élément se déplace par of_move_item du carrousel.


Méthodes #

MéthodeRôle
of_add_item (string as_key, string as_title)Ajoute un élément à la fin du carrousel, un titre seul (une carte) : son image, son texte, son sous-titre… se posent sur sa poignée. Sa clé est unique dans le carrousel. Le premier élément d'un carrousel vide vient devant (ue_current_changed). Rend 0 une fois ajouté, -5 pour une clé vide, contenant / ou `, commençant par __, ou déjà prise (un élément d'un DataStore compris), -2` quand le composant n'est pas créé
of_add_item (string as_key, string as_title, string as_image)La même chose avec son image. Avec ITEM_AUTO, une image et un titre seuls font un élément image, le titre en légende. Rend 0 une fois ajouté, -5 comme ci-dessus, -2 quand le composant n'est pas créé
of_clear ( )Vide le carrousel : éléments (ceux d'un DataStore compris) et leurs poignées ; le DataStore reste lié pour un nouveau of_from_datastore, les options restent. ue_current_changed suit, avec une clé vide, s'il y avait un élément devant. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_current_key ( )La clé de l'élément devant, qui que ce soit qui l'y ait amené ; vide quand le carrousel est vide. Lu en direct
of_current_row ( )Le numéro de ligne d'aujourd'hui, dans les lignes données à of_from_datastore, de l'élément devant — après un tri, un filtre ou la suppression d'autres lignes. Rend 0 quand le carrousel est vide, quand l'élément devant a été ajouté à la main ou que sa ligne est partie
of_from_datastore (datastore ads)Fait un élément de chaque ligne du DataStore (voir plus haut). Un second chargement met les éléments à jour en place avec ROLE_KEY, les refait sans lui (nouvelle époque : rien n'est hérité) ; ceux des lignes parties s'en vont (poignées libérées), ceux ajoutés à la main restent, après les lignes ; une ligne non chargée est nommée par of_get_last_error. Rend 0 une fois chargé, -5 quand le DataStore n'est pas valide, -2 quand le composant n'est pas créé
of_from_datastore (datawindow adw)La même chose depuis les lignes d'un DataWindow, lues par un DataStore qui les partage (ShareData). Rend 0 une fois chargé, -5 quand le DataWindow n'est pas valide ou refuse de partager ses lignes (of_get_last_error le dit), -2 quand le composant n'est pas créé
of_from_datastore (datawindowchild adwc)La même chose depuis les lignes d'un DataWindowChild (une liste déroulante DataWindow, un état imbriqué). Rend 0 une fois chargé, -5 quand il n'est pas valide, -2 quand le composant n'est pas créé
of_get_field (string as_key, string as_field)Lit un champ d'un élément, en direct : un des vôtres, une colonne de son DataStore ou un champ intégré (title, position, count…). Une chaîne vide quand il n'en a pas
of_get_last_error ( )Pourquoi le dernier appel a échoué : une méthode qui a rendu -5 ou -4, une valeur refusée (is_style, is_item_style, is_indicator, is_fit, is_caption_position, is_transition, is_item_ratio, is_align, is_style d'un élément), un appel fait pendant une attente (rien n'a pu être jugé), les lignes qu'un chargement a laissées de côté. Vidée par chaque méthode qui agit (une lecture la laisse) ; sinon la dernière erreur de la bibliothèque
of_insert_item (string as_key, string as_title, string as_image, long al_position)Ajoute un élément à une place comptée à partir de 1 (au-delà de la dernière : à la fin). L'élément devant reste devant. Rend 0 une fois ajouté, -5 comme of_add_item, -2 quand le composant n'est pas créé
of_is_playing ( )TRUE tant que la lecture automatique joue : il_autoplay_ms est posé et personne n'a appuyé sur PAUSE (un pointeur sur le carrousel la suspend un instant : elle joue toujours). Lu en direct
of_item (string as_key)Rend la poignée d'un élément (créée au premier accès, libérée quand l'élément est retiré)
of_map (string as_role, string as_column)Donne un rôle à une colonne du DataStore quand son nom ne le dit pas (ROLE_KEY, ROLE_TITLE, ROLE_SUBTITLE, ROLE_TEXT, ROLE_IMAGE, ROLE_BADGE, ROLE_TAGS, ROLE_COLOR). Avant ou après of_from_datastore : après, les lignes sont relues en place. Une colonne vide rend le rôle à la colonne qui porte son nom ; un nouveau ROLE_KEY donne de nouvelles clés aux éléments (les poignées des anciennes sont libérées). Rend 0 une fois posé, -5 pour un rôle inconnu ou une colonne que le DataStore n'a pas, -2 quand le composant n'est pas créé
of_move_item (string as_key, long al_position)Déplace un élément à une place comptée à partir de 1 (au-delà de la dernière : la dernière). L'élément devant reste devant. Rend 0 une fois déplacé, -5 pour un élément inconnu, -2 quand le composant n'est pas créé
of_next ( )Amène devant l'élément suivant (les grisés sont sautés ; après le dernier, le premier avec ib_loop), comme la touche fléchée vers lui (Droite, Gauche de droite à gauche), et lève ue_current_changed. Rend 0 une fois fait (au bout aussi : rien ne bouge, rien n'est levé), -4 quand ue_current_changing a refusé, -5 pendant une attente (rien n'a pu être jugé), -2 quand le composant n'est pas créé
of_pause ( )Met en pause la lecture automatique, comme le bouton PAUSE : l'élément devant reste jusqu'à of_play (ou LECTURE). ue_autoplay_changed suit — un ordre du code le lève comme le bouton. Rend 0 une fois en pause (déjà en pause aussi : rien n'est levé), -5 quand il_autoplay_ms vaut 0, -2 quand le composant n'est pas créé
of_play ( )Relance la lecture automatique après une pause — le bouton PAUSE de l'utilisateur ou of_pause. ue_autoplay_changed suit. Rend 0 une fois relancée (si elle joue déjà aussi : rien n'est levé), -5 quand il_autoplay_ms vaut 0 (rien à jouer), -2 quand le composant n'est pas créé
of_previous ( )Amène devant l'élément précédent, comme la touche fléchée vers lui. Rend 0 une fois fait (au début aussi : rien ne bouge, rien n'est levé), -4 quand ue_current_changing a refusé, -5 pendant une attente, -2 quand le composant n'est pas créé
of_reload_row (long al_row)Renvoie au carrousel une ligne du DataStore de of_from_datastore, lue maintenant, après que votre code l'a changée (SetItem, une fenêtre de saisie) ; son élément est mis à jour en place (drapeaux, champs, poignée et place restent). Une ligne que le carrousel ne tient pas encore (InsertRow) arrive après le dernier élément de ligne. Quand la colonne ROLE_KEY de la ligne a changé, l'élément prend la nouvelle clé : la poignée de l'ancienne est libérée et, s'il était devant, ue_current_changed le dit. Rend 0 une fois envoyée, -5 quand rien n'est lié, que la ligne n'existe pas ou que sa clé est vide, invalide ou tenue par un autre élément (of_get_last_error le dit), -2 quand le composant n'est pas créé
of_remove_item (string as_key)Retire un élément et libère sa poignée ; retirer l'élément devant amène le plus proche devant (ue_current_changed). Un élément de ligne d'un DataStore revient avec sa ligne (of_reload_row, un nouveau chargement) : masquez-le (ib_visible) ou supprimez la ligne. Rend 0 une fois retiré, -5 pour un élément inconnu, -2 quand le composant n'est pas créé
of_reset ( )Vide le carrousel, oublie le DataStore et remet chaque propriété à son défaut. Rend 0 une fois appliqué, -2 quand le composant n'est pas créé
of_select_item (string as_key)Amène un élément devant, comme un clic : il glisse jusque-là et ue_current_changed suit. Avec ib_veto_changes, ue_current_changing est posé d'abord. Un élément grisé est sélectionné quand même : le grisé arrête l'utilisateur, pas votre code. Rend 0 une fois fait (ou déjà devant : rien n'est levé), -4 quand ue_current_changing a refusé, -5 pour un élément inconnu ou non dessiné (masqué, au-delà du plafond démo), -2 quand le composant n'est pas créé
of_select_row (long al_row)Amène devant l'élément d'une ligne des lignes données à of_from_datastore — al_row est le numéro de ligne d'aujourd'hui, quoi que dise ROLE_KEY : le maître-détail d'un DataWindow, appelé depuis son RowFocusChanged. Comme of_select_item sur sa clé : ue_current_changed suit, ib_veto_changes demande d'abord. Rend 0 une fois devant (ou déjà devant), -4 quand ue_current_changing a refusé, -5 quand rien n'est lié, que la ligne n'existe pas ou n'a fait aucun élément (laissée de côté par le chargement, retirée, masquée, au-delà du plafond démo), -2 quand le composant n'est pas créé
of_set_field (string as_key, string as_field, string as_value)Donne à un élément un champ à vous, pour les modèles : {price} ; il passe avant une colonne du DataStore du même nom. Un nom de champ : lettres, chiffres et _, sans chiffre en tête. Rend 0 une fois posé, -5 pour un élément inconnu ou un nom qui n'en est pas un, -2 quand le composant n'est pas créé

Événements #

ÉvénementDéclenché quand
ue_current_changed (string as_from_key, string as_key)L'élément devant a changé : un clic sur un voisin, le clavier, la molette, un balayage, un point, une flèche, la lecture automatique, ou votre code (of_select_item, of_next, of_previous). Aussi quand l'élément devant s'en va (masqué, retiré : le plus proche prend sa place) quand le premier élément arrive dans un carrousel vide (as_from_key vide), et quand un nouveau chargement sans ROLE_KEY donne la clé devant à un autre enregistrement (as_from_key = as_key). as_key vide : le carrousel est vide. Avec ib_sync_row, le DataWindow lié montre déjà la ligne
ue_current_changing (string as_from_key, string as_key) → booleanAnnulable, posé avant un changement de l'élément devant, seulement quand ib_veto_changes = true : geste, lecture automatique et of_select_item (donc of_next, of_previous). Renvoyer FALSE laisse l'élément devant, et of_select_item rend alors -4. Par défaut : TRUE
ue_item_clicked (string as_key)L'élément devant a été cliqué (ou Espace pressée). Un clic sur un voisin l'amène devant à la place (ue_current_changed) — et un double-clic sur un voisin ne fait que l'amener, sans cet événement ; une zone [action=x] lève ue_action_clicked à la place ; un élément grisé ne lève rien
ue_item_opened (string as_key)Un double-clic sur l'élément devant, ou Entrée : ouvrez-le. Un double-clic sur un voisin ne fait que l'amener devant
ue_item_rclicked (string as_key, long al_x, long al_y)Un clic droit sur un élément, ou la touche Menu (ou Maj + F10) sur l'élément devant. al_x, al_y sont des pixels d'écran ; pour un menu PowerBuilder, PopMenu(PointerX(), PointerY()) de votre fenêtre
ue_action_clicked (string as_key, string as_action)Une zone [action=x] du texte de l'élément devant a été cliquée : as_action = "x"
ue_autoplay_changed (boolean ab_playing)La lecture automatique a été mise en pause (ab_playing = false) ou relancée (true) : le bouton PAUSE / LECTURE sous le carrousel, ou votre code (of_pause, of_play le lèvent aussi). Un pointeur posé sur le carrousel la suspend sans le lever
ue_image_failed (string as_key, string as_reason)L'image d'un élément n'a pas pu être montrée : as_reason vaut REASON_INSECURE (une adresse http://), REASON_UNC (un chemin réseau venu d'une colonne de DataStore, refusé avant toute requête) ou REASON_NOT_FOUND (fichier introuvable). Dit une fois par élément et par image
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)

Clavier et souris #


Exemples #

Une vitrine de produits #

// A flat strip : several products in full, a counter under it
uo_shop.is_style = u_pbt_carousel.STYLE_CAROUSEL
uo_shop.is_indicator = u_pbt_carousel.INDICATOR_COUNTER

// A product : a picture and a title, then a badge and tags (it becomes a card)
uo_shop.of_add_item(/*key*/ "p1", /*title*/ "Northern Lights", /*image*/ "img\packimages.dll:SVG/COVERS/COVER-01")
uo_shop.of_item(/*key*/ "p1").is_badge = "New"
uo_shop.of_item(/*key*/ "p1").is_tags = "Vinyl, Sale"

// The tone of each tag, and the price in the body of every card
uo_shop.is_tag_tones = "Vinyl=info|Sale=danger"
uo_shop.of_set_field(/*key*/ "p1", /*field*/ "price", /*value*/ "$12.90")
uo_shop.is_card_template = "From [b]{price}[/b]"

Demander avant de changer d'élément #

// Once : ask before the item in front changes
uo_covers.ib_veto_changes = true

// event ue_current_changing of uo_covers : not while the form beside it is not saved
if ib_unsaved then return false
return true

Ouvrir un élément d'un DataStore dans votre fenêtre #

// Local variables
long ll_row

// event ue_item_opened of uo_covers : the row of the item, edited in a RESPONSE window (the code waits for it)
ll_row = uo_covers.of_item(/*key*/ as_key).of_row()
OpenWithParm(w_album_edit, ll_row)

// The row may have changed : the item follows it
uo_covers.of_reload_row(/*row*/ ll_row)

Des nouvelles qui défilent seules #

// A banner : one item on the whole surface
uo_news.is_style = u_pbt_carousel.STYLE_HERO

// Text items : rich text on a themed panel, with an [action] zone
uo_news.of_add_item(/*key*/ "n1", /*title*/ "Release")
uo_news.of_item(/*key*/ "n1").is_text = "[b]Version 5.0[/b] is out. [action=notes]Read the notes[/action]"
uo_news.of_add_item(/*key*/ "n2", /*title*/ "Webinar")
uo_news.of_item(/*key*/ "n2").is_text = "[b]Webinar[/b] on Thursday at 10:00."
uo_news.of_add_item(/*key*/ "n3", /*title*/ "Support")
uo_news.of_item(/*key*/ "n3").is_text = "[b]Support[/b] answers within one day."

// A new one every 5 seconds, faded in, the first again after the last :
// a PAUSE button shows under the banner
uo_news.is_transition = u_pbt_carousel.TRANSITION_FADE
uo_news.il_autoplay_ms = 5000
uo_news.ib_loop = true
// event ue_action_clicked of uo_news : (string as_key, string as_action)
// The zone [action=notes] of the first item opens the release notes
if as_action = "notes" then Open(w_release_notes)

Un grand catalogue #

// The products : one row = one item, its key the product code
ids_products.Retrieve()
uo_shop.of_map(/*role*/ u_pbt_carousel.ROLE_KEY, /*column*/ "code")
uo_shop.of_from_datastore(/*ads*/ ids_products)

// Only the tiles near the one in front are drawn : thousands of rows cost nothing.
// Beyond 12 items a scrollbar replaces the dots ; the user types a name to reach it
uo_shop.of_select_item(/*key*/ "P250")

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_count · of_keys_at · of_hasParcourir ce que le composant contient3.2 Les items
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
is_accessible_name · is_accessible_descriptionLe nom et la description que dit un lecteur d'écran3.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.

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