# statictext — `u_pbt_statictext` #

← Component reference · Guide contents

> Rich text block: markup, alignments, clickable links and actions, header look, scrolling mode (marquee) and file drop zone.

> ▶ See it live — Demo application, Statictext tile: the preview, the code behind it and this page, side by side.

## At a glance #

Userobject | `u_pbt_statictext`
Item class | — (component without items)
Used for | Replacing a PowerBuilder `statictext` with a formatted, clickable text block that can act as a header, a scrolling banner or a drop zone
Opt-in options | `ib_auto_height`, `ib_track_mouse`, `ib_allow_drop`, `ib_selectable`, `ib_hover_effect`

## Quick start #

    // window open event
    uo_texte.is_text = "Welcome to [b][accent]PBToolboxAI[/accent][/b][br]" &
                       + "See the [hyperlink=https://pbtoolboxai.net]documentation[/hyperlink]."
    uo_texte.is_align = uo_texte.ALIGN_CENTER
    uo_texte.is_valign = uo_texte.VALIGN_CENTER

The text accepts rich text markup: this is the component that makes the most of it, since it is the only one that makes `[hyperlink=…]` and `[action=…]` areas genuinely clickable.

## Constants #

Constant | Value | For
--- | --- | ---
`ALIGN_START` · `ALIGN_CENTER` · `ALIGN_END` · `ALIGN_JUSTIFY` | `"start"` `"center"` `"end"` `"justify"` | `is_align`
`VALIGN_TOP` · `VALIGN_CENTER` · `VALIGN_BOTTOM` | `"top"` `"center"` `"bottom"` | `is_valign`

`start` and `end` are logical: they follow the writing direction (Language and RTL). The physical values `left` and `right` are still accepted as aliases.

## Properties #

### Text and formatting #

Property | Type | Default | Purpose
--- | --- | --- | ---
`is_text` | string | `""` | The text displayed, with rich text markup: `[b]`, `[i]`, `[u]`, colors, `[picture=…]`, `[hyperlink=…]`, `[action=…]`
`is_align` | string | `"start"` | Horizontal alignment: `ALIGN_START`, `ALIGN_CENTER`, `ALIGN_END`, `ALIGN_JUSTIFY`
`is_valign` | string | `"top"` | Vertical alignment within the control: `VALIGN_TOP`, `VALIGN_CENTER`, `VALIGN_BOTTOM`
`ib_wrap` | boolean | `true` | Automatic word wrap. `false` forces a single line
`ib_ellipsis` | boolean | `false` | With `ib_wrap = false`, truncates the overflow with an ellipsis instead of cutting it off
`ib_ellipsis_tooltip` | boolean | `false` | Opt-in: when the text does not fit the box, show it in full in a tooltip (markup included). Never replaces a tooltip you set yourself with `is_tooltip` or `is_super_tooltip_*`: yours wins
`is_font_family` | string | `""` | Default font for the block (empty = font from the theme)
`ii_font_size` | integer | `0` | Default size in points (`0` = size from the theme)
`il_text_color` | long | `-1` | Text color as `RGB()` (`-1` = color from the theme). `[color]` tags still take precedence over their own span
`ii_line_spacing` | integer | `0` | Line spacing as a percentage (`150` = 1.5 lines; `0` = default)
`ib_enabled` | boolean | `true` | Block enabled or grayed out (links and actions are inert when it is grayed out)
`ib_selectable` | boolean | `false` | Opt-in: lets the user select and copy the text (off by default, like a label)

### Block look (the "header" look) #

Property | Type | Default | Purpose
--- | --- | --- | ---
`il_back_color` | long | `-1` | Block background as `RGB()` (`-1` = background from the theme)
`il_border_color` | long | `-1` | Border color (`-1` = no border)
`ii_border_width` | integer | `0` | Border thickness in pixels (`0` = no border)
`ii_corner_radius` | integer | `0` | Corner rounding radius, in pixels
`ii_padding` | integer | `0` | Inner padding in pixels (`0` = value from the theme)
`ib_hover_effect` | boolean | `false` | Opt-in: slight darkening on hover, for a label acting as a button

### Scrolling mode (marquee) #

Property | Type | Default | Purpose
--- | --- | --- | ---
`ib_marquee` | boolean | `false` | Turns the block into a horizontally scrolling banner
`ii_marquee_speed` | integer | `60` | Scrolling speed, in pixels per second
`is_marquee_direction` | string | `MARQUEE_START` | Scrolling direction: `MARQUEE_START` (toward the start of the reading direction) or `MARQUEE_END`. The physical aliases `"left"` / `"right"` are accepted
`ib_marquee_overflow_only` | boolean | `false` | Opt-in: scroll only when the text is too wide for the box. A banner scrolling a text that already fits is pure visual noise. Off by default, so `ib_marquee = true` keeps meaning it scrolls
`ib_marquee_pause_on_hover` | boolean | `false` | Opt-in: stop the scrolling while the pointer is over the block, so a long text can actually be read. The loop position is kept: nothing jumps when the pointer leaves

