1. Re: Menu Bar
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