home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
cprog
/
guilib20.zip
/
GUI.DOC
< prev
next >
Wrap
Text File
|
1993-01-16
|
46KB
|
1,309 lines
****************************************************************************
Documentation for
GUI_LIB Library for Borland C++ and Turbo C++
Version 2.0
(c) Copyright 1993 - David S. Reinhart Associates
(717) 284-3736
****************************************************************************
All files included on this distribution diskette are (c) Copyright 1993,
David S. Reinhart Associates
Congratulations! You have just received one of the finest graphics
libraries available for use with Borland C++ and Borland's Turbo C++
compilers. Using the GUI library will enable you to create
graphic based applications to run in DOS just as easily as creating
text based applications. The objects included in the library are all
familiar objects, found in many commercially available software
packages. They include pushbuttons, icons, text entry fields, and
bitmaps to name just a few. Some of the features in this library are
found nowhere else! Now you can harness the power and intuitiveness
of the Graphic User Interface for use in your applications. From
paint programs to databases, all of your programs can benefit from
the use of graphics.
If you have not already done so, I would suggest that you stop
reading this documentation for a moment to check out the demo
provided on the distribution diskette. The name of the demo is
simply DEMO.EXE. In order to run the demo you must first have
loaded your mouse driver. Any Microsoft, Logitech, or compatible
mouse will be fine. From the DOS prompt type DEMO <ENTER>. The
demo highlights most of the objects in the library. After viewing
the demo, return to the documentation.
SHAREWARE
****************************************************************************
The GUI library and it's included files are being distributed as
Shareware. They are complete and not crippled in any way. You may
use these files for a 30 day period free of charge. You may not,
however, distribute any works created with these files in any way,
shape or form until you have registered your copy of the package.
If after 30 days you decide to continue using the files in this
package you are obligated to register with the author. The concept
of Shareware helps to keep the cost of quality software low. Please
do your part by registering this software. Use of the software
contained in this package after 30 days without registration will
bring about sever penalties.
This software package is comparable with many retail libraries
costing hundreds of dollars. It is through the concept of Shareware
that I am able to bring this software to you at a much reduced cost.
What's more, registered users will receive one upgrade free of cost
rather than at an upgrade cost.
The price of this package is as follows:
Single user license - $35
includes free copy of the next major upgrade of the
package.
Corporate user license - $60
includes free copy of the next major upgrade of the
package.
Please use the registration form included with this package to
register your copy. The form can be found in the file REGISTER.DOC.
Thank you
If you like this product you may also wish to order the
ObjectEase library also from this author. This library makes it
easy to migrate into the realm of C++ programming by offering
the widest range of classes available in any library at any
cost. Include a note on your registration form to receive a demo
of the ObjectEase library.
Use of the GUI library
In order to utilize the objects and functions in the GUI
library you need only add the GUI.LIB library to your project,
and include the header file in your program code. You can then
declare object instances and call the functions as you would with
any other library. You must, of course, first initialize the
graphics mode with a call to initgraph(). The best way to do this
is by using one of the member functions of the Screen class, new
in version 2.0. The GUI.LIB library file was compiled under the
large memory model using Borland C++ 3.1 and should be included
only in projects that are also to be compiled for the large memory
model. This is because the use of graphics can be very memory
intensive and the large memory model gives the program access to
all of the available RAM, not just a single 64K data segment.
This documentation is divided into sections describing each of the
various graphic objects followed by a description and examples of
all of the methods that may be used with the object. Please take
special note of the example fragments as they may be of great help
to you in getting to know the proper use of these objects and
methods. I'll start by describing the objects new in version 2.0.
If you are familiar with version 1.0, you should also check out
the new editors included in this version, as well as the file
EDITORS.DOC which describes their use.
****************************************************************************
SCREEN
****************************************************************************
The screen class was devised to put the hardware into any of several
graphics modes and to initialize several other variables that come
into play when programming for the graphics mode. I would highly
recommend using this class instead of calling initgraph() directly.
You should still call closegraph() at the end of your program to
restore the hardware to it's original state.
Here is the declaration of the Screen class from the header file:
class Screen {
protected:
static int huge alwayszero();
public:
Screen();
~Screen();
int VGA_480_16();
int VGA_350_16();
int VGA_200_16();
int VGA_200_256();
void fill(int);
};
As you can see, this class is really only useful for VGA modes,
but I think that this is where 95% of all graphics programming
is done anyway.
Class Screen is very simple to use. You should declare an instance
of this class as a global variable. Consider this short example:
Screen screen;
void main()
{
screen.VGA_200_256();
...
That's really all there is to it. The screen object will (re)init-
ialize the mouse driver if one is present. This is because I have
found that Logitech mice are not always capable of reaching the
entire screen if they are not initialized AFTER the screen changes
modes.
Use the fill(int) member function with an integer paremeter re-
presenting the color you would like to clear the screen with.
For example:
Screen screen;
void main()
{
screen.VGA_200_256();
screen.fill(15); //clears the screen to white
...
***************************************************************************
MCURSOR
***************************************************************************
The Mcursor object controls and gets information about the mouse
cursor. This is the only new class that will cause you to do some re-
coding if you use version 2.0 of the GUI library to re-compile programs
which you have written with version 1.0.
Several predefined shapes for the graphics mouse cursor have been
included in the GUI library, however, at this time there is no
provision for including your own designs with the Mcursor class.
****************************************************************************
Note: The instance "Mcursor the_mouse;" has been pre-defined in
the header file. This is because many of the objects in this library
make use of the Mcursor object on their own. You need to declare this
same instance of the Mcursor class within your code or the mouse will
not function as you expect. When you declare an Mcursor instance in your
code simply declare it as external like this:
extern Mcursor the_mouse; //you MUST name your instance
//the_mouse
****************************************************************************
int Mcursor::init()
Initializes the mouse. This function must be called before trying
to use any of the other mouse functions. If a mouse driver is
detected the function will return 1, if no mouse driver is present
it will return 0.
example: extern Mcursor the_mouse;
if(!the_mouse.init()) {
puts("No mouse driver detected");
exit(0);
}
The Mcursor instance is immediately put into a state of "unarmed."
You must "arm" the instance before it can be displayed.
void Mcursor::show()
Makes the mouse cursor visible on the screen.
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.show();
void Mcursor::hide()
Makes the mouse cursor invisible.
example: extern Mcursor the_mouse;
the_mouse.init();
getch();
the_mouse.hide();
void Mcursor::unarm()
Makes the mouse cursor invisible, and keeps other object instances
from turning it back on. Any object that needs to draw itself on the
screen will turn off the mouse cursor while it is manipulating the
screen and then turns it back on when it is finished. If you don't want
an object to have the capability of restoring the mouse cursor to the
screen you must call Mcursor::unarm().
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.unarm(); //hides the mouse cursor
//and keeps it from
//being restored by
//other objects
//instances.
void Mcursor::arm()
Restores the mouse cursor to the screen and allows other object
instances to restore it to the screen when they have finished updating
the screen. YOU MUST CALL THIS MEMBER FUNCTION AFTER INITIALIZING THE
MOUSE BECAUSE IT IS UNARMED UPON INITIALIZATION!
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.unarm();
...do some screen manipulation
the_mouse.arm();
void Mcursor::set_hor_bounds(int left,int right)
Sets the horizontal bounds of the mouse cursor movement.
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.set_hor_bounds(100,getmaxx()-100);
// the mouse cursor now cannot move closer than
//100 pixels to the sides of the screen.
void Mcursor::set_ver_bounds(int top,int bottom)
Sets the vertical bounds of the mouse cursor movement.
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.set_ver_bounds(100,getmaxy()-100);
//the mouse cursor now cannot move closer than
//100 pixels to the top or bottom of the screen.
void Mcursor::position(int x,int y)
Moves the mouse to the specified coordinates on the screen.
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.position(0,0);
//the mouse cursor is now in the upper left
//corner of the screen.
void Mcursor::conditional_off(int x,int y,int x1,int y1)
Declares a portion of the screen where the mouse cursor will not
be visible.
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.conditional_off(0,0,100,100);
//the mouse cursor will not be visible in the
//upper left corner of the screen.
int Mcursor::LBP()
Returns 1 if the left mouse button is pressed, 0 otherwise.
example: extern Mcursor the_mouse;
int done=0;
the_mouse.init();
while(!done) {
if(the_mouse.LBP())
done=1;
}
printf("\a");
int Mcursor::RBP()
Returns 1 if the right mouse button is pressed, 0 otherwise.
example: extern Mcursor the_mouse;
int done=0;
the_mouse.init();
while(!done) {
if(the_mouse.RBP())
done=1;
}
printf("\a");
int Mcursor::mx()
Returns an integer representing the x coordinate of the mouse
cursor.
example: extern Mcursor the_mouse;
int x;
the_mouse.init();
x=the_mouse.mx();
int Mcursor::my()
Returns an integer representing the y coordinate of the mouse
cursor.
example: extern Mcursor the_mouse;
int y;
the_mouse.init();
y=the_mouse.my();
void Mcursor::changeto(int)
Changes the shape of the graphics mouse cursor. Has no effect on
the text mode mouse cursor. This function first determines the
current shape of the mouse cursor. If the current shape is the
same as the one you are requesting it to change to the function
will exit with no action taken.
example: extern Mcursor the_mouse;
the_mouse.init();
the_mouse.changeto(CROSSHAIR);
Note: The following cursor shapes are predefined and may be used
as the parameter to the Mcursor::changeto(int) function:
#define UPARROW 1
#define DOT 2
#define PENCIL 3
#define CROSSHAIR 4
#define ARROW 5
#define FINGER 6
#define POINT 7
#define CLOCK 8
#define DISK 9
#define IBAR 10
#define PAINTCAN 11
#define HAND 12
#define ERASOR 13
#define GUNSIGHT 14
#define SCISSORS 15
#define JAWS 16
These are the member functions of the Mcursor class. I'm sure
you'll find them as easy to implement as they are powerful to use. In
these days of the Graphical User Interface, mouse routines are becoming
a standard even in text based applications. These tools out the power of
the mouse in your hands.
***************************************************************************
BITMAPS
***************************************************************************
The Bitmap object is used to display and capture graphic images.
There are two editors included in this package to create bitmap images.
The files are in the Borland getimage() format, which is certainly not
the most compressed format for image storage. Future versions of this
library are sure to include Bitmap objects with various graphic file
formats. The bitmap editors are 16IMAGE.EXE and 256IMAGE.EXE for
creating 16 and 256 color bitmaps respectively.
Bitmap::Bitmap()
The default constructor.
Bitmap::~Bitmap()
The default destructor.
void Bitmap::init(int x,int y)
Initializes a bitmap object. The x and y parameter represent the
x,y coordinates for displaying the bitmap. If this coordinate pair
is not known when you initialize the bitmap instance, simply
initialize it to 0,0.
void Bitmap::changexy(int x,int y)
Changes the x,y coordinates at which to display the bitmap.
void Bitmap::load(char* name)
Loads the bitmap image specified in the name parameter from disk.
This file must have been created by one of the bitmap editors
included with the GUI library, or by a previous call to
Bitmap::save(char*).
void Bitmap::save(char* name)
Saves a bitmap image to disk. Under most circumstances, this will
be an image that has been captured using the
Bitmap::capture(int,int,int,int) member function.
void Bitmap::capture(int x,int y,int x1,int y1)
Captures the area bounded by the rectangle x,y,x1,y1 to a Bitmap
object. This area MUST NOT exceed 64K as this is the maximum size
for a Borland getimage() buffer.
void Bitmap::moveto(int x,int y)
Hides a displyed Bitmap object and re-displays it at the new x,y
coordinates.
void Bitmap::hide()
Removes a displayed Bitmap object from the screen.
void Bitmap::show_COPY()
Displays a Bitmap image using the COPY_PUT mode.
void Bitmap::show_XOR()
Displays a Bitmap object using the XOR_PUT mode.
void Bitmap::show_OR()
Displays a Bitmap object using the OR_PUT mode.
void Bitmap::show_NOT()
Displays a Bitmap using the NOT_PUT mode.
void Bitmap::show_AND()
Displays a Bitmap object using the AND_PUT mode.
int Bitmap::isshown()
Returns 1 if the Bitmap object is displayed on the screen, 0
otherwise.
int Bitmap::hit()
Returns 1 if the mouse cursor is on the Bitmap object, 0
otherwise.
int Bitmap::xsize()
Returns an integer representing the horizontal size of the Bitmap.
int Bitmap::ysize()
Returns an integer representing the vertical size of the Bitmap.
int Bitmap::bitmapx()
Returns the upper left x coordinate of the Bitmap.
int Bitmap::bitmapy()
Returns the upper left y coordinate of the Bitmap.
int Bitmap::LBSCLK()
Returns 1 if the left mouse button has been pressed while the
mouse cursor was on the Bitmap object, 0 otherwise
int Bitmap::LBDCLK()
Returns 1 if the left mouse button was pressed twice while the
mouse cursor was on the Bitmap object. The button must have been
pressed two times within 1/2 of a second or else the timer resets.
***************************************************************************
GCHECKBOXES
***************************************************************************
A Gcheckbox can be used to allow the user to make multiple selections.
Call "init()" with the following three parameters to initialize a Gcheckbox.
The x int coordinate, the y int coordinate, and a char * representing the
descriptive text to be displayed with the Gcheckbox. Call "show()" to
display the Gcheckbox on the screen. Calling "check()" and "uncheck()"
will toggle the state of the Gcheckbox, and calling "is_checked()" will
tell you its current state. The "hit()" member function returns true if
the mouse cursor is positioned on the Gcheckbox.
Follow this example:
Gcheckbox mybox;
int done=0;
mybox.init(100,100,"This is a Gcheckbox");
mybox.show();
while(!done) {
if(the_mouse.LBP()) {
if(mybox.hit()) {
if(mybox.is_checked())
mybox.uncheck();
else
mybox.check();
}
}
}
You don't have to use the mouse as the trigger to toggle states.
Any keypress or key combination that you choose can be used to toggle
the state.
****************************************************************************
GRADIO
****************************************************************************
Gradio is the graphics mode version of the radio button. Basically
the way a radio button works is this: First, you must have more than one
of them. If you only need one use a Gcheckbox instead. One of the series
of Gradios is initially selected. When the user selects a different
radio button, the first one becomes de-selected, and the new one becomes
selected, and so on. Remember, unlike a series of Gcheckboxes, only ONE
Gradio can be selected at a time.
Initialize a Gradio by calling "init()" with three parameters. The
first two are ints specifying the x and y coordinates respectively to
display the Gradio, and the third is a char* representing the
descriptive text to be displayed to the right of the Gradio. After
initializing the Gradio you can show it with a call to "show()". Like a
Gcheckbox you can toggle the state of a Gradio with calls to "check()"
and "uncheck()", and test if it has been hit with the mouse cursor by
calling "hit()". Calling "is_checked()" will tell you the current state
of the Gradio.
Let's look at an example:
Gradio rb1,rb2;
int done=0;
rb1.init(100,100,"This is a radio button");
rb2.init(100,120,"So is this");
rb1.show();
rb2.show();
while(!done) {
if(the_mouse.LBP()) {
if(rb1.hit()) {
if(rb1.is_checked()) {
rb1.uncheck();
rb2.check();
}
else {
rb1.check();
rb2.uncheck();
}
if(rb2.hit()) {
if(rb2.is_checked()) {
rb2.uncheck();
rb1.check();
}
else {
rb2.check();
rb1.uncheck();
}
}
}
}
***************************************************************************
SOUNDQ
***************************************************************************
The SoundQ class is used for playing music and sounds in the
background while foreground processes continue to execute. This is a
feature that you will commonly find in use in game programs, but can be
useful in any application. If you're like me, you have probably tried to
find some way to do this before, but the necessary functions are simply
not available as part of the standard C or C++ libraries. Now you have
the tools... you have the POWER...the power of the OBJECT!
NOTE: When you include an instance of the SoundQ class in your
program the timer chip will be reset to tick 500 times per second. The
normal rate for this chip is 18.2 times per second. Clock functions will
continue to operate normally as the SoundQ object issues a clock tick at
the normal rate of 18.2 times per second, however, you may find that you
need to make adjustments in any delays issued by the "void delay(long)"
function that comes with the standard library.
Let's take a look at the details of the SoundQ class...
SoundQ::SoundQ
The default constructor.
SoundQ::~SoundQ
The default destructor.
void SoundQ::adjust_speed(float)
Adjusts the speed of the sounds being played in the background.
The default value is 1.0. Increasing this value will slow down the
playback, decreasing it will of course speed up the playback.
Changing this value to 2.0 will effectively play back the sounds
at half speed.
example: SoundQ sq;
sq.adjust_speed(2.0);
void SoundQ::play(int freq,int duration)
Places notes in the queue to be played by the SoundQ object. The
notes placed in the queue will begin to play immediately. Remember
that the timer tick has been reset to tick 500 times per second by
the SoundQ object, therefore, to make a note sound for 1 second
the duration parameter must be 500.
example: SoundQ sq;
sq.play(440,100);
Note: The following have been defined in the header file, and make
the programming of music much simpler:
#define C 523 Frequency of Middle C
#define CS 554 C Sharp
#define D 587 D
#define DS 622 D Sharp
#define E 659 E
#define F 698 F
#define FS 740 F Sharp
#define G 784 G
#define GS 831 G Sharp
#define A 880 A
#define AS 932 A Sharp (or B Flat)
#define B 988 B
#define C1 1046 C one octave above middle C
#define SN 32 Duration of sixteenth note
#define EN 63 Eighth note
#define QN 125 Quarter note
#define HN 250 Half note
#define WN 500 Whole note
#define ENT 20 Duration of eighth note triplet
#define QNT 41 Duration of Quarter note triplet
#define HNT 83 Duration of Half note triplet
#define BN 30000,5 Place between two notes of the same
frequency to clearly define the sounding
of two notes.
#define SR 30000,32 Plays a sixteenth note rest
#define ER 30000,63 Plays an eighth note rest
#define QR 30000,125 Plays a quarter note rest
#define HR 30000,250 Plays a half note rest
#define WR 30000,500 Plays a whole note rest
#define NM 30000,1 Stops the sounding of a tone. Use at the
end of a song.
Let's use these defines to play the C Major Scale with quarter
notes...
SoundQ sq;
sq.play(C,QN);
sq.play(D,QN);
sq.play(E,QN);
sq.play(F,QN);
sq.play(G,QN);
sq.play(A,QN);
sq.play(B,QN);
sq.play(C1,QN);
sq.play(NM); //used to stop the sound
These defined values can be multiplied or divided to play sounds
from different octaves. Remember that once you have created a song you
only need to use SoundQ::adjust_speed to vary the playback speed of the
song.
****************************************************************************
MISCELLANEOUS
****************************************************************************
The following functions, while not part of any class structure, are
included in this version of the library, and will be of great use to you.
void dlay(int ticks);
Causes a delay of the specified number of clock ticks. Clock ticks
occur 18.2 times per second.
long getticks();
Returns the time as a long number representing the number of clock
ticks since the preceding midnight.
int altkey();
Returns 1 if an ALT key is pressed, 0 otherwise.
int ctrlkey();
Returns 1 if a CTRL key is pressed, 0 otherwise.
int lshiftkey();
Returns 1 if the LEFT SHIFT key is pressed, 0 otherwise.
int rshiftkey();
Returns 1 if the RIGHT SHIFT key is pressed, 0 otherwise.
void flushkeys();
Clears any and all keypresses from the keyboard buffer.
unsigned char getvidmode();
Returns an unsigned char value representing the current video
mode.
****************************************************************************
PANELS
****************************************************************************
Panels can be associated with pop-up windows in a text environment.
They serve to contain and draw attention to other objects such as
text or pushbuttons. The class Panel is declared in the header
file GROBJECT.H as:
class Panel:public Point
{
protected:
int w; WIDTH
int h; HEIGHT
int in_or_out; CONCAVE or CONVEX
int thick_or_thin; BORDER STYLE
public:
Panel();
~Panel();
virtual void show();
void init(int xpos,int ypos,int width,int height,
int inorout,int thickorthin);
};
The class POINT from which Panel is derived is the base class for
all of the graphic objects in this library.
In order to facilitate the initialization of the inorout and
thickorthin variables the definitions IN, OUT, THICK and THIN
may be used. These are defined in the header file.
To declare an instance of class PANEL and display it in your
application follow the example in the following code fragment.
Panel mypanel;
mypanel.init(10,10,100,100,IN,THICK);
mypanel.show();
It's just that simple. Remember that the graphics mode must first
be initialized by a call to initgraph. If you are unfamiliar with
this function consult your compiler documentation.
All of the objects in this library contain the method "init".
You must call "init" with the proper parameters before trying
to display the object. There's no telling what might happen if
you try to display an uninitialized object.
****************************************************************************
BEVELS
****************************************************************************
Bevels are just like panels with a more decorative border. All
calls to their methods are identical except that a call to
Bevel.init() takes one less parameter. You do not need to specify
IN or OUT because Bevel borders always go out. Here is the
definition. I'll skip an example as you can easily follow the
Panel example and make appropriate substitutions.
class Bevel:public Point
{
private:
int w; WIDTH
int h; HEIGHT
int thick_or_thin; STYLE OF BORDER
Panel outerbevel;
Panel innerbevel;
public:
void init(int,int,int,int,int);
virtual void show();
};
****************************************************************************
PUSHBUTTONS
****************************************************************************
Pushbuttons simulate keyboard keys on the screen. They serve to
get user input for a variety of purposes. They are very intuitive
and can display either a text title or a graphic image.
The header file definition of the class Button is:
class Button:public Point
{
protected:
int state, UP or DOWN
int sizex, WIDTH
int sizey; HEIGHT
char btntxt[40]; TEXT ID
int file_text; TEXT ID or GRAPHIC IMAGE
void *picture; BUFFER CONTAINING GRAPHIC IMAGE
void getpic(char*);
public:
Button();
~Button();
virtual void show();
virtual void press();
void init(int xpos,int ypos,char* text,int);
int hit();
};
To declare an instance of class Button you need to supply the
parameters for the upper left x and y positions, a string which
either represents the text to be displayed on the button or the
name of the file containing the image to be used on the button,
and an integer flag representing whether or not the last parameter
refers to text or a filename.
The definitions TEXT and IMAGE can be used in this parameter and are
defined in the header file.
Consider this example:
Button textbutton;
textbutton.init(10,10," EXIT ",TEXT);
textbutton.show();
This would create and display a button that said " EXIT " on it.
Consider this:
Button graphbutton;
graphbutton.init(10,10,"EXIT",IMAGE);
graphbutton.show();
This would create and display a button containing the image stored
in the file "EXIT.BTN". The file extension should not be included
in the parameter as ".BTN" is the assumed extension. The graphic
file must be present on the disk before trying to call this function.
Using the ICONEDIT program supplied with this package you can very
easily create these graphics to be included on buttons.
Note that you do not need to specify the width and height of buttons.
If you are using text labels the button width is determined
automatically to accomodate up to 40 characters, and if your are
using graphics the button defaults to 20x20. This is the size of
the button graphics created by the ICONEDIT program.
Pressing the button is usually done with the mouse cursor, however,
you may find it useful to use some other trigger to press the button.
The button method "hit()" determines if the mouse cursor is within the
boundaries of the button. For a detailed discussion on the use of the
mouse functions see the appropriate section of this documentation. If
you don't understand all of the functions in this next code fragment
you can find explanations elsewhere in this document.
Button mybutton; DECLARES INSTANCE OF BUTTON
mybutton.init(10,10,"EXIT",TEXT); INITIALIZES MYBUTTON
mybutton.show(); DISPLAYS MYBUTTON ON SCREEN
while(!kbhit()) { DO THIS WHILE NO KEYS ARE HIT
if(leftmousekeypressed()) { IF THE LEFT MOUSE KEY IS
PRESSED
if(mybutton.hit()) { IF MOUSE CURSOR IS ON MYBUTTON
mybutton.press(); DISPLAY MYBUTTON AS PRESSED
while(leftmousekeypressed()); WAIT UNTIL LEFT MOUSE KEY HAS
BEEN RELEASED
mybutton.show(); DISPLAY MYBUTTON IN NORMAL
STATE
}
}
}
Immediately after restoring the button to the normal (undepressed)
state the program can branch to take whatever action the button
calls for. By using the Button method "press()" all of the
redrawing and repositioning of the text and/or graphic images is
handled automatically by the GUI_LIB library.
****************************************************************************
COLORBUTTONS
****************************************************************************
Colorbuttons don't do much except tell you when they are hit and
return their current color. This is very useful if you are coding a paint
program and need some way to set the current foreground and background colors.
I'm sure you can find some other good uses for this class as well.
The header definition of class Colorbutton is:
class Colorbutton:public Point
{
protected:
int color;
int width;
int height;
public:
void init(int,int,int,int,int);
void show(int);
int hit();
int getcolor();
};
Call "init()" with integer parameters for the x and y position,
the width, the height, and the color of the button. Call "show()" with
and integer value representing the color of the rectangle you wish to
have surrounding the Colorbutton. By manipulating this value you can
effectively show an "active" Colorbutton in a row of Colorbuttons. "Hit()"
simply returns whether or not the mouse cursor is in the Colorbutton
area, and "getcolor()" return the color of the Colorbutton.
A quick way to make a color selection bar is as follows:
Colorbutton colorarray[16];
for(int i=0;i<16;i++) {
colorarray[i].init(100+(i*20),100,20,20,i);
colorarray[i].show(15);
}
****************************************************************************
ICONS
****************************************************************************
Icons can be used in much the same way as buttons. They will always
contain a graphic image, although text can be a part of the graphic.
They are not 3 dimensional like pushbuttons.
The graphic images for these Icon objects are created using the
ICONEDIT program. This program produces 32x32 pixel icons that can be
single or multi-framed. More on this in a moment.
The definition of the Icon class is:
class Icon:public Point
{
protected:
int state; SELECTED OR NOT
public:
void far *picture; BUFFER CONTAINING GRAPHIC
Icon();
~Icon();
void init(int xpos,int ypos,char* fname);
void show();
void choose();
int hit();
int ispressed();
};
Like the other graphic objects, the Icon class must first be
initialized with a call to "init()." Init() takes three parameter,
the x and y coordinates of the upper left corner, and the file name
of the file containing the graphic image for the icon. The filename
parameter should be given without an extension as the default
extension ".ICN" is assumed. The file named in this parameter must
exist in the current directory.
Let's look at a short example:
Icon myicon;
myicon.init(10,10,"paint");
myicon.show();
This example declares an instance of class Icon using the file
"paint.icn" as the graphic, and then displays the icon.
As with the pushbutton, the method "hit()" determines if the
mouse cursor is within the boundaries of the icon. If it is,
and if a mouse key is pressed, we can change the appearance of
the icon to mark it as selected using the method "choose()." Here's
a quick example, similar to that presented for the pushbutton:
Icon myicon;
myicon.init(10,10,"paint");
myicon.show();
while(!kbhit()) {
if(leftmousekeypressed()) {
if(myicon.hit()) {
if(!myicon.ispressed()) {
myicon.choose();
while(leftmousekeypressed());
myicon.show();
}
}
}
}
Usually when an icon has been selected you will want to make
sure that the last icon to be selected gets reset to its normal
state with a call to "show()." Whatever action needs to be taken
as a result of the icon's selection can be done after the call to
"choose()." The method "ispressed()" simply returns whether or not
the icon is already displayed in its selected state.
****************************************************************************
ACTICONS
****************************************************************************
Acticons are exactly like Icons except that instead of simply
reversing their image to mark them as the selected icon, they
become animated. Acticons are created using the ICONEDIT program.
They are created in the same manner as an Icon, but instead of just
a single frame graphic, they contain several (up to 32) frames.
Acticons are defined in the header file as follows:
class Acticon:public Icon
{
protected:
void *picture[32]; GRAPHICS BUFFERS
int state; SELECTED OR NOT
int numpix; NUMBER OF FRAMES
public:
Acticon();
~Acticon();
void init(int,int,char*);
void show(int);
void choose();
int ispressed();
void animate(int);
void backforth(int);
};
Like Icons, they are initialized with a call to "init()" with
parameters for the upper left x and y coordinates, and the file
name containing the graphic images. When you call "show()", however,
you must supply an integer parameter specifying which frame to
display. Usually you will want to make this frame 0 because if
you call "choose()" the negative image of frame 0 will be displayed
by default.
For example:
Acticon myicon;
myicon.init(10,10,"paint");
myicon.show(0);
Just like an Icon except for the parameter in the call to "show()."
If you want to use choose to show the reverse image of the Acticon
it is done the same as it is for class Icon. If however you want
to animate the Acticon you must call "animate()" or "backforth()."
Both of these methods will put the Acticon in motion. "Animate()"
will display the frames in ascending order and then restart at
frame 0. "Backforth()" will display the frames in ascending order,
but when it reaches the last frame it will then display the frames
in reverse order back to frame 0. Both of these methods take a
single parameter which specifies the delay between displaying each
frame. This delay is expressed in eighteenths of a second. The
lower the value, the faster the animation. You do not need to
specify the number of frames in the Acticon as this information is
contained in the graphic file created by ICONEDIT. Let's take a look:
Acticon myicon;
myicon.init(10,10,"paint");
myicon.show(0);
while(!kbhit()) {
if(leftmousekeypressed()) {
if(myicon.hit()) {
while(leftmousekeypressed())
myicon.animate(3);
}
}
}
In this code fragment, if the left mouse key is pressed while the
cursor is on the Acticon, then the Acticon will animate for as long
as the left mouse key is pressed. Note that "animate()" and
"backforth()" will only change the animation by one frame, so for
continuous motion you must include calls to these methods within
some sort of loop.
****************************************************************************
GSTRINGS
****************************************************************************
No, it's not something a stripper wears, the G in Gstring simply
stands for graphic. These object are used for getting text input
while in graphics mode. They display their own input fields and can
handle all of the text editing keys like arrows, backspace, delete,
etc...
Class Gstring is defined as:
class Gstring:public Tstring {
protected:
int curpos; CURSOR POSITION IN STRING
int curson; CURSOR ON OR OFF
void showcurs();
void hidecurs();
public:
void init(int xpos,int ypos,int length,int caps);
void show();
void input();
void get_input();
void get_form_input();
int isshown();
void check_for_blink();
};
Once again a call to "init()" is necessary to begin. The necessary
parameters are the x and y coordinates of the upper left corner of
the input field, the length of the field, and an integer flag to
indicate whether of not to force the input into all capital letters.
Any nonzero value will force all caps.
Notice that Gstring is not derived from class Point as are all the
other object, but is derived from class Tstring. Tstring is not a
part of this graphics library, but performs the same functions as
Gstring only in text mode.
Two methods that are part of Tstring that you might find useful are
"preset()" and "reset()." Call "preset()" with a string parameter
that you wish to have displayed in the input field by default, and
"reset()" with no parameters to clear the input field. For example,
if you wanted the input field to be displayed with the preset value
of "Married" you would use code similar to the following:
Gstring mystring;
mystring.init(100,10,10,0);
mystring.preset("Married");
mystring.show();
If you don't use the "preset()" method the input field will just
be blank, probably what you want in most cases anyway. To allow
user input just add the statement:
mystring.get_input();
This will allow text input until the user presses either <ESCAPE>
or <ENTER>. You can test for the <ESCAPE> key with the Tstring
method "escapehit()." Let's put it all together...
Gstring mystring;
char *the_string;
mystring.init(100,10,10,0);
mystring.get_input();
if(mystring.escapehit())
exit(0);
else
strcpy(the_string,mystring.getstring());
The Tstring method "getstring()" returns a char * to the actual
text string that was entered by the user.
****************************************************************************
GMENUBUTTON and GMENU
****************************************************************************
The classes Gmenubutton and Gmenu provide the capabilities for you
to include pulldown menus in you graphics applications. The
Gmenubutton is simply the text that will appear in the menu bar
whereas the Gmenu is the moving bar menu that will pop up when a
Gmenubutton is selected. Since these two objects are so closely
related I will discuss them together. Here are the definitions:
class Gmenu {
protected:
int on;
int x,y,w,h;
int num;
gitemarray gitems;
int menuchoice;
int oldbarx,oldbary;
void *ptr;
void *menubar;
public:
Gmenu();
~Gmenu();
void init(int xloc,int yloc,int numentries,
gitemarray gitem);
int show();
void hide();
int isshown();
};
class Gmenubutton {
protected:
int on;
int x,y;
int offfgd,offbgd;
int onfgd,onbgd;
char id[20];
public:
Gmenubutton();
~Gmenubutton();
void init(int xloc,int yloc,int ffgd,int fbgd,
int nfgd,int nbgd,char txt[20]);
void show();
void press();
int hit();
};
The data element gitemarray is a predefined two dimensional
array containing the strings that will appear in the Gmenu.
The maximum number of items in a Gmenu is 10, and the width of
the pop-up menu is fixed at 100 pixels. When initializing the
strings in the gitemarray always start at index 1 rather than
index 0. Like this:
gitemarray menu1array;
strcpy(menu1array[1],"ITEM 1");
strcpy(menu1array[2],"ITEM 2");
etc...
A Gmenubutton is initialized with parameters for x and y screen
locations, normal state fgd and bgd colors, selected state fgd
and bgd colors, and the text to be displayed.
A Gmenu is initialized with parameters for the x and y screen
locations, the number of entries to be in the menu, and the
gitemarray containing the item strings. The Gmenu is popped-up
with a call to "show()" which returns an integer representing the
index of the gitemarray the bar was on when the selection was made.
If no selection was made "show()" returns 11.
Let's look at an example to hopefully clear this all up.
gitemarray itemarray;
Gmenu mymenu;
Gmenubutton mymenubutton;
int menuchoice;
strcpy(itemarray[1],"ITEM 1");
strcpy(itemarray[2],"ITEM 2");
strcpy(itemarray[3],"ITEM 3");
strcpy(itemarray[4],"ITEM 4");
setfillstyle(SOLID_FILL,15); MAKE A MENU BAR AT TOP OF SCREEN
bar(0,0,getmaxx(),10);
mymenubutton.init(0,0,0,15,15,0,"MENU 1");
mymenubutton.show();
mymenu.init(0,11,4,itemarray);
if(leftmousekeypressed()) {
if(mymenubutton.hit()) {
mymenubutton.press();
choice=mymenu.show();
mymenu.hide();
mymenubutton.show();
}
}
In this example the integer variable choice will contain the
number of the item that was selected. Execution can then branch
to the appropriate functions based on this value using case
statements.
**************************************************************************
PRINTING TEXT
***************************************************************************
Although not part of a class library, there is a text output
function included in the library that you will find most useful. The
"outtextxy()" function which is part of the Borland library will only
take a char* as the parameter to write to the screen. You cannot give
it a variable to format into a string for you. There is a function in the
GUI_LIB library called gprintxy() that will format variables into
printable text for you. The definition is:
gprintxy(int,int,char *fmt,...)
You can use this function just as you would the "printf()" function
in text mode. So for example you could write:
int age=27;
gprintxy(100,100,"%d",age);
"gprintxy()" will format the variable and print it to the screen
correctly. The two integer parameters represent the x and y position to
print the string. Remember that this function is dependent on the current
text justification settings. Use the Borland library function
"settextjustify()" to alter these settings.
Don't forget to use the registration form in the file REGISTER.DOC
to register your copy of this library package. I feel that it is
good quality and very useful software that is well worth the price
that I am asking.
Thank you for using software from David S. Reinhart Associates