"Everyone has a photographic memory, but some don't have film."
YOUR SECOND GFA BASIC 3.XX MANUAL
- or -
HOW I LEARNED TO STOP WORRYING AND LOVE GFA-BASIC
PART 23
CHAPTER TWENTY-ONE - EVENTS
by Han Kempen
MENU()
In an accessory you have to check if it has been selected by the
user. This is done with MENU(1). It is not necessary to check
again with MENU(5) (and certainly not with MENU(4) as stated
incorrectly in my Dutch GFA-manual):
DO ! endless accessory-loop
~EVNT_MESAG(0) ! check if there is a message
IF MENU(1)=40 ! yes, this accy was selected
IF MENU(5)=me_id& ! check accessory-number (*)
@main ! do accessory-stuff there
ENDIF ! (*)
ENDIF
LOOP
The accessory-number (0-5: not more than six accessories are
possible) can be checked with MENU(5), but we already know that
this number is correct because the accessory is activated. The
two (*)-lines can be left out.
There is no easy way to test in a program if an accessory has
been selected by the user. MENU(1) looks promising, but the value
40 (select accessory) or 41 (close accessory) is only sent to the
accessory and not to your program! It would have been nice to be
able to determine if an accessory has been closed, because GEM
will clear the accessory-window and will fill the space with the
desktop-pattern. No easy solution for this one, sorry. The best
idea probably is to test frequently if a redraw is necessary,
e.g.:
ON MENU MESSAGE GOSUB message
REPEAT
ON MENU
(...)
UNTIL ready!
(...)
'
PROCEDURE message
SELECT MENU(1)
CASE 20
(...) ! redraw screen
ENDSELECT
RETURN
This method only works if you have opened a window. If you're on
the desktop (not in a window) you could ask GEM to restore the
desktop:
~WIND_SET(14,0,0,0,0)
ON MENU BUTTON
The syntax for ON MENU BUTTON is:
ON MENU BUTTON clicks,button,event GOSUB button_procedure
For both 'button' and 'event' you can use the numbers 0-3. The
variable 'button' determines which mouse-button you're monitoring
(0=none, 1=left, 2=right, 3=both). The variable 'event'
determines which button-presses should be intercepted (resulting
in calling Procedure Button_procedure), so this variable usually
is the same as 'button'. The variable 'clicks' stands for the
maximal number of clicks you want to register. If you choose '2',
the Procedure will be called if the user clicks once or twice:
ON MENU BUTTON 2,1,1 GOSUB proc ! left click or left
double-click
It's not possible to wait for a double-click, unless the progam
is really waiting, and not doing anything else:
SELECT EVNT_BUTTON(2,1,1)
CASE 1
' clicked once
CASE 2
' clicked twice
ENDSELECT
But you can't combine this with an ON MENU loop.
If you use the described method:
ON MENU BUTTON 2,1,1 GOSUB proc
you could use MENU(15) in the called Procedure to check if the
user clicked twice. The same Procedure would be called after a
single click, but you could ignore that. Fasten your seatbelts
now. If you run such a program the first time, a double click is
not registered in MENU(15). If you suspect a bug and run the
program again, MENU(15) works all right. Nasty.
Another GFA-bug (I think) after:
ON MENU BUTTON 1,2,2 GOSUB proc
The Procedure is called immediately, whether the right mouse-
button was pressed or not. Use one dummy-call (to an empty
Procedure) and all is well:
ON MENU BUTTON 0,0,0 GOSUB dummy
ON MENU ! dummy-call
ON MENU BUTTON 1,2,2 GOSUB proc ! works fine now
If you want to switch ON MENU BUTTON temporarily off, let it
call an empty dummy-Procedure (also possible with other ON MENU
commands):
ON MENU BUTTON clicks,button,event GOSUB dummy
ON MENU IBOX
You can define two independent rectangles with ON MENU IBOX
and/or ON MENU OBOX, either:
- one IBOX and one OBOX
- two IBOXes
- two OBOXes
Here is an example how you can use IBOX/OBOX to invert a
rectangle if the mouse happens to enter the rectangle:
BOX x1,y1,x2,y2 ! the rectangle
w=x2-x1+1 ! rectangle-width
h=y2-y1+1 ! rectangle-height
ON MENU IBOX 1,x1,y1,w,h GOSUB invert ! if mouse enters
rectangle
REPEAT
ON MENU ! watch the mouse
UNTIL exit! ! never happens here
'
PROCEDURE invert ! mouse entered
rectangle
GET x1,y1,x2,y2,b$
PUT x1,y1,b$,10 ! invert rectangle
ON MENU OBOX 1,x1,y1,w,h GOSUB normal ! if mouse leaves
rectangle
RETURN
'
PROCEDURE normal ! mouse left
rectangle
GET x1,y1,x2,y2,b$
PUT x1,y1,b$,10 ! restore rectangle
ON MENU IBOX 1,x1,y1,w,h GOSUB invert ! if mouse enters
rectangle
RETURN
ON MENU KEY
If you are using keyboard-alternatives for submenu-options,
you'll need ON MENU KEY:
ON MENU KEY GOSUB key
DO
ON MENU
LOOP
In the Procedure Key you examine the key that has been pressed
by the user and take an appropriate action:
PROCEDURE key
status|=MENU(13)
key&=MENU(14)
asci|=BYTE(key&)
scan|=BYTE{V:key&}
' Examine variables status|, asci| and scan|
(...)
RETURN
The three byte-variables can be used as described in the
paragraph 'KEYGET' in chapter 8. The advantage of the above
method is that the mouse can be monitored at the same time:
REPEAT
REPEAT
ON MENU
MOUSE mx&,my&,mk&
UNTIL mk& OR exit!
IF mk&
' Mouse-button pressed, do something
(...)
ENDIF
UNTIL exit!
You can also use ON MENU to monitor both mouse and keyboard:
ON MENU BUTTON 1,1,1 GOSUB left_click
ON MENU KEY GOSUB key
REPEAT
ON MENU
UNTIL exit!
But if a mouse-Procedure is called (Left_click in this case) you
can't determine the mouse-position with MENU(10) and MENU(11).
You'll have to use MOUSEX and MOUSEY.
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.