### Optional interactions #

Property | Type | Default | Purpose
--- | --- | --- | ---
`ib_allow_drop` | boolean | `false` | Opt-in: accepts files dropped from Windows Explorer; the full paths arrive through `ue_drop_files`
`ib_track_mouse` | boolean | `false` | Opt-in: enables `ue_mouse_enter` / `ue_mouse_leave`
`ib_auto_height` | boolean | `false` | Opt-in: the block measures its ideal height and resizes the userobject; see Shared foundation
`is_theme_style` | string | `fluent` | Visual style of the component (`THEME_STYLE_*` constants)
`is_theme_mode` | string | `light` | Light or dark variant (`THEME_MODE_*` constants)
`il_theme_accent` | long | `-1` | Accent color of this component (`-1` = the theme accent)
`is_tooltip` | string | `""` | Simple tooltip shown when hovering the component
`is_super_tooltip_title` | string | `""` | Title of the rich tooltip (takes precedence over `is_tooltip`)
`is_super_tooltip_text` | string | `""` | Text of the rich tooltip (rich markup accepted)
`is_super_tooltip_image` | string | `""` | Image of the rich tooltip

## Methods #

Method | Purpose
--- | ---
`of_reset ( )` | Resets every property to its default and clears the text
`of_set_redraw (boolean)` | Groups a burst of changes into a single render
`of_save_as_png (string)` · `of_save_as_jpg (string)` | Exports the rendering as an image
`of_scroll_to_end ( )` | Scrolls to the bottom of the text. For a log, whose newest line sits at the end: without it that line drops below the fold as soon as the text outgrows the visible height

## Events #

Event | Raised when
--- | ---
`ue_clicked ( )` | Left click on the block — not raised on an `[action]` or `[hyperlink]` area (no duplicates)
`ue_hyperlink (string as_url)` | A `[hyperlink=url]` zone was clicked. The browser opens on its own: the event reaches you as well, to log the click or do more with it
`ue_action (string as_id)` | An `[action=id]` area has been clicked: it is up to you to hook your code in
`ue_drop_files (string as_files[])` | Files have been dropped from Windows: full paths, one entry per file. Requires `ib_allow_drop = true`
`ue_drag_enter ( )` | A file drag enters the component (`ib_allow_drop`)
`ue_drag_leave ( )` | The file drag leaves the component
`ue_auto_height (long al_height)` | The block has computed its ideal height — requires `ib_auto_height = true`
`ue_rclicked ( )` | Right click on the block
`ue_double_clicked ( )` | Double click on the block, like the native PowerBuilder `StaticText`. The single clicks that precede it are raised too, in the same order. Not raised on an `[action]` or `[hyperlink]` zone, which have their own channel
`ue_text_overflow (boolean ab_truncated)` | The text stopped fitting the box — or fits again. Raised only on change, never as a flood: a wrapped block counts as cut when it is clipped at the bottom, a single-line one when it is cut on the side. Handle it to widen a column, offer a see more button, or simply switch `ib_ellipsis_tooltip` on
`ue_mouse_enter ( )` | The mouse enters — requires `ib_track_mouse = true`
`ue_mouse_leave ( )` | The mouse leaves — requires `ib_track_mouse = true`
`ue_cycle ( )` | Scrolling mode only: the text has just finished a full pass
`ue_ready ( )` | The component has finished loading; everything sent beforehand has been replayed
`ue_runtime_missing ( )` | The WebView2 runtime is missing: the component stays empty
`ue_bg_color (long al_color)` | The component has computed its theme background color; the userobject has already adopted it (`backcolor`)

## Examples #

### A section header #

Solid background, centered white text and a height fitted to the content: the block reads like a real title bar.

    uo_entete.of_set_redraw(false)

    uo_entete.is_text  = "[b]Sales dashboard"
    uo_entete.is_align = uo_entete.ALIGN_CENTER

    // Solid background and readable white text
    uo_entete.il_back_color = RGB(/*red*/ 60, /*green*/ 110, /*blue*/ 190)
    uo_entete.il_text_color = RGB(/*red*/ 255, /*green*/ 255, /*blue*/ 255)
    uo_entete.ii_padding = 14

    // The block hugs its content : it reads like a title bar
    uo_entete.ib_auto_height = true

    uo_entete.of_set_redraw(true)

    // ue_auto_height event of uo_entete
    of_repositionner_sous_entete(al_height)   // moves the content below the header

