ReAction GUI Toolkit

ReAction is the BOOPSI-based GUI class system shipped with AmigaOS 3.2 (V47). It was absent from NDK 3.1 — this is one of the genuinely new subsystems. ReAction treats each gadget type as a library you open by file name, builds the UI as a nested tree of BOOPSI objects via macros, and replaces the classic IDCMP message loop with method dispatch on a window object.

The NDK 3.2 Examples/ tree ships ~40 demonstration programs (one per gadget class), and the class headers live in Include_H/gadgets/ (29 gadget classes) plus Include_H/classes/ (window.h, requester.h, arexx.h).

The mental model shift

Classic Intuition (see Intuition Library Reference): you OpenWindow(), then Wait()/GetMsg() on the IDCMP port, switching on msg->Class. Gadgets are created with CreateGadgetA() and freed individually.

ReAction: you build a window object whose children are layout groups whose children are gadgets — all via taglists. Input arrives as a method result from RA_HandleInput(), not as IDCMP messages. DisposeObject() on the window closes it and recursively disposes every child.

All ReAction tags share one base: REACTION_Dummy (TAG_USER + 0x5000000).

Opening the classes

Each class is a library opened by file name, not a shared library name:

WindowBase = OpenLibrary("window.class",        0L);
LayoutBase = OpenLibrary("gadgets/layout.gadget", 0L);
ButtonBase = OpenLibrary("gadgets/button.gadget", 0L);

Note the convention: window.class and gadgets/<name>.gadget. SAS/C or DICE reaction.lib auto-init can open them for you; the examples open them manually to be self-contained. Close with CloseLibrary() at exit.

Building the UI with macros

reaction_macros.h provides macros that expand to NewObject(GetClass(), NULL, ...) with a trailing taglist. The result is a readable, nested description:

Win_Object = WindowObject,
    WA_ScreenTitle, "ReAction",
    WA_Title,       "Demo",
    WA_CloseGadget, TRUE,
    WINDOW_ParentGroup, HGroupObject,
        LAYOUT_SpaceOuter,  TRUE,
        LAYOUT_DeferLayout, TRUE,
        StartMember, ButtonObject,
            GA_Text, "OK",
            GA_ID,   1,
        EndMember,
        StartMember, ButtonObject,
            GA_Text, "Cancel",
            GA_ID,   2,
        EndMember,
    EndGroup,
EndWindow;

Macro expansion (verified in the headers): - WindowObject = NewObject(WINDOW_GetClass(), NULL, ... - HGroupObject = HLayoutObject = NewObject(LAYOUT_GetClass(), NULL, ... (horizontal) - VGroupObject = VLayoutObject = ... LAYOUT_Orientation, LAYOUT_ORIENT_VERT, ... (vertical) - StartMember = LAYOUT_AddChild - EndMember = End

Classic WA_* tags still work on the window object (it wraps a real struct Window); ReAction-specific behavior uses WINDOW_* tags (base WINDOW_Dummy = REACTION_Dummy + 0x25000).

LAYOUT_DeferLayout (TRUE recommended) defers layout recalculation until needed — pass FALSE only when benchmarking raw layout/render speed. The layout gadget (gadgets/layout.gadget) is the container that manages sizing and spacing of its children.

The event loop — RA_HandleInput

ReAction replaces GetMsg()/ReplyMsg() with a method call on the window object:

ULONG signal, result, wait, done = FALSE;
GetAttr(WINDOW_SigMask, Win_Object, &signal);   /* which signal to Wait() on */

while (!done) {
    wait = Wait(signal | SIGBREAKF_CTRL_C);
    if (wait & SIGBREAKF_CTRL_C) { done = TRUE; continue; }

    while ((result = RA_HandleInput(Win_Object, NULL)) != WMHI_LASTMSG) {
        switch (result) {
            case WMHI_CLOSEWINDOW: done = TRUE; break;
            case WMHI_GADGETUP:    /* result's low 16 bits hold GA_ID */ break;
            case WMHI_ICONIFY:     /* hide, not close */ break;
        }
    }
}
DisposeObject(Win_Object);   /* closes window + disposes all children */

Key facts (from reaction_macros.h and classes/window.h): - RA_HandleInput(win, code) expands to DoMethod(win, WM_HANDLEINPUT, code). - WMHI_LASTMSG is 0L — the loop terminator (no more messages this pass). - Result codes are bit fields: WMHI_CLOSEWINDOW = (1<<16), WMHI_GADGETUP = (2<<16), WMHI_ICONIFY = (9<<16). The gadget's GA_ID arrives in the low bits of a WMHI_GADGETUP result.

Contrast with classic Intuition: there is no struct IntuiMessage to allocate/free, no IDCMP port to manage, and the close gadget is WMHI_CLOSEWINDOW rather than IDCMP_CLOSEWINDOW.

Disposal

DisposeObject(Win_Object) closes the window if it is open and disposes every object attached to it. You do not free each gadget individually. Just close the three (or N) class libraries at the end.

Gadget class inventory

The 29 gadget classes in Include_H/gadgets/, each with an example in Examples/:

Container / input Selection Display Requesters
layout, space, page button, checkbox, radiobutton, chooser, clicktab, tabs label¹, string, integer, texteditor, listbrowser, listview, scroller, slider, speedbar, fuelgauge, tapedeck, sketchboard, bitmap², virtual getfile, getfont, getcolor, getscreenmode, palette, gradientslider, colorwheel, datebrowser

¹ label is part of layout. ² bitmap from Examples/Bitmap.

Plus the three classes in Include_H/classes/: window.class (the root), requester.class (modal requesters), and arexx.class (ARexx host port integration — pairs with the ARexx Scripting Language article).

When to use ReAction vs classic GadTools

  • ReAction is the forward path for new GUIs on OS 3.2+: automatic layout (no manual coordinate math), recursive disposal, method-based input, and source-level affinity with OS 4.x (many tag values and the WMHI_* scheme align with OS 4.x).
  • Classic GadTools / Intuition (GadTools Library Reference) remains valid and is what every pre-3.2 program uses. It is the only option on V40 and earlier.

ReAction classes are themselves BOOPSI subclasses, so they coexist with classic gadgets and images; GA_ID, GA_Text, GA_RelVerify, etc. carry over.

See Also


Sources: Hyperion Entertainment / AmigaOS Team, NDK 3.2 Examples/ (Buttons.c et al.) and Include_H/{classes,gadgets,reaction} headers, 2021; "ROM Kernel Reference Manual: The Coveted Addendum" (2021-12-26 edition). Raw: raw/gadtools/reaction-examples.md; raw/architecture/coveted-addendum.md Updated: 2026-08-08