Skip to main content

 "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.