Skip to content

checkbox, clicktab, string, integer, space: domains, frames, input - #1854

Merged
Kalamatee merged 13 commits into
aros-development-team:masterfrom
terminills:reaction-4-fields
Oct 28, 2026
Merged

Kalamatee merged 13 commits into
aros-development-team:masterfrom
terminills:reaction-4-fields

Conversation

@terminills

Copy link
Copy Markdown
Contributor

Depends on #1851, #1852 and #1853 (their commits are included; review the last four).

  • checkbox.gadget: GM_DOMAIN, underlined shortcut, tick in a raised box
  • clicktab.gadget: hit only on the tab row, so the gadgets of a CLICKTAB_PageGroup page can be clicked
  • string.gadget, integer.gadget: field frame and natural size (GM_DOMAIN); the text area is inset inside the frame for STRGCLASS's render and input
  • space.gadget: GM_DOMAIN from SPACE_MinWidth/MinHeight, SPACE_AreaBox

Built for pc-x86_64 and pc-i386; QEMU (x86_64): typing into the ClassAct page example's string fields and the ReqTools mockup's integer fields shows the text; the tabs switch pages.

@Kalamatee

Copy link
Copy Markdown
Member

String and integer need a different mechanism.

  • Both classes temporarily rewrite the live struct Gadget around every superclass call. The program's task can read the shrunken box meanwhile, and a re-layout landing between the inset and the undo leaves the gadget permanently offset. Store the outer frame box in instance data and keep a fixed inset box in the gadget, set from OM_SET.
  • About 100 lines of that field code are pasted identically into both classes. Share them next to the new box helper.

The LBAddNode(), LBEditNode() and LBRemNode() helpers of the link
library send these methods, but the class did not implement them, so
the calls fell through to rootclass and returned 0.

LBM_ADDNODE allocates a node with one entry per column of the
gadget's ColumnInfo and inserts it after lba_Node: NULL puts it at the
head, ~0 at the tail. LBM_REMNODE removes and frees the node and
LBM_EDITNODE applies the attributes to it. After each the gadget
recounts the list, finds the selected node's new index (or clears the
selection when it was removed), keeps the scroll position in range and
redraws when it has a GadgetInfo.

Checked on x86_64 with a listbrowser in a window: three LBAddNode()
calls (two at the tail, one at the head), LBEditNode() reading back
the new text, LBRemNode() of the head keeping the selection on the same
node at its new index, LBRemNode() of the selected node clearing it.
The node pointers survive only
with DoGadgetMethodA() returning the full IPTR.
The varargs forms of ChooserLabels(), ClickTabs(), RadioButtons() and
BrowserNodes() collected their strings in a 64-entry array and silently
stopped at 63 labels. They now add each string to the list as they read
it, with no limit, as on AmigaOS.

The varargs stubs of the class functions duplicate the proto macros;
their file now says they are for programs built with NO_INLINE_STDARG.

Checked on x86_64: ChooserLabels() with 70 strings returns 70 labels.
CHILD_Label was stored and never placed or drawn. In a vertical group the
labels now share a column left of the children, right-aligned against
them and centred on each child's height; in a horizontal group each label
sits in front of its own child. Both count in the group's minimum size,
and a label is drawn disabled when its gadget is.
Without WA_Width/WA_Height the window opened at 400x300 and the layout
spread its children over the extra room; ReAction opens it at the
layout's minimum, which is what the programs are written for.
A gadget placed by the program with GA_RelRight/RelBottom/RelWidth/
RelHeight drew nothing: every class read LeftEdge/TopEdge/Width/Height
as absolute values. reaction_box.h resolves them against the gadget's
domain the way intuition does (gadgets.c GetGadgetLeft and friends), and
the render methods of button, checkbox, chooser, clicktab, fuelgauge,
getfile, getfont, getscreenmode, listbrowser, palette, slider, space,
speedbar and textfield use it.

QEMU: ClassAct's ListBrowserExample (relative width and height) shows its
three titled columns and rows; the window was empty.
The group fills its own area before drawing the frame, and bevel.image
fills a selected bevel with FILLPEN: a group recessed with
LAYOUT_BevelState IDS_SELECTED came out solid blue. The frame now only
draws its edges.
The window was opened with a fixed set of tags: the program's WA_IDCMP
(MOUSEBUTTONS, INTUITICKS...) never reached it, and every window got a
close, depth, size and drag gadget whatever was asked. The WA_ tags
listed by the window_cl autodoc are now kept and passed on after the
class's own, WA_IDCMP is added to the flags the class needs (and to an
open window with ModifyIDCMP), and the default gadgets are only added
when the program names none of them.
A group erased its whole box on GM_RENDER. When Intuition refreshes the
window it draws each group before the gadgets in it, so that was
harmless there, but a group rendered on its own wiped its gadget
children. The erase now fills the group's box minus the boxes of its
gadget children (a region of what is left); the children keep what
they drew. Image children and labels are still drawn by the group.