### Rich text with a link and an action #

    uo_texte.is_text = "Your license expires on [b]12/31[/b]. " &
                       + "[hyperlink=https://pbtoolboxai.net]Learn more[/hyperlink] " &
                       + "or [action=renew]renew it now[/action]."

    // ue_action event of uo_texte : (string as_id)
    choose case as_id
        case "renew" ; of_ouvrir_renouvellement()
    end choose

`ue_hyperlink` is meant for URLs (the browser opens on its own); `[action=id]` is the right choice when the click has to stay inside your application. The `[invisibleaction=id]` variant raises the same `ue_action` without looking like a link.

### A collapsible block #

    uo_recap.is_text = "[b]Order 2026-0148[/b][br]" &
                       + "[foldarea:[b]Delivery[/b]]Shipped on 12/07, within 48 hours.[/foldarea]" &
                       + "[foldarea-closed:[i]Legal notice[/i]]Returns accepted within 14 days.[/foldarea]"

    uo_recap.ib_auto_height = true   // the block shrinks when a section is folded

A `[foldarea:Title]` adds a clickable header above its content: the reader folds the section with a click, and the marker turns from `−` into `+`. `[foldarea-closed:Title]` produces the same block, folded from the start. Blocks nest, and folding raises no event: it is a reading matter, not a coding one. When `ib_auto_height` is on, the height is reported again on every fold. The title is markup: `[foldarea:[b][accent]Order 2026-0148[/accent][/b]]` makes its own bold and accent-colored.

### A scrolling banner #

    uo_bandeau.is_text = "[b]Notice[/b] -- the service will be closed on Friday the 12th."

    // Scrolling mode, news-ticker style
    uo_bandeau.ib_marquee = true
    uo_bandeau.ii_marquee_speed = 90        // pixels per second
    uo_bandeau.is_marquee_direction = uo_bandeau.MARQUEE_START

The scrolling loops with no dead time. To stop it, set `ib_marquee` back to `false`: the text returns to its normal layout.

On every full pass of the text, the `ue_cycle` event is raised — handy for rotating several messages:

    // In ue_cycle of the banner : move on to the next message
    ii_message = Mod(ii_message, UpperBound(is_messages)) + 1
    uo_bandeau.is_text = is_messages[ii_message]

### A file drop zone #

    // Accept files dragged from Windows Explorer
    uo_zone.ib_allow_drop = true

    uo_zone.is_text = "[size=32][accent][b]Drop your files here[/b][/accent][/size][br][br]" &
                      + "Drag one or more files from Windows Explorer."
    uo_zone.is_align  = uo_zone.ALIGN_CENTER
    uo_zone.is_valign = uo_zone.VALIGN_CENTER

    // ue_drop_files event of uo_zone : (string as_files[])
    integer li

    for li = 1 to UpperBound(as_files)
        of_importer(as_files[li])       // as_files[li] = FULL path of the file
    next

    // ue_drag_enter event of uo_zone : highlight the target while hovering
    uo_zone.il_border_color = RGB(/*red*/ 21, /*green*/ 101, /*blue*/ 192)
    uo_zone.ii_border_width = 2

The paths you receive are full paths: you can pass them straight to `FileOpen` or to your own import routine.

### A label that behaves like a button #

    uo_lien.is_text = "Select all"
    uo_lien.il_text_color = RGB(/*red*/ 21, /*green*/ 101, /*blue*/ 192)
    uo_lien.ii_padding = 8
    uo_lien.ii_corner_radius = 6
    uo_lien.ib_hover_effect = true       // reacts to hover like a button

    // ue_clicked event of uo_lien
    of_tout_selectionner()

## Best practices #

- Text without markup costs nothing extra: feel free to replace your PowerBuilder `statictext` controls systematically, even for plain text.
- Prefer `is_align = uo.ALIGN_START` over `"left"`: your screen will still be correct if the application switches to right-to-left writing.
- `ib_selectable` stays off by default, like a label. Turn it on only where copying makes sense (case number, technical error message).
- For a header, combine `il_back_color` + `ii_padding` + `ib_auto_height`: the block sizes itself when the text changes length.
- Only turn `ib_track_mouse` on if you really script `ue_mouse_enter` / `ue_mouse_leave`.
- Call `of_reset()` before reusing a block for different content: otherwise a previous background, border or scrolling mode stays in place.

← Component reference · Guide contents