Not sure what you're after , but FWIW :
I use one central function for handling my GUIs : "#.capture".
It stores all GUI fields "that I require" into a central table ( called #.Capture ) such as to make searching, sorting, reading GUIs , writing GUIs & validating during callbacks extremely simple.
It maintains a second ( less important ) global called : #.CaptureOR
... which stores the complete GUI Quad-OR object if I reuqire it later.
The function "#.capture" uses the first element of the RH-Arg to point to a multitude of sub-functionality within the function.
I'd have thought this was the obvious way to handle GUIs, and might , from what I've understood, suggest a basis for solving your problem.
Here's an example of what #.Capture might look like :
...
ArbitraryTag Field-name Attribute Value Default
--------------------------------------------------------------------------
∆PDF F1.SF1.AHELL Caption
∆PDF F1.SF1.AHELL State
∆LANGUAGE F1.SF1.TC.B1 Caption
∆LANGUAGE F1.SF1.TC.B2 Caption
∆LANGUAGE F1.SF1.TC.B3 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B4 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B4 Tip
∆LANGUAGE F1.SF1.TC.F1.TC.B1 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B1 Tip
∆LANGUAGE F1.SF1.TC.F1.TC.B2 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B2 Tip
∆LANGUAGE F1.SF1.TC.F1.TC.B3 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B3 Tip
∆DATA F1.SF1.TC.F1.TC.F4.ED1 Text
∆DATA F1.SF1.TC.F1.TC.F1.ED1 Text
∆DATA F1.SF1.TC.F1.TC.F2.ED1 Text
Here's an example of using the function in the GUI-Create stage :
(∆∆3 #.capture FORM,'.ED2')⎕WC'Edit' ''('Posn'...
⍝
Basically , the #.capture function is easily expanded to handle all new functionalities that one needs.
Typically, a result is always returned, and the simple case of writing / reading ...
GUI --> #.Capture
#.Capture --> GUI
.. for single fields, whole groups of fields, or over the all GUIs that are currently "open" is a simple operation.
The "ArbitraryTag" is just a way of grouping items for convenience.
e.g. Using the "∆LANGUAGE" Tag enables me to change the User-Language in real-time with one function call, and changes all GUIs that are currently "open".
Here's a sample of some Callback code :
:Else
:If ∧/' '=OBJ ⎕WG'Caption' ⍝ then add default
Choice←,''makeInputBOX 1 '' 'Name'
:If 0≠⍴Choice
OBJ ⎕WS'Caption'Choice
DATA←capture 0 '∆DATA'
DATA←duplicate∆DATA∆files DATA ⍝ duplicate files
∆∆PAGEDEFS[CNR]←⊂Choice
DATA DB∆PAGEDEF CNR ⍝ update
:EndIf
:Else ⍝ activate default
DATA←DB∆PAGEDEF CNR
X←capture 1 DATA
Here's a few lines of the "in function" documentation for #.capture :
( view full screen width , to see all whole lines )
...
⍝⍝ : READ-from WRITE-to RETURN
⍝⍝ -------------- -------------- ------------------------
⍝⍝ monadic, eg: R←capture 0 'INIBASE' '∆NEW1' '∆NEW2' ... : GUI Capture → field-names,ATTs,values from GUI
⍝⍝ monadic, eg: R←capture 0 : Capture-DATA defaults → Capture
⍝⍝ monadic, eg: R←capture 1 (1 SYSREAD 1) : DATA by name GUI + Capture → field-names,ATTs,values from GUI
⍝⍝ R←capture 1 'INIBASE' : Capture by Name GUI → field-names,ATTs,values from GUI
⍝⍝ R←capture ¯1 'INIBASE' '∆DATA' ... : Capture defaults GUI → ⍳0
Bottom line :
By having all the GUI fields needed in one central table, one would just add a few more "code subsections" to the #.capture function to include various cross-field validations that one requires, as the application develops ( that would be used within the Callbacks).