Graphics User Interface
Immediate Mode User Interface
After several versions of building a gui for :r4 I found the one type of GUI called IMGUI, this fits perfectly with the concept of forth. The idea here is to draw the interface while the interaction is calculated, that is, there is no way to save but the behavior is being executed while drawing.
The implentatios is simple, every gui element have an id, in the case of button, if the mouse enter in this element, the id is store and if the mouse unclick this id, the vector of execution is called.
The zones are managed with the gc library: xc,yc and w,h shared by sprites and others.
The basic things are in lib/gui.txt and in lib/btn.txt there are diferent buttons.
A simple usageof tbnt
, the stack usage is 'vector "string"
.
^r4/lib/btn.txt
#value
:main
show clrscr
$ffffff ink
value "value:%d" print cr cr
$ff0000 ink
'exit dup >esc< "Exit" btnt cr cr
cr
$ff ink
0 ( 10 <? )( sp
[ dup 'value ! ; ] over "hit %d" mprint btnt cr cr
1+ ) drop
cminiflecha ;
: main ;
See the power of IMGUI, we can define a dynamic quantity of button, the dynamic label can be made with mprint
, a memory version of print
, leave in stack a memory adress with the formated string, and the dup
in the vector of button use the top of stack of loop for set the var value
.
Basic Words
Every gui object has an autogenerated id (you dont see this when use it), there are two class of basic words:
The first class of words generates an id and therefore they differ from other elements:
::guibtn | 'click --
::guiMove | 'move --
::guiDnMove | 'dn 'move --
::guiDnMoveA | 'dn 'move --
::guiMap | 'dn 'move 'up --
::guiDraw | 'move 'up --
::guiEmpty | --
guiBtn
: Execute the vector if you click on the element, that is, lift the button inside the element.
guiMove
: Execute the vector if you move the mouse inside the elemento when press button.
guiDnMove
: Execute dn when you press and execute move when you move.
guiDnMoveA
: Execute dn when press and execute move when you move but if you exit from this element work too.
guiMap
: Execute dn when press, move when move and up when release.
guiDraw
: Execute Move when move and up when release.
guiEmpty
: Don’t execute, this is because you can overlap regions ans in some cases you need clean the behavior for any place.
The Second class of words are tester for in or out the region:
::guiI | 'vector --
::guiO | 'vector --
::guiIO | 'vi 'vo --
This not generate a new element.
Whit this words you can make any type of button, drawin zones, color chooses, etc.
Text Input
Some words of input in lib/input.txt
::input | 'var max --
::inputcr | 'var max --
::inputexec | 'vector 'var max --
::inputint | 'var max --
::inputreal | 'var max dec --
::inputm | 'var max h w --
Here you need a buffer for storte the string 'var
and the max or chars
Example:
^r4/lib/input.txt
#name )( 64
#adress )( 64
#memo )( 256
#int )( 16
#real )( 16
:main
show clrscr
$ff00 ink
"form test " print cr cr
"name: " print 'name 64 input cr
"adress: " print 'adress 64 input cr
"integer: " print 'int 200 inputint cr
$ff0000 ink
'exit "Exit" sp .btnt
cminiflecha
'exit >esc< ;
: main ;
See how you need memory for store every input pad!, .btnt
has focus control, then with tab and enter you can exit of this screen