Title: Pop-Up Menus
1Pop-Up Menus
- Glenn G. ChappellCHAPPELLG_at_member.ams.org
- U. of Alaska Fairbanks
- CS 381 Lecture Notes
- Friday, September 26, 2003
2ReviewReshape Callback 1/2
- The GLUT reshape callback function is called
- When the window is first created, before any
other callback. - Later, whenever the window size/shape changes.
- Not when the window is merely moved.
- Reshape has 2 parameters
- New width of window, in pixels.
- New height of window, in pixels.
- In the reshape function, we handle things related
to the size/shape of the window. - This is relevant to mouse handling (right?).
- If you need information on the window size
somewhere else in your program, save it in the
reshape function.
3ReviewReshape Callback 2/2
- Example reshape function
- void reshape(int w, int h)
-
- // Set up the viewport
- glViewport(0, 0, w, h)
- // Save the window width height in globals
- winw w
- winh h
- // Set up the projection (now we do not need
to do this in init) - glMatrixMode(GL_PROJECTION)
- glLoadIdentity()
- gluOrtho2D(0.0, 1.0, 0.0, 1.0) // left,
right, bottom, top - glMatrixMode(GL_MODELVIEW) // Always go back
to model/view mode
4ReviewMouse-Related Callbacks
- GLUT has two main mouse-handling callbacks.
- The mouse function.
- Called when any mouse button is pressed or
released. - Unless there is a pop-up menu attached to that
button. - 4 parameters
- Which button (GLUT_LEFT_BUTTON,
GLUT_MIDDLE_BUTTON, or GLUT_RIGHT_BUTTON). - Button state (GLUT_UP or GLUT_DOWN).
- Mouse x (in pixels from left)
- Mouse y (in pixels from top)
- The motion function.
- This is called (possibly repeatedly) whenever the
mouse moves while any of the buttons is pressed. - 2 parameters mouse x, y, as in mouse function.
- Mouse is always called before motion is called.
5ReviewConverting Coordinates
- GLUT gives mouse coordinates in pixels from the
upper-left corner of the window. - OpenGL deals with coordinates set by the
projection. - May not be in pixels.
- Based at the lower-left corner of the viewport.
- Youll need to convert between the two.
- Lirp!
- Note Converting between coordinate systems is a
theme that runs all through 3-D CG.
6Mouse-Related CallbacksExample
- Write a program the uses the mouse and motion
callbacks. - Modified bmptext.cpp to make a purple square
appear at the mouse position, and follow the
mouse, when the left button is down. A similar
program is on the web page simplemouse.cpp.
7Menus in GeneralIntroduction
- The next piece in our discussion of GUIs is
menus. - Menus are a common user-interface feature.
- Menus predate GUIs.
- Advantages of Menus (over other GUI concepts)
- Easy for the user Many commands all work alike,
and new ones work the same as the old ones they
already know how to use. No need to memorize
command names (grep), keypresses (ctrl-alt-F4),
etc. - Easy for the programmer, if menuing is included
in the libraries being used. - Pop-up style menus use little or no screen/window
space. - Disadvantages of Menus
- Using a menu takes time and interrupts users
train of thought. - They are too easy overuse can lead to a poorly
designed user interface.
8Menus in GeneralSpecification
- To design a menu, we need to specify
- What entries does the menu have?
- When/where does the menu appear?
- In a dialog box
- In a menu bar
- Pop-up on mouse click
- Submenu of other menu
- How are entries in the menu chosen?
- Mouse actions
- Key combinations
- What happens when a menu entry is selected?
9Using GLUT MenusIntroduction
- GLUT provides simple mouse-controlled pop-up
menus. - GLUT menus are not full-featured, but they
provide a nice introduction. - Here is the window and menu from creature.cpp.
10Using GLUT MenusOverview
- What we can do with menus
- We can create (and destroy) menu data structures.
- We can add entries (and submenus) to a previously
created menu. - We can attach a previously created menu to a
mouse button (and we can also detach it). - We can change the entries of a menu.
- The first three above are illustrated in
creature.cpp. We will look at these in detail
shortly. - Each menu has a callback associated with it the
handler function. This function is called when
the user selects an entry in that menu.
11Using GLUT MenusMenu Creation
- Creating a Menu
- Creating a menu means creating a data structure
in memory nothing is displayed yet. - GLUT manages the data structure.
- When we create a menu, we also register the
handler callback function. - The initialization function (init) is a good
place to create your menus. - To create a menu, call glutCreateMenu.
- This function takes one parameter
- A pointer to the handler callback function for
this menu. - A menu handler function takes one int parameter
and returns void more on this later. - Example glutCreateMenu(handle_menu)
12Using GLUT MenusAdding Entries
- Adding Entries to a Menu
- We can add entries to the end of the current
menu. - What is the current menu? For now, if you have
created one menu, then it is the current menu
(similarly, if you have one window, then it is
the current window). - To add an entry, call glutAddMenuEntry.
- This function takes two parameters
- A char (C-style string) that gives the text of
the entry. - If you are using the C string class, you can
pass a C-style string using the .c_str() member
function. - An int that is passed to the handler function
when the user selects this entry. - Example glutAddMenuEntry("Toggle eye color", 1)
13Using GLUT MenusAttaching
- Attaching a Menu to a Mouse Button
- We can attach the current menu to a mouse button
in the current window. - To attach a menu, call glutAttachMenu.
- This function takes one parameter
- An int indicating which mouse button to attach
to. - Example glutAttachMenu(GLUT_RIGHT_BUTTON)
- Once we attach a menu, the user can use it.
- Whenever they want, the user pops up the menu
with the appropriate mouse action. - We do not draw the menu GLUT does this for us.
- When a menu entry is selected, the handler
function is called, with the proper number as a
parameter. - Since a menu is attached in the current window,
do not attach a menu until you have created a
window.
14Using GLUT Menus Example (creature.cpp) 1/2
- The following is called in function init.
- void make_main_menu()
-
- glutCreateMenu(handle_main_menu)
- glutAddMenuEntry("Toggle eye color", 1)
- glutAddMenuEntry("Toggle mouth motion", 2)
- glutAddMenuEntry("Quit", 3)
- glutAddMenuEntry("------------------------",
999) -
- glutAddMenuEntry("for CS 381, fall 2003",
999) - glutAttachMenu(GLUT_RIGHT_BUTTON)
-
- Value passed to handler callback can be the same
for multiple entries.
15Using GLUT Menus Example (creature.cpp) 2/2
- Here is part of the handler callback function
(declared before make_main_menu!). - // handle_main_menu
- // Menu handling callback function for our menu
- void handle_main_menu(int value)
-
- switch (value)
-
- case 1 // Toggle eye color
- blueeyes !blueeyes
- glutPostRedisplay()
- break
-
- case 3 // Quit
- exit(0)
- break
- case 999 // Other menu items do nothing
- break
-
16More on MenusOverview
- Now, we quickly look at a few more advanced
topics. We will discuss some of these in more
detail later on. - GLUT Menus
- The current menu.
- Submenus.
- Changing menu entries.
- Thoughts on menus in general
- What are submenus for?
- On changing menus.
17More on Menus GLUT The Current Menu
- Some GLUT menuing commands (e.g.,
glutAddMenuEntry, glutAttachMenu) deal with the
current menu. - If you have just one menu, then it is the current
menu. - glutCreateMenu sets the current menu to the menu
created. - In a menu handler, the current menu is the one
handled. - Function glutCreateMenu returns an int
identifying the menu created. If you have
multiple menus, save this value. - int menu_x glutCreateMenu(handle_menu_x)
- You can set the current menu yourself using
glutSetMenu. - There is also a current window. It is dealt
with similarly.
18More on Menus GLUT Submenus
- A submenu is a menu that is an item in another
menu. - To make a submenu (in the main menu)
- Create the submenu (as an ordinary menu, but do
not attach it). - Create the main menu.
- Use glutAddSubMenu to make submenu an item in the
main menu. - int superduper_menu
- glutCreateMenu(handle_superduper_m
enu) -
- int rightmouse_menu
- glutCreateMenu(handle_rightmouse_m
enu) - glutAddSubMenu("Super-Duper Stuff",
superduper_menu) - The submenu does not need to be attached.
19More on MenusGLUT Changing Menu Entries
- To change the text or return value of a menu
entry - Set the the current menu, by passing the proper
ID to glutSetMenu. - If you are in the menu handler, this is
unnecessary. - glutSetMenu(superduper_menu)
- Use glutChangeToMenuEntry to set the new text
return value. This function takes 3 parameters - The entry number (int) count from the top of the
menu, starting at 1. - The new text (char).
- The new return value (int).
- glutChangeToMenuEntry(1, the_entry.c_str(), 1)
- You can also change submenus, using
glutChangeToSubMenu see the GLUT documentation.
20More on MenusWhat are Submenus For?
- There are many bad uses for submenus. Here are
three good ones. - Write a submenu corresponding to a single
variable or option, with its entries being the
possible values (e.g., a color submenu entries
are colors). - Put rarely-used commands that belong together in
a submenu (e.g., program-configuration commands). - Have a submenu corresponding to a list of
objects, with the entries being the objects
(e.g., a recently-opened files submenu).
21More on MenusOn Changing Menus
- Changing a menu item can be a useful way to
indicate state information to the user. - But be sure to differentiate clearly between
current state and what this menu item does. - Bad example a menu item reading Super-Duper
Mode ON. Does this mean that super mode is
currently on, or that selecting this entry turns
super mode on?