1. Re: Menu Bar
- Posted by David Cuny <dcuny at DSS.CA.GOV> May 14, 1998
- 586 views
Luis Campos wrote: >How is it supposed to work with a menu bar? It's pretty much the same thing as buttons. When you draw the menu bar, = keep track of where the text is. You only need to keep track of the x = position, because you know that the menu bar is always in row 1. = Whenever you get a mouse click, check to see if it's in row 1. If it is, = see if a menu text has been hit. If it has, open a menu. A user will typically want to interact with your controls using both a = mouse AND keys. Having to bounce between mouse and key events in the = code is a pain, so in EE I ended up creating some "fake" keystrokes for = mouse keys. From KEYS.E: =20 -- mouse states global integer MOUSE_COL, -- mouse x position at time of event MOUSE_ROW, -- mouse y position at time of event MOUSE_BUTTON_STATE -- button held or not global constant MOUSE_CLICK =3D 801, MOUSE_UP =3D 802, MOUSE_DRAG =3D 803, MOUSE_DOUBLE =3D 804, MOUSE_HELD =3D 805 This unified mouse and keystroke events, and let me treat the get key = routine similar to a Win32 event buffer. Another "cheat" I did was define 0 as a sort of "dead" key. So my main = loop logic would look something like this: -- get a key or a mouse event key =3D watch_keys() -- see if the menu wants the key key =3D run_menu() -- see if any controls on the screen want the key key =3D control_handler() if key > 1000 -- menu item selected... or key =3D ALT_F then -- ...or menu shortcut key? if key =3D 1101 then -- run code for menu 1, item 1 elsif key =3D 1102 =20 or key =3D ALT_F then -- run code for menu 1, item 2 elsif key =3D 1201 then =20 -- run code for menu 2, item 1 end if OK, here's an explanation of the code: 1. First of all, I got an event from my key handler. It returned both = keystrokes and mouse events. It also has a special trap for control-C = characters, so they are returned without Euphoria breaking. 2. Next, the keystroke is handed to the menu routine. If the keystroke = didn't involve the menu, it would ignore it, and return the original = value. If the key activated the menu, the menu routine would run (see MENU.E = for details). If the user ended up selecting a menu item, the selection = was returned as a value > 1000 (more on that later). If the user ended = up cancelling the menu, a 0 would be returned (dead key). 3. Next, the key is handed to the control handler, to see if and buttons = or controls get the event. EE doesn't actually do this, since all the = controls are limited to dialogs - but if you were allowing the user to = place controls on the screen, this is where you would put the test. 4. Finally, the key is tested to see if a menu selection was made. If = the user selected a menu item in the run_menu() routine, it would be = returned as follows: 1000 + (100*menu number) + item number So 1203 =3D 1000 + (100*2) + 3 =3D menu 2, item 1. Notice the test: elsif key =3D 1102 -- menu 1, item 2 or key =3D ALT_F then -- also has a shortcut In this case, the user is allowed to press ALT_F as a shortcut to = activating the menu's behavior. That's about all there is to it conceptually. In practice, there are a = lot of details to making a menu work. Again, refer to MENU.E in EE for = details. If you want, you can use the menu routine in EE _without_ the dialogs. = You just need to call the routines: key =3D watch_keys() to get keys and mouse events, draw_menu_bar( sequence menu ) to display the menu bar initially, and: give_menu( sequence menu, integer key ) to feed the menu keystrokes. That's all there is to it! In the WinMan demo, you can see that the logic is similar to the text = version - rows 1-20 are hard-coded as belonging to the menu bar. In = later versions, the menu bar will be implemented as a "real" control, so = I can place it inside a window (Win95 style), on the main screen (Mac = style), or as a popup menu (OpenStep style). Hope this helps! -- David Cuny