The erase, the bevel and the layout of the children use the group's
box with relative geometry resolved (reaction_box.h), not the raw
LeftEdge/TopEdge/Width/Height.

Checked on x86_64 with ClassAct's LayoutExample, LabelExample,
ListBrowserExample, ClickTabExample and IntegerExample: the windows
are pixel-identical to the previous version, which drew every gadget
child again after the erase, also after growing and shrinking the
LayoutExample window.
WA_Width/WA_Height were stored like WA_InnerWidth/WA_InnerHeight and
always opened as the inner size, so a window given an outer size came
out larger by its borders. The class now remembers which was given and
opens with the same tag. Only an inner size is fitted to the layout's
minimum before opening.

WA_MinWidth/WA_MinHeight were set to the layout's minimum, which is an
inner size, while Intuition takes them as outer sizes: the window could
be shrunk by its borders below the layout and the gadgets spilled over
the frame. The limits are now set after opening, from the real borders.
A window opened with an outer size below that is grown to it, and as
WindowLimits() refuses a minimum above the current size, it is set
again on the IDCMP_NEWSIZE of that change.

Checked on x86_64 with a layout of three buttons (inner minimum
147x67, borders 20x46): no size opens at 167x113, WA_Width 400 x
WA_Height 250 at 400x250 (was 420x296), WA_Width 60 x WA_Height 40 is
grown to 167x113, WA_InnerWidth 400 x WA_InnerHeight 250 at 420x296;
the minimum is 167x113 in every case (was 147x67). Shrinking
ClassAct's LayoutExample stops at its layout instead of cutting it off.
Without GM_DOMAIN the layout gave a checkbox the 40-pixel fallback and cut
its label short. It now reports the box, a gap and the label width, and
one text line of height.

An underscore in the label marks the shortcut: the next character is
drawn underlined and the underscore itself is not drawn (it was printed).

The box is a raised bevel with a tick in the text pen when checked, as on
AmigaOS; it was a recessed box with an X in the fill pen.

QEMU: ClassAct's ReqTools preferences layout shows all six labels in full
with their shortcuts underlined.
With CLICKTAB_PageGroup the gadget's box covers the page as well, and
without a GM_HITTEST of its own gadgetclass claimed every click in it:
no gadget on the page could be activated. The page's gadgets follow the
clicktab in the window's list, so returning no hit below the tab row
lets intuition find them.
Both classes rendered only STRGCLASS's text area: no frame, and no
GM_DOMAIN, so the layout gave them no room and the fields vanished.

They now draw a BVS_FIELD bevel around the text and report a domain of
their minimum visible characters plus the frame. STRGCLASS edits, draws
and places the cursor in the gadget box, so the gadget box is the text
area: when GA_Left/Top/Width/Height (or their Rel forms) are set, the
frame box is kept in the instance data and the gadget box is set inset
from it, and OM_GET of those attributes returns the frame box. The
frame is drawn on GREDRAW_REDRAW, before the superclass draws the text,
since the bevel fills its inside. The frame code is shared by both
classes in reaction_field.h, next to reaction_box.h.

Checked on x86_64 with ClassAct's IntegerExample: the fields are framed
and sized by the layout; clicking into one, typing, Return and the
second field look the same as with the box narrowed around each
superclass call, which this replaces.
The class kept SPACE_MinWidth/MinHeight but never reported them, so a
layout gave the gadget a few pixels. GM_DOMAIN now returns the minimum
size plus the bevel, and SPACE_AreaBox (get) returns the box inside the
bevel, where programs draw.
@terminills

Copy link
Copy Markdown
Contributor Author

Reworked and force-pushed, on top of the updated #1853.

  • The gadget box is now fixed at the text area. The outer frame box is kept in instance data, taken from what the superclass applied for GA_Left/Top/Width/Height (and the Rel variants) in OM_NEW and OM_SET. OM_GET returns the frame box for those attributes.
  • Nothing rewrites the live struct Gadget around superclass calls any more, so the GM_GOACTIVE/GM_HANDLEINPUT overrides are gone.
  • The shared code is in workbench/classes/reaction/reaction_field.h, next to reaction_box.h, and both classes use it.

Tested with the ClassAct IntegerExample in QEMU (clicking into a field, typing, Return, then the second field): pixel-identical to the previous version. The string gadget uses the same header, but I only compile-tested it, as none of the examples has a string field.

@Kalamatee
Kalamatee merged commit f98ae8b into aros-development-team:master Oct 28, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants