# 2. Getting started #

← Installation · Contents · Shared foundation →

Goal: get a first component on screen in five minutes, then understand the pattern that is identical for every component.

## 2.1 Opening the demo application #

The demo application (`pbtoolboxai_demo`) and the `pbtoolboxai.pbl` library ship in PowerBuilder 10 format — the oldest format every supported version can still read.

1. Open the `pbtoolboxai_demo.pbw` workspace in your version of PowerBuilder.
2. PowerBuilder offers to migrate the libraries: accept. The migration converts `pbtoolboxai_demo.pbl` and `pbtoolboxai.pbl` to your version's format.
3. Run a Full Build on the target, then run it: the showcase opens on the component tiles.

That migration is what gives you a `pbtoolboxai.pbl` in your PowerBuilder's format: it is that migrated file you then add to the library list of your own applications.

> ⚠️ Migration is one-way: a library migrated to PowerBuilder 2025 can no longer be opened in PowerBuilder 10. Migrate a copy of the delivered folder and keep the original.

## 2.2 Dropping the component #

1. Open a window (new or existing).
2. Insert → Control → User Object → pick `u_pbt_statictext` from `pbtoolboxai.pbl`.
3. Name it `uo_texte` and size it.

In the painter, the control shows a gray frame reading "PBToolboxAI component (rendered at runtime)": the actual rendering only happens at run time.

> 💡 To handle the component's events, it is better to create an inherited userobject (`u_pbt_statictext` → `uo_mon_texte`) and script the events there. You can also script them directly on the control dropped in the window.

## 2.3 Driving it #

In the window `open` event:

    // Content (the text accepts rich markup: [b], [color=...], [br]...)
    uo_texte.is_text = "Welcome to [b]PBToolboxAI[/b]!"

    // Formatting: everything is a PROPERTY, not a setter
    uo_texte.is_align    = uo_texte.ALIGN_CENTER
    uo_texte.is_valign   = uo_texte.VALIGN_CENTER
    uo_texte.ii_font_size = 14
    uo_texte.il_text_color = RGB(0, 103, 192)

That is all: the component renders itself, themes itself, and reacts to interaction.

### Constants rather than strings #

Every property with predefined values exposes constants on the component. The IDE auto-completes them and they save you from typos:

    uo_texte.is_align = uo_texte.ALIGN_CENTER      // instead of "center"
    uo_texte.is_theme_style = uo_texte.THEME_STYLE_OFFICE2007
    uo_texte.is_theme_mode  = uo_texte.THEME_MODE_DARK

## 2.4 Receiving events #

Components raise typed PB events. Script them on your control (or on your inherited userobject):

    // ue_clicked event of uo_texte
    MessageBox("PBToolboxAI", "Text clicked")

    // ue_hyperlink event of uo_texte -- raised by [hyperlink=...]
    // as_url = the address that was clicked
    Run("explorer.exe " + as_url)

## 2.5 The pattern, identical for every component #

Step | You do | The component does
--- | --- | ---
Creation | Drop the userobject | Creates itself, queues your commands
Configuration | Assign properties / call `of_add_*` | Applies them, even before it is ready
Ready | (nothing) | Raises `ue_ready`
Interaction | (nothing) | Raises typed `ue_*` events
Resizing | (nothing) | Follows the size of the userobject
Reset | `of_reset()` | Returns to a pristine state
Closing | Close the window | Destroys itself cleanly

You never have to deal with HTML, JSON, or the ready / not-ready state.

## 2.6 A complete example #

    // ---- window open event -----------------------------------------------
    // Groups the changes into ONE single repaint (no flicker)
    uo_texte.of_set_redraw(false)

    uo_texte.is_text        = "Revenue: [b][color=#2e7d32]1,240,500 €[/color][/b]" &
                              + "[br][size-=15]Updated " + String(Today(), "dd/mm/yyyy") + "[/size-=15]"
    uo_texte.is_align       = uo_texte.ALIGN_CENTER
    uo_texte.is_valign      = uo_texte.VALIGN_CENTER
    uo_texte.ii_padding     = 12
    uo_texte.ii_corner_radius = 6
    uo_texte.is_tooltip     = "Total since January 1st"

    uo_texte.of_set_redraw(true)

## 2.7 Return codes #

All `of_*` methods return a `long`:

    long ll_rc

    ll_rc = uo_texte.of_reset()
    if ll_rc < 0 then
        // -2 = component not created (runtime missing) ; -5 = invalid argument
        f_log(uo_texte.of_get_last_error())
    end if

In practice the return value is often ignored (configuration errors are rare) and you rely on `ue_ready` / `ue_runtime_missing` instead.

Assigning a property returns nothing (it is a PowerScript assignment): an invalid value is ignored by the component, with no exception raised.

## 2.8 What next #

- Shared foundation: property engine, items, detailed life cycle.
- Themes and appearance: applying a visual identity across the whole application.
- Component reference: one page per v1 component.

← Installation · Contents · Shared foundation →