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_auto_width, ib_follow_end, ib_track_mouse, ib_track_cycle, ib_allow_drop, ib_selectable, ib_hover_effect, ib_ellipsis_tooltip, ib_marquee_overflow_only, ib_marquee_pause_on_hover, ib_mnemonic, ib_veto_links |
Quick start #
// window open event
uo_text.is_text = "Welcome to [b][accent]PBToolboxAI[/accent][/b][br]" &
+ "See the [hyperlink=https://pbtoolboxai.net]documentation[/hyperlink]."
uo_text.is_align = uo_text.ALIGN_CENTER
uo_text.is_valign = uo_text.VALIGN_CENTER
The text accepts rich text markup: this is the component that makes the most of it — its [action=…] areas raise ue_action and are reachable with the keyboard too (the message box makes them clickable as well; a [hyperlink=…] opens everywhere).
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 at the edge. false no longer folds long lines: they overflow, and only the line breaks of the text ([br], a new line) start a new 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, from 6 to 200 like the [size] tag (0 = size from the theme, or the one PBT_SetDefaultFont gave). A value out of that range is brought back to the nearest bound, and read back as applied |
il_text_color | long | -1 | Text color as RGB() (-1 = color from the theme). [color] tags still take precedence over their own span. A PowerBuilder SYSTEM colour (WindowText, ButtonFace…) means the colour of the theme, and reads back -1 |
ii_line_spacing | integer | 0 | Line spacing as a percentage, from 50 to 400 (150 = 1.5 lines; 0 = default). A value out of that range is brought back to the nearest bound, and read back as applied |
ib_enabled | boolean | true | Block enabled or grayed out. Grayed out, links, actions and fold headers are inert and leave the Tab order; on the theme's surface the text takes the theme's grey, on a background of its own (il_back_color, a [bk] run) its colours are kept and attenuated: it stays readable |
ib_selectable | boolean | false | Opt-in: lets the user select the text and copy it with Ctrl+C (off by default, like a label). Releasing the mouse after a selection does not raise ue_clicked |
ii_max_lines | integer | 0 | At most N lines shown (0 = no limit): the last one ends with "…", the text counts as cut for ue_text_overflow and ib_ellipsis_tooltip, and ib_auto_height measures the lines shown. Not applied to a scrolling banner |
ib_mnemonic | boolean | false | Opt-in: the & of the text marks the letter of a shortcut, as on a PowerBuilder StaticText — "&Name:" shows the N underlined, && writes one &. As in PowerBuilder, the shortcut itself belongs to the control the label names (its Accelerator). Off by default: "R&D" stays as written; is_text reads back with its & |
Block look (the "header" look) #
| Property | Type | Default | Purpose |
|---|---|---|---|
il_back_color | long | -1 | Block background as RGB() (-1 = background from the theme). With ii_corner_radius it follows the rounded corners, and outside them the block shows the color of the object it sits on. It stays announced to PowerBuilder when the theme changes. A PowerBuilder SYSTEM colour (ButtonFace…) means the background of the theme, and reads back -1 |
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. The border AND the il_back_color background follow it |
ii_padding | integer | -1 | Inner margin in pixels: -1 = the theme's margin (default), 0 = no margin at all (the text lines up with the edge of a neighbouring field), more = pixels |
ib_hover_effect | boolean | false | Opt-in: slight darkening on hover (lightening on a dark theme), 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 (0 = default speed, 60) |
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: they stay physical, whatever the reading direction. Any other value is taken, and read back, as MARQUEE_START |
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. A disabled text (ib_enabled = false) refuses every drop |
ib_track_mouse | boolean | false | Opt-in: enables ue_mouse_enter / ue_mouse_leave |
ib_track_cycle | boolean | false | Opt-in: enables ue_cycle, raised at the end of each scrolling pass; without it, the text scrolls in silence |
ib_auto_height | boolean | false | Opt-in: the block measures its ideal height and resizes the userobject; see Shared foundation |
ib_auto_width | boolean | false | Opt-in: the userobject takes the WIDTH of its text — the longest line, without wrapping (the [br] breaks count), plus the padding and the border; a new text, a font or a padding resizes it again, and ue_auto_width tells the width settled on. A scrolling banner (ib_marquee) has no natural width and reports none |
ib_follow_end | boolean | false | Opt-in, for a log written with of_append_text: the view stays at the BOTTOM as lines arrive — unless the reader scrolled up to read an older line: he is never pulled away from it |
il_max_log_lines | long | 0 | For a log written with of_append_text: the number of lines kept (0 = all of them). Beyond it the oldest lines go, from the screen AND from is_text; the text set by is_text counts as one line. Lowering it cuts at once |
ii_max_width | integer | 0 | With ib_auto_width: the widest the userobject may grow, in pixels (0 = no limit). A longer text wraps at that width, and ib_auto_height takes over for the height |
ib_veto_links | boolean | false | Opt-in: before a [hyperlink] opens, ue_hyperlink_opening is asked; return FALSE to keep the link shut and handle it yourself (your own browser, a confirmation). Off by default, like every cancelable event of the library: the link opens at once |
is_theme_style | string | "" | Visual style of the component (THEME_STYLE_* constants); empty = the application's, followed at every change |
is_theme_mode | string | "" | Light or dark variant (THEME_MODE_* constants); empty = the application's, followed at every change |
il_theme_accent | long | -1 | Accent colour of this component (-1 = the application accent, or the theme's) |
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. Returns 0 once applied, -2 when the component is not created |
of_set_redraw (boolean) | Groups a burst of changes into a single render. Returns 0 once applied, -2 when the component is not created |
of_save_as_png (string) · of_save_as_jpg (string) | Exports the rendering as an image. Returns 0 once the image is written, -4 when writing fails, -2 when the component is not created |
of_refresh_parent_color ( ) | A block with a background (il_back_color) and rounded corners (ii_corner_radius) paints what lies OUTSIDE its corners with the colour of the object it sits on, so the corners look cut out. That colour is read when those two properties are set: if the window or the tab page behind the block changes its BackColor afterwards, the four corners keep the old colour — square patches around the block. Call this method then (or after moving the block to another parent) and the corners blend in again. Returns 0 once sent, -2 when the component is not created |
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. Returns 0 once sent, -2 when the component is not created |
of_append_text (string as_markup) | Adds ONE line at the end of the text, for a log: only that line travels to the component and only that line is drawn — rewriting is_text at every line sent and drew the whole log again. as_markup takes the same markup as is_text; a line starts with no tag open, and an empty one keeps the height of a line. Read back, is_text holds every line, joined by [br], each one closing the tags it left open. With ib_follow_end the view stays at the bottom, with il_max_log_lines the oldest lines go; a screen reader announces each new line. Returns 0 once sent, -2 when the component is not created |
of_clear ( ) | Empties the text, every line of a log included, and keeps every other setting (of_reset puts them all back to their defaults). Returns 0 once sent, -2 when the component is not created |
Events #
| Event | Raised when |
|---|---|
ue_clicked ( ) | Left click on the block — not raised on an [action] or [hyperlink] area (no duplicates), on the header of a [foldarea] (folding raises nothing), nor after a text selection |
ue_hyperlink (string as_url, boolean ab_opened) | 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. ab_opened says whether it really opened: FALSE for a scheme other than http, https or mailto (is_last_error says why), or when ue_hyperlink_opening kept it shut |
ue_hyperlink_opening (string as_url) → boolean | Cancelable, asked before a [hyperlink=url] zone opens, only when ib_veto_links = true. Return FALSE to keep the link shut and handle it yourself: ue_hyperlink then arrives with ab_opened = FALSE. By default: TRUE |
ue_action (string as_key) | An [action=id] area has been clicked: it is up to you to hook your code in. The area is reachable with the keyboard too: Tab to it, then Enter or Space |
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_auto_width (long al_width) | The block has taken a new width, in PowerBuilder units — requires ib_auto_width = 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 (an animation INSIDE the text never counts as a pass) — requires ib_track_cycle = true |
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.
// Freeze the drawing while everything is set
uo_header.of_set_redraw(/*on*/ false)
// The title, centred
uo_header.is_text = "[b]Sales dashboard"
uo_header.is_align = uo_header.ALIGN_CENTER
// Solid background and readable white text
uo_header.il_back_color = RGB(/*red*/ 60, /*green*/ 110, /*blue*/ 190)
uo_header.il_text_color = RGB(/*red*/ 255, /*green*/ 255, /*blue*/ 255)
uo_header.ii_padding = 14
// The block hugs its content : it reads like a title bar
uo_header.ib_auto_height = true
// Everything is drawn at once
uo_header.of_set_redraw(/*on*/ true)
// ue_auto_height event of uo_header
of_reposition_below_header(al_height) // moves the content below the header
Rich text with a link and an action #
// A link to a web page, and an action your application handles (ue_action)
uo_text.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_text : (string as_key)
choose case as_key
case "renew" ; of_open_renewal()
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 #
// Two foldable sections : the second one starts folded
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]"
// The block shrinks when a section is folded
uo_recap.ib_auto_height = true
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 #
// The message of the banner
uo_banner.is_text = "[b]Notice[/b] -- the service will be closed on Friday the 12th."
// Scrolling mode, news-ticker style
uo_banner.ib_marquee = true
uo_banner.ii_marquee_speed = 90 // pixels per second
uo_banner.is_marquee_direction = uo_banner.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.
Once ib_track_cycle = true is set, the ue_cycle event is raised on every full pass of the text — 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_banner.is_text = is_messages[ii_message]
A file drop zone #
// Accept files dragged from Windows Explorer
uo_zone.ib_allow_drop = true
// What the zone shows, centred
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[])
// Local variables
integer li
// The drop is over : the zone looks normal again
uo_zone.ii_border_width = 0
// Each dropped file, one after the other
for li = 1 to UpperBound(as_files)
of_import(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
// ue_drag_leave event of uo_zone : the drag went away, the zone looks normal again
uo_zone.ii_border_width = 0
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 #
// A text that behaves like a link button
uo_link.is_text = "Select all"
uo_link.il_text_color = RGB(/*red*/ 21, /*green*/ 101, /*blue*/ 192)
uo_link.ii_padding = 8
uo_link.ii_corner_radius = 6
uo_link.ib_hover_effect = true // reacts to hover like a button
// ue_clicked event of uo_link
of_select_all()
A log written line by line #
Each call sends only the line added; ib_follow_end keeps the last one in view as long as the reader does not scroll up, and il_max_log_lines keeps only the newest ones.
// Local variables
long ll_row
// Once, when the window opens : the view follows the end, the 500 newest lines are kept
uo_log.ib_follow_end = true
uo_log.il_max_log_lines = 500
uo_log.is_text = "[b]Import[/b]"
// For every row imported : one line, sent alone
for ll_row = 1 to 2000
uo_log.of_append_text(/*markup*/ "Row " + String(ll_row) + " [color=#2e7d32]imported[/color]")
next
A label as wide as its text #
// A status chip : background, rounded corners, and the width of its text
uo_status.is_text = "[b]Status :[/b] connected"
uo_status.il_back_color = RGB(/*red*/ 232, /*green*/ 245, /*blue*/ 233)
uo_status.ii_corner_radius = 12
uo_status.ib_auto_width = true
A field label written the PowerBuilder way #
A label taken over from a PowerBuilder StaticText keeps its &: with ib_mnemonic, the letter is underlined and && writes one &. As in PowerBuilder, the shortcut itself is the Accelerator of the field the label names.
// The & marks the shortcut letter : "Customer name:" with the C underlined
uo_label.ib_mnemonic = true
uo_label.is_text = "&Customer name:"
Deciding whether a link opens #
With ib_veto_links, ue_hyperlink_opening is asked before a [hyperlink] opens: returning FALSE keeps it shut — open it your own way, or ask for a confirmation — and ue_hyperlink then arrives with ab_opened = FALSE.
// Ask before a link opens
uo_text.ib_veto_links = true
uo_text.is_text = "See the [hyperlink=https://pbtoolboxai.net/doc/]documentation[/hyperlink]."
// ue_hyperlink_opening event of uo_text : (string as_url) returns boolean
// Only the pages of the company site open, every other link stays shut
return Left(as_url, 24) = "https://pbtoolboxai.net/"
Best practices #
- Text without markup costs nothing extra: feel free to replace your PowerBuilder
statictextcontrols systematically, even for plain text. - Prefer
is_align = uo.ALIGN_STARTover"left": your screen will still be correct if the application switches to right-to-left writing. ib_selectablestays 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_mouseon if you really scriptue_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. - A screen taken over from PowerBuilder whose labels carry an
&("&Name:"): turnib_mnemonicon, the letter is underlined as in the original. - A PowerBuilder SYSTEM colour (
ButtonFace,WindowText…) given toil_back_colororil_text_colormeans the colour of the theme and reads back-1: a themed component does not take the Windows grey.
Inherited from the common base #
These members exist on every visual component — they are not specific to this one. They are detailed once, in the transverse chapters; this table only says where to read them.
| Members | Role | Detailed in |
|---|---|---|
of_reset | Put the component back to zero | 3.6 Resetting a component: of_reset() |
of_register_shortcut · of_clear_shortcuts | The component's keyboard chords | 3.5 Keyboard shortcuts |
ib_created · ib_ready · is_last_error | Whether it was born, whether it is ready, what failed | 3.7 Diagnostics |
of_save_as_png · of_save_as_jpg | Export the rendering as an image | 3.8 Exporting the rendering as an image |
of_set_redraw | Group changes into a single repaint | 3.10 Best practices |
of_preload_icons | Icons shown with no delay | Instant display: of_icon |
of_set_translation | Translate one of the component's labels | 5.2 Adapting a label: of_set_translation |
of_focus_webview | Give the component the focus | 6.4 Keyboard and focus |
of_print · of_print_to_pdf | Print, or write a PDF | 6.9 Printing |
of_set_property · of_get_property · is_component_name | Driving a property by its name | 3.1 The property engine |
is_accessible_name · is_accessible_description | The name and description a screen reader says | 3.4 Optional properties and events |
Two helpers are not inherited: of_icon and of_escape_markup live on n_pbt_utils. Declare one — n_pbt_utils lnv_utils, nothing to create — and call them on it.