Previous: Building and Using Menus
The behavior of Allegro's GUI can change, even without creating whole
new GUI controls. To accomplish this, Allegro provides a few global
variables and an interesting way of hunting down the mouse. Before we
learn how to extend the system, let's look
at how we can use these things to our advantage.
Using GUI Variables
Allegro provides five global variables that you can use to modify the
behavior of the dialog manager. They don't bring about drastic change,
but they can be useful nonetheless.
int gui_mouse_focus When this is set to TRUE, Allegro gives
the input focus to whatever object has the mouse. For people used to
working with Microsoft Windows, this can be somewhat annoying. Setting
this variable to FALSE changes this behavior: the input focus can then
only be moved with a mouse click or a keypress. Default: TRUE.
int gui_fg_color This changes the default foreground color
for the prepackaged dialogs (the alert
boxes, the graphics mode
chooser, and the file selection
dialog). It also changes the foreground color of any menus you may
have in your program. In a 256-color graphics mode, this number should be
in the range [0..255], so it can pick a color from the palette. In a
highcolor or truecolor mode, it should be in the same format as the return
value from makecol(). Default: 255.
int gui_bg_color This is the same as gui_fg_color above,
except that it controls the background color. Default: 0.
int gui_mg_color All of the prepackaged dialog controls use
this variable as the color for disabled objects (i.e. ones with the
D_DISABLED flag set), so if you don't like gray, you can change it.
Default: 8.
int gui_font_baseline This variable adjusts the location of
the keyboard shortcut underscores in text strings. This most useful if
you are not using the default font, and your font's descenders are
bigger or smaller than those of the default font. A positive number
moves the underscore "up," closer to the text, and a negative number
moves it "down," or away from the text. Default: 0.
In addition to these five variables, the GUI provides a way to
manipulate mouse input prior to its being processed by the system. Let's
look at that.
Accessing the Mouse
Whenever one of the predefined GUI controls needs to know what the
mouse is doing, it doesn't read the mouse_x, mouse_y, or mouse_b
variables like you may think. Instead, it calls some functions that
can be hooked into so that the mouse input can be "preprocessed." These
functions can be overridden (they're just function pointers), so you can
modify the mouse tracking behavior to your heart's content. The functions
are:
int (*gui_mouse_x)()
int (*gui_mouse_y)()
int (*gui_mouse_b)()
The functions that these point to by default just return whatever is in
the mouse_x, mouse_y, and mouse_b variables, respectively. However, if you
want to change this, simply write your own function and direct the pointer
so it points to your function (e.g. gui_mouse_x =
my_mouse_x;).
This can be a very useful thing. Three possibilities are:
- Scaling the mouse position.
- Say you have a bitmap
editor, and it has zoom in/zoom out functionality. Instead of
doing the math on mouse_x and mouse_y to determine which pixel the
mouse is operating on when the image is zoomed in, override
gui_mouse_x() and gui_mouse_y() to automatically do the math for
you, regardless of how far the image is zoomed in or out. This
only works if your editor is based on GUI functions, of
course.
- Redirecting mouse input.
- Creating self-running demos
could be made easier if you create an array of mouse coordinates
and use the positions in that array (probably in conjunction with a
timer interrupt) to return the mouse position. As far as the GUI is
concerned, the mouse position is wherever you say it is, and not
where the user has put it. The problem with this is that the actual
mouse pointer is drawn wherever the user has put it, not where the
user-supplied hooks say. This could be fixed by calling
position_mouse(your_x, your_y) at each point.
- Changing the way buttons are read.
- If the user's
mouse only has two buttons, you could simulate a three-button mouse
by supplying your own gui_mouse_b() function that sets bit 2 of the
return value and clears bits 0 and 1 if both mouse buttons are held
down. The GUI will be "fooled" into thinking that the middle button
is pressed. Of course, this makes it hard to actually tell when
both buttons are pressed, if you want to handle that as
well...
One further note: any special GUI objects you as a programmer create
should almost always use the gui_mouse_* functions for reading mouse
state. That way, preprocessing the mouse input like this will work for
your own objects as well as the predefined ones.
This doesn't exactly fit here, but in case you're wondering how to get
the GUI to use a font besides the default one, simply set the global
"font" pointer to point to something else: the GUI uses whatever font that
pointer points to. This can quickly add a little zing to your application,
with minimal effort, but be warned: the
graphics mode and
file selector dialogs will look
funny with anything but an 8x8 font! Don't worry too much, though;
every other GUI object will work fine with any font.
So without further ado, let's get to the real meat of the tutorial...
Next: Extending the System
|