From Amiga Coding
Revision as of 10:27, 14 August 2015 by Daedalus (talk | contribs) (Full Event Example)
Jump to: navigation, search

Intuition uses an event system to notify programs of any GUI actions they need to be aware of, such as a gadget being clicked or a menu item being selected. These notifications are passed to programs as a message, which the program then decodes and decides what to do based on the message. Blitz decodes these messages for you and provides some simple commands for figuring out what happened so your program can respond.

Typically, once the interface is set up, the program flow for dealing with events will be something like this:

  • Wait for an event message to arrive
  • Check the event flags
  • Check the individual item that caused the event
  • Carry out the desired action
  • Repeat

Event Flags

Events are identified by special values called IDCMP flags, which are defined by the operating system. Each flag corresponds to a type of event, e.g. menu selected, close gadget clicked, key pressed. All the flags are defined in the Intuition Autodocs, however a window will only report the flags it has been set up to look for. All the common flags are configured for windows in Blitz by default, and the list of flags reported by a window can be modified if required by your program. Many of the Blitz Basic example programs use the actual values of the flags to check for events. The use of constants is advisable however, and will make your code easier to follow later on. The Intuition contents are defined in the amigalibs.res resident file, which can be added to the Resident Files list in the Complier Settings window to include it in your code. Don't forget to add a hash symbol (#) before the constant name from the Autodocs to make it a valid Blitz constant! For example, the C constant IDCMP_MENUPICK becomes #IDCMP_MENUPICK.

Reading Events

Events are entered into a queue automatically by Intuition. Two commands are used to read the first event flag from the queue: Event and WaitEvent. Event checks the queue and returns the flag of the first event waiting. If there are no events waiting (i.e. nothing happened), Event will return 0. WaitEvent works similarly, except program flow will stop until an event does occur.

WaitEvent has the advantage that your program sleeps while it waits and uses no CPU time, and is the preferred method for handling GUI input from the user. The disadvantage is that your program can't do anything else while it waits, so if you need to do something without user interaction (for example animation or enemy movements), use Event instead.

Event flags are long values, so always use a long variable for storing the result of Event or WaitEvent!

Example usage: ev.l = Event If ev

 NPrint "Event flag: ", ev


 NPrint "No event in queue"

End If ev.l = WaitEvent NPrint "Event flag: ", ev

Identifying the Event

Once you see the type of event you want to deal with, you need to decide what to do. For gadgets and menus, you need to identify the individual item that triggered the event since the IDCMP flag just says "a gadget was clicked". This is done differently depending on the type of event.

Gadget Clicked

If the event flag corresponds to a gadget being clicked or released, the GadgetHit function returns the ID code of the gadget affected. For example: gh = GadgetHit Select gh

 Case 0
   NPrint "Cancel gadget clicked!"
 Case 1
   NPrint "Continue gadget clicked!"

End Select

Again, many of the old Blitz examples use "magic numbers" for gadget IDs, but your code will be much more readable if you use constants instead. These should be defined in your code before they're used. Reworking the above example: gh = GadgetHit Select gh

 Case #cancel
   NPrint "Cancel gadget clicked!"
 Case #continue
   NPrint "Continue gadget clicked!"

End Select

Menu Item Selected

If the event flag corresponds to a menu item being selected, the MenuHit, ItemHit and SubHit commands return the ID of the menu, item, and subitem (if relevant) respectively. Since menu positions are defined by their ID number, this means that MenuHit returns 0 for the first menu, 1 for the second and so on. Similarly, ItemHit will return 0 for the first item in the chosen menu, 1 for the second, and the same for SubHit. Constants are still recommended for identifying menu items of course. As well as making your code easier to read, constants will also make it much easier to rearrange the menu items later on without having to search your code to update the values. Example code: Select MenuHit

 Case #menu_project
   Select ItemHit
     Case #menu_about
       Gosub about
     Case #menu_quit
       quit = true
   End Select
 Case #menu_settings
   Select ItemHit
     Case #menu_size
       Select SubHit
         Case #menu_small
           size = 1
         Case #menu_large
           size = 5
       End Select
       Gosub resize
     Case #menu_savesettings
   End Select
 End Select

End Select

Full Event Example

This example code includes the example code above, as well as a couple of other IDCMP flags. It also defines the constants required, but the window/GUI setup code, procedures and subroutines are obviously missing.

Put window and GUI set up code here

ev.l = WaitEvent NPrint "Event flag: ", ev

gh = GadgetHit Select gh

 Case #cancel
   NPrint "Cancel gadget clicked!"
 Case #continue
   NPrint "Continue gadget clicked!"

End Select