home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-12 | 53.4 KB | 1,411 lines |
- 4 GADGETS
-
- 4.1 INTRODUCTION
-
- In this chapter we will look at how the user can communicate
- with the program. All programs which use Intuition should,
- if possible, be controlled by a mouse, since it is the most
- commonly used input device. Intuition's Gadgets will play a big
- role here.
-
- A gadget can be a "button" which the user can click on, but it
- can also be a small knob which can be dragged (like a volume
- control on a radio). A gadget can even be a box where the user
- can enter a text string or a value. The advantages of using
- gadgets are almost uncountable. They are very well supported by
- Intuition which means that your program hardly needs to do
- anything, but still have an outstanding user interface which
- is both easy to understand as well as use.
-
-
-
- 4.2 DIFFERENT TYPES OF GADGETS
-
- There exist two types of gadgets: System gadgets, which we
- already have discussed in chapter 2.3 SYSTEM GADGETS, and
- Custom gadgets. For every window System gadgets always look
- the same, and are always placed in the same places. Custom
- Gadgets, however, can be placed wherever you want, and it is
- you who decide what they should look like.
-
-
-
- 4.3 CUSTOM GADGETS
-
- There exist four different types of Custom gadgets:
- - Boolean gadget On/Off (True/False) button.
- - Proportional gadget A small knob which can be moved around
- inside a container.
- - String gadgets Gadget which enables the user to enter
- a string.
- - Integer gadget Same as the String gadget, except that
- the user can only enter integer numbers.
-
-
-
- 4.3.1 GRAPHICS FOR CUSTOM GADGETS
-
- You can render the gadget with help of the high-level graphics
- utilities which are supported by Intuition (See chapter 3
- GRAPHICS for more information). You can render the gadget with
- help of a Border structure, or an Image structure. You can even
- have a different rendering when the gadget is selected,
- highlighted.
-
- It is of course possible to open gadgets with no rendering at
- all. The Drag gadget (System gadget) is a good example.
-
-
-
- 4.3.2 POSITION
-
- You can position the gadget anywhere on the display. The
- position is normally relative to the top left corner of the
- displaying element (Window, Requester etc). If you want you
- can position the gadget relative to some other sides than the
- top left corner:
-
- If you want the gadget to be placed 10 pixels out and 20 lines
- down from the top left corner of a window, you set LeftEdge to
- 10, and TopEdge to 20. (LeftEdge etc are elements in the Gadget
- structure which is described later in the chapter.)
-
- If you on the other hand want the gadget to always be 20 pixels
- above the bottom border of the window, and 10 pixels to the left
- of the right border, you set LeftEdge to -10 and TopEdge to -20
- together with the Flags GRELRIGHT and GRELBOTTOM. (More about
- this later.)
-
-
-
- 4.3.3 SIZE
-
- You decide the width and height of the gadget (the select box
- of the gadget) by setting the Width and Height variables as
- desired.
-
- If you set the Height to 25, the gadget will be 25 lines high.
-
- If you on the other hand set the Height to -25 and you set the
- GRELHEIGHT flag, the gadget will always be 25 lines smaller
- than the containing element (window etc).
-
- Same applies for the Width. If you set the Width to 50, the
- gadget will always be 50 pixels wide.
-
- If you on the other hand set the Width to be -50 and you set
- the flag GRELWIDTH, the gadget will always be 50 pixels smaller
- than the containing element.
-
-
-
- 4.4 INITIALIZE A CUSTOM GADGET
-
- When you want to use a Custom gadget you need to declare and
- initialize a Gadget structure which look like this:
-
- struct Gadget
- {
- struct Gadget *NextGadget;
- SHORT LeftEdge, TopEdge, Width, Height;
- USHORT Flags;
- USHORT Activation;
- USHORT GadgetType;
- APTR GadgetRender;
- APTR SelectRender;
- struct IntuiText *GadgetText;
- LONG MutualExclude;
- APTR SpecialInfo;
- USHORT GadgetID;
- APTR UserData;
- }
-
- NextGadget: A pointer to the next gadget in the list if
- there exist one, else NULL.
-
- LeftEdge, TopEdge: Position of the gadget's select box relative
- to the displaying element.
-
- Width, Height: Width and height of the gadget's select box.
-
- Flags: You must set one of the following four
- highlighting flags: (The gadget is
- highlighted when it is selected)
-
- GADGHCOMP: Complement the colours of all
- pixels in the gadget's select
- box.
-
- GADGHBOX: Draw a box around the the
- gadget's select box.
-
- GADGHIMAGE: Display an alternative Image/
- Border.
-
- GADGHNONE: No highlighting.
-
- If the gadget should be rendered as an Image
- set the flag GADGIMAGE, otherwise (render it
- with a Border structure, or no rendering at
- all) clear this flag.
-
- If you want the position and/or size of the
- gadget to be relative to the size of the
- displaying element, set the desired flags:
-
- GRELBOTTOM: TopEdge is used as an offset
- relative to the bottom of the
- displaying element, instead of
- an offset relative to the top of
- the displaying element.
-
- GRELRIGHT: LeftEdge is used as an offset
- relative to the right edge of
- the displaying element, instead
- of an offset relative to the
- left edge of the displaying
- element.
-
- GRELWIDTH: Width describes an increment to
- the width of the displaying
- element, instead of describing
- the absolute width of the
- gadget.
-
- GRELRIGHT: Height describes an increment
- to the height of the displaying
- element, instead of describing
- the absolute height of the
- gadget.
-
- If this gadget is a toggle-select gadget
- (see Activation flags) you can set the
- SELECTED flag, and the gadget will be
- selected and highlighted when opened. If
- not, the gadget will be unselected and non-
- highlighted when opened.
-
- You can also examine this field to see if
- the SELECTED flag is set or not. If it is
- set, the gadget is selected, else it is
- unselected.
-
- If you want that the gadget should be
- disabled when opened, you set the flag
- GADDISABLED. Your program can later change
- this by calling the functions OnGadget()
- (enables the gadget) and OffGadget()
- (disables the gadget).
-
- Activation: Set the flags for the desired effects:
- (More about these later...)
-
- GADGIMMEDIATE: If you want your program to
- know immediately when the
- user selects this gadget, you
- should set this flag.
-
- RELVERIFY: If you want your program to
- receive a message when the
- user releases the gadget and
- the pointer is still inside
- the gadget's select box, you
- should set this flag.
-
- FOLLOWMOUSE: Set this flag if you want
- your program to receive mouse
- positions every time the user
- moves the mouse while this
- gadget is selected.
-
- TOGGLESELECT: Each time the user selects
- this gadget, the on/off state
- of the gadget (as well as the
- image) is toggled. Your
- program can later check the
- status of the gadget by
- examining the SELECTED bit in
- the Flags field.
-
- BOOLEXTEND: Set this flag if your gadget
- has a BoolInfo structure
- connected to it.
-
-
- If your gadget is connected to a window you
- can set the following flags in order to
- change the size of the window's borders.
- (You can then put the gadget there.):
-
- RIGHTBORDER: The width of the window's
- right border is calculated
- with help of the gadget's
- position and width.
-
- LEFTBORDER: The width of the window's
- left border is calculated
- with help of the gadget's
- position and width.
-
- TOPBORDER: The height of the window's
- top border is calculated
- with help of the gadget's
- position and height.
-
- BOTTOMBORDER: The height of the window's
- bottom border is calculated
- with help of the gadget's
- position and height.
-
-
- If this gadget is connected to a requester
- you can set the ENDGADGET flag. The
- requester will only go away when a gadget
- with the ENDGADGET flag has been selected.
- (See chapter 5 REQUESTERS for more
- information about gadgets connected to
- requesters.)
-
- Intuition will only care about these flags
- if the gadget is a String/Integer gadget:
-
- STRINGRIGHT: Set this flag if you want the
- characters in the string to
- be right-justified.
-
- STRINGCENTER: Set this flag if you want the
- characters in the string to
- be center-justified.
-
- (The default is left-justified.)
-
- LONGINT: Set this flag if you want
- that the user should only be
- able to enter a 32-bit signed
- integer value.
-
- ALTKEYMAP: Set this flag if you want to
- use an alternative keymap.
- Remember to give the AltKeyMap
- pointer in the StringInfo
- structure a pointer to the
- keymap.
-
- GadgetType: You must set one of the following three
- flags:
-
- BOOLGADGET: Set this flag if you want a
- Boolean gadget.
-
- STRGADGET: Set this flag if you want a
- String/Integer gadget. If you
- want an Integer gadget you
- also need to set the
- Activation flag LONGINT.
-
- PROPGADGET: Set this flag if you want a
- Proportional gadget.
-
- The following two flags are only for gadgets
- connected to Gimmezerozero windows and
- requesters.
-
- GZZGADGET: If the gadget is connected to
- a Gimmezerozero window and
- you have set this flag, the
- gadget will be put in the
- outer window, and will not
- destroy any drawings etc in
- the inner window.
-
- REQGADGET: Set this flag if the gadget
- is connected to a requester.
-
- GadgetRender: A pointer to an Image or Border structure
- (See chapter 3 GRAPHICS for more information)
- which will be used to render the gadget. (If
- you supply a pointer to an Image structure
- you need to set the Flags variable to
- GADGIMAGE.) Set it to NULL if you do not
- want to supply the gadget with any graphics.
-
- SelectRender: A pointer to an alternative Image or Border
- structure which will be used when the gadget
- is highlighted. Remember to set the
- GADGHIMAGE bit in the Flags variable if you
- want to use an alternative Image/Border.
- (GadgetRender and SelectRender must point to
- the same type of data. If you have specified
- that you want to use an Image for the
- GadgetRender (GADGIMAGE), SelectRender must
- then also point to an Image structure.)
-
- GadgetText: A pointer to an IntuiText structure (See
- chapter 3 GRAPHICS for more information)
- which will be used to print some text in the
- gadget. Set it to NULL if you do not want
- any text connected to your gadget.
-
- MutualExclude: This field represent the first 32 gadgets
- in the list. If this gadget is selected,
- all specified gadgets in the MutualExclude
- field are deselected automatically. For
- example, if you want that gadget number 0,
- 2, 5 and 8 should be deselected (mutual
- excluded) when this gadget is selected, the
- MutualExclude field should be set to 293.
- ( 293(d) == 100100101(b) )
-
- Remember, the mutual exclude works only with
- toggle-select gadgets.
-
- SpecialInfo: If the gadget is a Proportional gadget you
- should here give Intuition a pointer to a
- PropInfo structure, or if the gadget is a
- String (Integer) gadget you should give
- Intuition a pointer to a StringInfo
- structure.
-
- If the gadget is a Boolean gadget you can
- connect a BoolInfo structure which will
- place a mask on the gadget's select box.
- (See below for more information.)
-
- GadgetID This variable is left for your own use.
- Intuition ignores this field.
-
- UserData: A pointer to any structure you may want
- to connect to the gadget. Intuition ignores
- this field.
-
-
-
- 4.5 BOOLEAN GADGET
-
- If you want a Boolean gadget you should declare and initialize
- the Gadget structure something like this:
-
- struct my_gadget=
- {
- NULL, /* NextGadget, no more gadgets in the list. */
- 40, /* LeftEdge, 40 pixels out. */
- 20, /* TopEdge, 20 lines down. */
- 60, /* Width, 60 pixels wide. */
- 20, /* Height, 20 pixels lines high. */
- GADGHCOMP, /* Flags, when this gadget is highlighted, */
- /* the gadget will be rendered in the */
- /* complement colours: */
- /* (Colour 0 (00) will become colour 3 (11) */
- /* (Colour 1 (01) - " - 2 (10) */
- /* (Colour 2 (10) - " - 1 (01) */
- /* (Colour 3 (11) - " - 0 (00) */
- GADGIMMEDIATE| /* Activation, our program will receive a */
- RELVERIFY, /* message when the user has selected this */
- /* gadget, and when the user has released */
- /* it. */
- BOOLGADGET, /* GadgetType, a Boolean gadget. */
- &my_border, /* GadgetRender, a pointer to our Border */
- /* structure. */
- NULL, /* SelectRender, NULL since we do not */
- /* supply the gadget with an alternative */
- /* image. (We complement the colours */
- /* instead.) */
- &my_text, /* GadgetText, a pointer to our IntuiText */
- /* structure. */
- NULL, /* MutualExclude, no mutual exclude. */
- NULL, /* SpecialInfo, no BoolInfo connected to it. */
- 0, /* GadgetID, no id. */
- NULL /* UserData, no user data connected to the */
- /* gadget. */
- };
-
-
- It is possible to connect a mask to a Boolean gadget. In that
- case the gadget would only be selected when the user clicks
- inside the selected (masked) area, and only that area would be
- highlighted. If you want to connect a mask to a Boolean gadget
- you need to declare and initialize a BoolInfo structure
- together with its mask.
-
- The BoolInfo structure looks like this:
-
- struct BoolInfo
- {
- USHORT Flags;
- UWORD *Mask;
- ULONG Reserved;
- };
-
- Flags: There exists only one flag for the moment: BOOLMASK.
-
- Mask: Pointer to the binary mask. (The width and height of
- the mask must be the same as the width and height of
- the select box.)
-
- Reserved: This field is reserved and should therefore be set
- to 0.
-
-
- The binary mask is built up as an Image plane. Only the
- selected (1's) parts of the mask will be sensitive and
- highlighted.
-
- A mask for a gadget with the width of 16 pixels, and the height
- of 8 pixels can look something like this: (Only the inner part
- of the select box will be sensitive and highlighted.)
-
- Mask 16-Bit memory words Hexadecimal
- ------------------------------------------------------
-
- 0000001111000000 0000 0011 1100 0000 03C0
- 0000111111110000 0000 1111 1111 0000 0FF0
- 0011111111111100 0011 1111 1111 1100 3FFC
- 1111111111111111 1111 1111 1111 1111 FFFF
- 1111111111111111 1111 1111 1111 1111 FFFF
- 0011111111111100 0011 1111 1111 1100 3FFC
- 0000111111110000 0000 1111 1111 0000 0FF0
- 0000001111000000 0000 0011 1100 0000 03C0
-
-
- The mask would in this case be declared/initialized like this:
-
- UWORD my_mask[]=
- {
- 0x03C0,
- 0x0FF0,
- 0x3FFC,
- 0xFFFF,
- 0xFFFF,
- 0x3FFC,
- 0x0FF0,
- 0x03C0
- };
-
- See Example6 for more information about the BoolInfo structure.
-
-
-
- 4.6 STRING/INTEGER GADGET
-
- String and Integer gadgets are a bit more complicated to
- declare since you need to supply the Gadget structure with a
- StringInfo structure. However, String and Integer gadgets
- allow the user to enter a string or an integer value without
- much effort from your side. Intuition takes care of most of the
- work, and you almost only need to decide how long and where the
- string gadget should be.
-
-
-
- 4.6.1 STRINGINFO STRUCTURE
-
- The StringInfo structure look like this:
-
- struct StringInfo
- {
- UBYTE *Buffer;
- UBYTE *UndoBuffer;
- SHORT BufferPosition;
- SHORT MaxChars;
- SHORT DispPos;
- SHORT UndoPos;
- SHORT NumChars;
- SHORT DispCount;
- SHORT CLeft, CTop;
- struct Layer *LayerPtr;
- LONG LongInt;
- struct KeyMap *AltKeyMap;
- };
-
- Buffer: A pointer to a NULL-terminated string.
-
- UndoBuffer: A pointer to a NULL-terminated string which
- is used by Intuition to store an undo string.
- This must be at least as long as the Buffer
- string. When the user selects this gadget
- Intuition makes a copy of the Buffer string
- which will be copied back if the user
- presses AMIGA + Q. Since only one String/
- Integer gadget can be active at a time
- several String/Integer gadgets can use the
- same undo string.
-
- MaxChars: The maximum number of characters which may
- be entered. (Number of characters in the
- buffer + the NULL '\0' sign.)
-
- BufferPos: Cursor position in the buffer string.
-
- DispPos: Position of the first character which is
- displayed.
-
- These variables are initialized and maintained by Intuition:
-
- UndoPos: Cursor position in the undo string.
-
- NumChars: Current number of characters in the buffer.
-
- DispCount: Current number of visible characters in the
- container.
-
- CLeft, CTop: Top left offset of the container.
-
- LayerPtr: Pointer to the Layer structures.
-
- LongInt: If this is an Integer gadget you can examine
- the value here to find out what the user has
- entered.
-
- AltKeyMap: A pointer to an alternative keymap.
- (Remember to set the flag ALTKEYMAP in the
- Activation field.)
-
-
-
- 4.6.2 INITIALIZE A STRING/INTEGER GADGET
-
- This is an example of how you can initialize a string gadget:
-
- UBYTE my_buffer[50];
- UBYTE my_undo_buffer[50];
-
- struct StringInfo my_string_info=
- {
- my_buffer, /* Buffer, pointer to a NULL-terminated s. */
- my_undo_buffer, /* UndoBuffer, pointer to a NULL- */
- /* terminated string. (Remember my_buffer */
- /* is equal to &my_buffer[0]) */
- 0, /* BufferPos, initial position of the */
- /* cursor. */
- 50, /* MaxChars, 49 characters + NULL-sign. */
- 0, /* DispPos, first character in the string */
- /* should be first character in the */
- /* display. */
-
- /* Intuition initializes and maintains these variables: */
-
- 0, /* UndoPos */
- 0, /* NumChars */
- 0, /* DispCount */
- 0, 0, /* CLeft, CTop */
- NULL, /* LayerPtr */
- NULL, /* LongInt */
- NULL, /* AltKeyMap */
- };
-
- struct Gadget my_gadget=
- {
- NULL, /* NextGadget, no more gadgets in the list. */
- 68, /* LeftEdge, 68 pixels out. */
- 30, /* TopEdge, 30 lines down. */
- 198, /* Width, 198 pixels wide. */
- 8, /* Height, 8 pixels lines high. */
- GADGHCOMP, /* Flags, draw the select box in the */
- /* complement colours. Note: it is actually */
- /* only the cursor which will be drawn in */
- /* the complement colours (yellow). If you */
- /* set the flag GADGHNONE the cursor will */
- /* not be highlighted, and the user will */
- /* therefore not be able to see it. */
- GADGIMMEDIATE| /* Activation, our program will receive a */
- RELVERIFY, /* message when the user has selected this */
- /* gadget, and when the user has released */
- /* it. */
- STRGADGET, /* GadgetType, a String gadget. */
- &my_border, /* GadgetRender, a pointer to our Border */
- /* structure. */
- NULL, /* SelectRender, NULL since we do not */
- /* supply the gadget with an alternative */
- /* image. */
- &my_text, /* GadgetText, a pointer to our IntuiText */
- /* structure. */
- NULL, /* MutualExclude, no mutual exclude. */
- &my_string_info,/* SpecialInfo, a pointer to a StringInfo */
- /* structure. */
- 0, /* GadgetID, no id. */
- NULL /* UserData, no user data connected to the */
- /* gadget. */
- };
-
- The only difference between declaring and initializing a String
- gadget and an Integer gadget, is that when you initialize an
- Integer gadget you also need to:
-
- 1. Set the flag LONGINT in the Activation field.
- 2. Copy an integer string into the buffer string.
- eg: strcpy( my_buffer, "0" );
-
-
-
- 4.6.3 USING A STRING/INTEGER GADGET
-
- Once you have declared and initialized the appropriate
- structures Intuition takes care of everything else. While the
- user is entering a string he/she can even use some special
- keys:
-
- ------------------------------------------------------------
- | <- Moves the cursor to the left. |
- | -> Moves the cursor to the right. |
- | SHIFT and <- Moves the cursor to the beginning of the |
- | string. |
- | SHIFT and -> Moves the cursor to the end of the string. |
- | BACKSPACE Deletes the character to the left of the |
- | cursor. |
- | DEL Deletes the character under the cursor. |
- | AMIGA and Q Undo the last changes of the string. |
- | AMIGA and X Clears the buffer string. |
- | RETURN Releases the gadget. If we have set the |
- | activation flag RELVERIFY we will receive |
- | a message telling us that the user has |
- | finished. |
- ------------------------------------------------------------
-
-
-
- 4.7 PROPORTIONAL GADGET
-
- A proportional gadget is roughly a knob which can be moved
- horizontally, vertically or both inside a container. It can be
- like a volume control on a radio, or it can be used to show the
- user how much more data there exist in the file etc.
-
-
-
- 4.7.1 PROPINFO STRUCTURE
-
- The PropInfo structure look like this:
-
- struct PropInfo
- {
- USHORT Flags;
- USHORT HorizPot;
- USHORT VertPot;
- USHORT HorizBody;
- USHORT VertBody;
- USHORT CWidth;
- USHORT CHeight;
- USHORT HPotRes, VPotRes;
- USHORT LeftBorder;
- USHORT TopBorder;
- };
-
- Flags: You normally should set one or both of the
- following two bits:
-
- FREEHORIZ Set this bit if you want the
- user to be able to move the
- knob horizontally.
-
- FREEVERT Set this bit if you want the
- user to be able to move the
- knob vertically.
-
- AUTOKNOB Set this bit if you want that
- the size of the knob to be
- controlled by Intuition.
- (HorizBody and VertBody
- affects the size of the
- Autoknob.)
-
- - If you want to use
- Intuition's Autoknob you
- should give GadgetRender a
- pointer to an Image structure.
- (You do not need to initialize
- the Image structure since
- Intuition takes care of it.)
-
- - If you on the other hand
- would like to use your own
- knob image, you give
- GadgetRender a pointer to your
- Image structure, which you have
- initialized yourself.
-
- PROPBORDERLESS Set this bit if you do not
- want any border around the
- container.
-
- KNOBHIT This is a flag which is set by
- Intuition if this gadget is
- selected.
-
- HorizPot: This variable contains the actual
- (horizontally) proportional value. If the
- user has moved the knob 25% to the right,
- HorizPot is 25% of MAXPOT (0xFFFF).
- (0xFFFF * 0.25 = 0x3FFF)
-
- VertPot: Same as HorizPot except that this is the
- vertically proportional value.
-
- HorizBody: Describes how much HorizPot should change
- every time the user clicks inside the
- container. If the volume of a melody can be
- between 0-63 (64 steps), HorizPot should
- change 1/64 each time. The HorizBody should
- therefore be initialized to:
- 1/64 * MAXBODY (0xFFFF) == 3FF
-
- HorizBody describes also how much the user
- can see/use of the entire data. For example,
- if you have a list of 32 file names, and the
- user only can see 8 names at one time (25%),
- the knob (AUTOKNOB) should fill 25% of the
- container. HorizBody should in this case be
- initialized to:
- MAXBODY * 8 / 32 (25% of 0xFFFF) == 3FFFF
-
- VertBody: Same as HorizBody except that it affects
- VertPot, and the vertical size of the knob
- (AUTOKNOB).
-
- These variables are initialized and maintained by Intuition:
-
- CWidth: Width of the container.
-
- CHeight: Height of the container.
-
- HPotRes, VPotRes: Pot increments.
-
- LeftBorder: Position of the container's left border.
-
- TopBorder: Position of the container's top border.
-
-
-
- 4.7.2 INITIALIZE A PROPORTIONAL GADGET
-
- This is an example of how you can initialize a proportional
- gadget which can, for example, be used to change the volume of
- a melody (64 positions):
-
- /* We need to declare an Image structure for the knob, but */
- /* since Intuition will take care of the size etc of the */
- /* knob, we do not need to initialize the Image structure: */
- struct Image my_image;
-
- struct PropInfo my_prop_info=
- {
- FREEHORIZ| /* Flags, the knob should be moved */
- AUTOKNOB, /* horizontally, and Intuition should take */
- /* care of the knob image. */
- 0, /* HorizPot, start position of the knob. */
- 0, /* VertPot, 0 since we will not move the */
- /* knob vertically. */
- MAXBODY * 1/64, /* HorizBody, 64 steps. */
- 0, /* VertBody, 0 since we will not move the */
- /* knob vertically. */
-
- /* These variables are initialized and maintained by */
- /* Intuition: */
-
- 0, /* CWidth */
- 0, /* CHeight */
- 0, 0, /* HPotRes, VPotRes */
- 0, /* LeftBorder */
- 0 /* TopBorder */
- };
-
- struct Gadget my_gadget=
- {
- NULL, /* NextGadget, no more gadgets. */
- 80, /* LeftEdge, 80 pixels out. */
- 30, /* TopEdge, 30 lines down. */
- 200, /* Width, 200 pixels wide. */
- 12, /* Height, 12 pixels lines high. */
- GADGHCOMP, /* Flags, no highlighting. */
- GADGIMMEDIATE| /* Activation, our program will receive a */
- RELVERIFY, /* message when the user has selected this */
- /* gadget, and when the user has released */
- /* it. */
- PROPGADGET, /* GadgetType, a Proportional gadget. */
- &my_image, /* GadgetRender, a pointer to our Image */
- /* structure. (Intuition will take care */
- /* of the knob image. See chapter 3 */
- /* GRAPHICS for more information about */
- /* images.) */
- NULL, /* SelectRender, NULL since we do not */
- /* supply the gadget with an alternative */
- /* image. */
- &my_text, /* GadgetText, pointer to a IntuiText */
- /* structure. */
- NULL, /* MutualExclude, no mutual exclude. */
- &my_prop_info, /* SpecialInfo, pointer to a PropInfo */
- /* structure. */
- 0, /* GadgetID, no id. */
- NULL /* UserData, no user data connected to */
- /* the gadget. */
- };
-
-
-
- 4.8 MONITORING THE GADGETS
-
- Once you have decided which gadgets to use and what they should
- look like, it is time to decide what information they should
- send to your program. You need to decide if they should send a
- message when the user has selected them, or when the user has
- released them etc. All this work with handling the input can be
- easily done with help of Intuition's IDCMP system. IDCMP stands
- for Intuition's Direct Communications Message Ports system.
- Hard name but very easy to use.
-
- The IDCMP system is also explained, in more detail, in chapter
- 8 IDCMP.
-
- If you want to use the IDCMP system you only need to follow
- these steps:
-
- 1. Decide what events your gadget should report. You do it by
- setting the appropriate flags in the Activation field in the
- Gadget structure:
-
- GADGIMMEDIATE Set this flag if you want your program to
- receive a message immediately when the user
- selects this gadget.
-
- RELVERIFY Set this flag if you want your program to
- receive a message when the user releases
- (while still pointing at it) this gadget. If
- the user releases the gadget after having
- moved the pointer away from the select box,
- your program will not receive any message.
-
- FOLLOWMOUSE Set this flag if you want your program to
- receive a message every time the mouse is
- moved while this gadget is selected.
-
-
- 2. If the gadgets are connected to a window you need to tell
- Intuition which messages should be sent to your program. You
- do it by setting the appropriate flags in the IDCMPFlags
- field in the NewWindow structure:
-
- GADGETDOWN If a gadget connected to a window has the
- GADGIMMEDIATE flag set, you should set the
- GADGETDOWN flag.
-
- GADGETUP If a gadget connected to a window has the
- RELVERIFY flag set, you should set the
- GADGETUP flag.
-
- MOUSEMOVE If a gadget connected to a window has the
- FOLLOWMOUSE flag set, you should set the
- MOUSEMOVE flag.
-
- CLOSEWINDOW If you have connected the Close window gadget
- (System gadget) to your window, you can set
- this bit, and your program will receive a
- message when the user selects this gadget.
- Remember, Intuition does not close the window
- automatically when the user clicks on the
- Close window gadget. It is up to your program
- to decide what to do when you receive a
- CLOSEWINDOW event. (See Example1)
-
-
- 3. Once your program is running it is time to try to collect
- and examine the messages sent to us by Intuition. One very
- commonly used way of doing it is to put the program to sleep
- [ Wait() ] and it will wake first when a message has
- arrived. We will then try to collect it [ GetMsg() ], and
- then (if success) examine the message. When we are finished
- with it we send it back [ ReplyMsg() ] so Intuition can send
- us another message if there is one. We can then put the
- program to sleep again, and so on.
-
- When we collect a message with help of the function GetMsg() we
- actually receive a pointer to an IntuiMessage structure or NULL
- if there was nothing for us. The IntuiMessage structure looks
- like this:
-
- struct IntuiMessage
- {
- struct Message ExecMessage;
- ULONG Class;
- USHORT Code;
- USHORT Qualifier;
- APTR IAddress;
- SHORT MouseX, MouseY;
- ULONG Seconds, Micros;
- struct Window *IDCMPWindow;
- struct IntuiMessage *SpecialLink;
- };
-
- This structure is fully explained in chapter 8 IDCMP, so you do
- not need to bother so much about it for the moment. However,
- there are two variables in the structure that we need to
- understand. They are:
-
- Class: When a message is sent this field contains the
- reason why it was sent. It contains an IDCMP
- flag which tells us what has happened. For
- example, if the user has selected a gadget with
- the GADGIMMEDIATE flag set, this variable is
- equal to GADGETDOWN.
-
- IAddress: This is a pointer to the gadget (or similar)
- which sent the message. For example, if a program
- receives a message telling us that a gadget was
- selected, we need to know which gadget since
- there may be several gadget connected to the same
- window. This pointer points to that gadget.
-
- Here is an example of a program which collects IDCMP messages:
-
- main()
- {
- /* Declare a variable in which we will store the IDCMP */
- /* flag: */
- ULONG class;
-
- /* Declare a pointer in which we will store the address */
- /* of the object (gadget) which sent the message: */
- APTR address;
-
- /* Declare a pointer to an IntuiMessage structure: */
- struct IntuiMessage *my_message;
-
-
- /* ... */
-
-
- /* (This is an endless loop) */
- while( TRUE )
- {
- /* 1. Put our program to sleep, and wake up first when */
- /* we have received a message. Do not bother for the */
- /* moment about all these funny thing we put inside */
- /* the Wait () function. I will talk about that later */
- /* on. */
-
- /* Wait until we have received a message: */
- Wait( 1 << my_window->UserPort->mp_SigBit );
-
-
-
- /* 2. We have now received a message and we shall now */
- /* try to collect it. If success the function GetMsg() */
- /* will return a pointer to an IntuiMessage */
- /* structure, otherwise it will return NULL. */
-
- /* Collect the message: */
- my_message = GetMsg( my_window->UserPort );
-
-
-
- /* 3. If we have collected a message successfully we save */
- /* some important values which we later can use. */
-
- if( my_message )
- {
- /* Save the code variable: */
- class = my_message->Class;
-
- /* Save the address of the gadget: */
- address = my_message->IAddress;
-
-
- /* 4. After we have saved all important values we */
- /* reply as fast as possible. Once we have replied */
- /* we can NOT use the IntuiMessage structure any */
- /* more! */
-
- ReplyMsg( my_message );
-
-
- /* 5. We can now check what message was sent to us. */
-
- /* Check which IDCMP flag was sent: */
- switch( class )
- {
- case GADGETDOWN: /* The user has selected a gadget: */
-
- /* If we want to check which gadget sent the */
- /* message we simply need to check the */
- /* address pointer: */
-
- if( address == &my_first_gadget)
- /* The gadget "my_first_gadget" selected. */
- /* Do what ever you want... */
-
- if( address == &my_second_gadget)
- /* The gadget "my_second_gadget" selected. */
- /* Do what ever you want... */
-
- break;
-
- case GADGETUP: /* The user has released a gadget: */
- /* Do what ever you want... */
- break;
-
- case MOUSEMOVE: /* The user has moved the mouse */
- /* while a gadget was selected. */
- /* Do what ever you want... */
- break;
-
- case CLOSEWINDOW: /* The user has selected the close */
- /* window gadget. Time to quit. */
- /* Do what ever you want... */
- break;
- }
- }
- }
-
-
- /* ... */
- }
-
-
-
- 4.9 FUNCTIONS
-
- Here are some commonly used functions:
-
- ActivateGadget()
-
- This function is used to activate a string or integer gadget,
- although other gadgets too can be activated (selected) with
- this function. This function can be used to make it easier
- for the user to input text or values. Since the function will
- automatically activate (select) a specified gadget can the
- user continue to keep his/her fingers on the keyboard and
- does not have to fiddle around with the mouse each time he/
- she wants to input some values.
-
- Synopsis: ActivateGadget( gadget, window, requester );
-
- gadget: (struct Gadget *) Pointer to the gadget which
- should be selected.
-
- window: (struct Window *) Pointer to the window which the
- gadget is connected to.
-
- requester: (struct Requester *) If the gadget is connected to
- a requester, set this pointer to point to that
- requester, else NULL. Important, if this gadget is
- connected to a requester, it must be displayed
- when you execute this command! (See chapter 5
- REQUESTERS for more information about requesters.)
-
-
- ActivateWindow()
-
- This function is used to activate a specified window.
-
- Synopsis: ActivateWindow( window );
-
- window: (struct Window *) Pointer to the window which
- should be activated. Note! The window must be open
- when you call the function!
-
-
- RefreshGadgets()
-
- This function redraws all the gadgets in the list, starting
- by the specified gadget. If you for example have added or
- deleted a gadget you need to call this function to see the
- changes. On the other hand, if you have changed the imagery
- of a gadget, or the gadget's image has been trashed by
- something, you can also use this function to refresh the
- display.
-
- Synopsis: RefreshGadgets( gadget, window, requester);
-
- gadget: (struct Gadget *) Pointer to the gadget where the
- redrawing should start. This gadget, and all the
- following gadgets in the list will be redrawn.
-
- window: (struct Window *) Pointer to the window which the
- gadgets are connected to.
-
- requester: (struct Requester *) If the gadget is connected to
- a requester, set this pointer to point to that
- requester, else NULL. Important, if this gadget is
- connected to a requester, it must be displayed
- when you execute this command! (See chapter 5
- REQUESTERS for more information about requesters.)
-
-
- AddGadget()
-
- This function adds a gadget to the gadget list.
-
- Synopsis: result = AddGadget( window, gadget, position );
-
- result: (long) The actual position of the gadget when it
- has been added.
-
- window: (struct Window *) Pointer to the window, to which
- the gadget should be added.
-
- gadget: (struct Gadget *) Pointer to the gadget which will
- be added.
-
- position: (long) Position in the gadget list. (Starts from
- zero). Eg:
- 0 -> Before all other gadgets.
- 1 -> After the first gadget, but before the
- second.
- If a too big value is entered (or -1), the gadget
- will be placed last in the list.
-
-
- Important, after your program has added the necessary
- gadgets, you need to call the function RefreshGadgets() in
- order to see your changes. You may add (or take away) several
- gadgets, but when you are finished you must call that
- function.
-
-
- RemoveGadget()
-
- This function removes a gadget from the list:
-
- Synopsis: result = RemoveGadget( window, gadget );
-
- result: (long) The position of the removed gadget or -1 if
- something went wrong.
-
- window: (struct Window *) Pointer to the window that the
- gadget is connected to.
-
- gadget: (struct Gadget *) Pointer to the gadget which will
- be removed.
-
-
- Important, after your program has removed the necessary
- gadgets, you need to call the function RefreshGadgets() in
- order to see your changes. You may take away (or add) several
- gadgets, but when you are finished you must call that
- function.
-
-
- OnGadget()
-
- This function enables a gadget (removes the GADGDISABLED bit
- in the gadget structure's Flags field):
-
- Synopsis: OnGadget( gadget, window, requester );
-
- gadget: (struct Gadget *) Pointer to the gadget which
- will be enabled.
-
- window: (struct Window *) Pointer to the window that the
- gadget is attached to.
-
- requester: (struct Requester *) If the gadget is connected
- to a requester, set this pointer to point to that
- requester, else NULL. Important, if this gadget
- is connected to a requester, it must be displayed
- when you execute this command!
-
- Remember, as long as the gadget is disabled the user can not
- select it, and it will not broadcast any messages. A disabled
- gadget is drawn as usual except that it "ghosted".
-
-
- OffGadget()
-
- This function disables a gadget (sets the GADGDISABLED bit in
- the gadget structure's Flags field):
-
- Synopsis: OffGadget( gadget, window, requester );
-
- gadget: (struct Gadget *) Pointer to the gadget which will
- be disabled.
-
- window: (struct Window *) Pointer to the window that the
- gadget is attached to.
-
- requester: (struct Requester *) If the gadget is connected to
- a requester, set this pointer to point to that
- requester, else NULL. Important, if this gadget is
- connected to a requester, it must be displayed
- when you execute this command!
-
-
- ModifyProp()
-
- This function modifies a proportional gadget's values and
- knob. For example, if your program is reading files from the
- disk, VertBody was maybe equal to 0xFFFF (MAXBODY) in the
- beginning, but as more files are collected from the disk, you
- maybe want to change the size of the knob etc. You then
- simply call this function and it will change the values as
- well as redraw the gadget.
-
- Synopsis: ModifyProp( gadget, window, requester, flags,
- horiz_pot, vert_pot, horiz_body, vert_body );
-
- gadget: (struct Gadget *) Pointer to the proportional
- gadget which should be changed and redrawn.
-
- window: (struct Window *) Pointer to the window which
- the proportional gadget is connected to.
-
- requester: (struct Requester *) If the gadget is connected
- to a requester, set this pointer to point to
- that requester, else NULL. Important, if this
- gadget is connected to a requester, it must be
- displayed when you execute this command!
-
- flags: (long) Here is the list of all flags you may
- use:
-
- FREEHORIZ Set this bit if you want the
- user to be able to move the
- knob horizontally.
-
- FREEVERT Set this bit if you want the
- user to be able to move the
- knob vertically.
-
- AUTOKNOB Set this bit if you want that
- the size of the knob to be
- controlled by Intuition.
- (HorizBody and VertBody
- affects the size of the
- Autoknob.)
-
- - If you want to use
- Intuition's Autoknob you
- should give GadgetRender a
- pointer to an Image structure.
- (You do not need to initialize
- the Image structure since
- Intuition takes care of it.)
-
- - If you on the other hand
- would like to use your own
- knob image, you give
- GadgetRender a pointer to your
- Image structure, which you have
- initialized yourself.
-
- PROPBORDERLESS Set this bit if you do not
- want any border around the
- container.
-
- (See chapter 4.7 for more information.)
-
- horiz_pot: (long) This variable contains the actual
- (horizontally) proportional value. If the knob
- should be moved 25% to the right, HorizPot
- should be set to 25% of MAXPOT (0xFFFF).
- (0xFFFF * 0.25 = 0x3FFF)
-
- vert_pot: (long) Same as HorizPot except that this is the
- vertically proportional value.
-
- horiz_body: (long) Describes how much HorizPot should change
- every time the user clicks inside the container.
- If the volume of a melody can be between 0-63
- (64 steps), HorizPot should change 1/64 each
- time. The HorizBody should therefore be set to:
- 1/64 * MAXBODY (0xFFFF) == 3FF
-
- HorizBody describes also how much the user can
- see/use of the entire data. For example, if you
- have a list of 32 file names, and the user only
- can see 8 names at one time (25%), the knob
- (AUTOKNOB) should fill 25% of the container.
- HorizBody should in this case be set to:
- MAXBODY * 8 / 32 (25% of 0xFFFF) == 3FFFF
-
-
- vert_body: Same as HorizBody except that it affects
- VertPot, and the vertical size of the knob
- (AUTOKNOB).
-
-
- 4.10 EXAMPLES
-
- Example 1
- This program will open a normal window which is connected to
- the Workbench Screen. The window will use all System
- Gadgets, and will close first when the user has selected the
- System gadget Close window. (Same as Example3 in chapter 2
- WINDOWS, except that we have added an IDCMP check on the
- Close window gadget.)
-
- Example 2
- Same as Example 1 except that we have added a Boolean gadget
- with the text "PRESS ME".
-
- Example 3
- Same as Example 2 except that the on/off state of the gadget
- is toggled each time the user hits the gadget.
-
- Example 4
- This program will open a normal window which is connected to
- the Workbench Screen. The window will use all System
- Gadgets, and will close first when the user has selected
- the System gadget Close window. Inside the window we have put
- two Boolean gadgets with the text "GADGET 1" and "GADGET 2".
-
- Example 5
- This program will open a normal window which is connected to
- the Workbench Screen. The window will use all System Gadgets,
- and will close first when the user has selected the System
- gadget Close window. Inside the window we have put a Boolean
- gadget with two Image structures connected to it. Each time
- the user clicks on the gadget it will change images, lamp
- on/lamp off.
-
- Example 6
- This program will open a normal window which is connected
- to the Workbench Screen. The window will use all System
- Gadgets, and will close first when the user has selected the
- System gadget Close window. Inside the window we have put a
- Boolean gadget with a connecting mask. The gadget will only
- be highlighted when the user selects this gadget while
- pointing inside the specified (masked) area.
-
- Example 7
- This program will open a normal window which is connected to
- the Workbench Screen. The window will use all System
- Gadgets, and will close first when the user has selected the
- System gadget Close window. Inside the window we have put a
- String gadget.
-
- Example 8
- Same as Example 7 except that it is an Integer gadget.
-
- Example 9
- Same as Example 7 except that it is a Proportional gadget.
-
- Example 10
- Same as Example 9 except that the Proportional gadget uses a
- custom image knob.
-
- Example 11
- This program will open a normal window which is connected to
- the Workbench Screen. The window will use all System
- Gadgets, and will close first when the user has selected the
- System gadget Close window. Inside the window we have put a
- Proportional gadget where the knob can be moved both
- horizontally and vertically.
-
- Example 12
- This program will open a SuperBitmap window which is
- connected to the Workbench Screen. The window will use all
- System Gadgets, and will close first when the user has
- selected the System gadget Close window. Inside the window we
- have put two Proportional gadgets, one on the right side, and
- one at the bottom. With help of these two gadgets, the user
- can move around the BitMap.
-
- This example is for experienced programmers only, since it
- uses some functions etc which we have not discussed yet. I
- have, however, included it here since it is a good example on
- how you can combine Proportional gadgets with SuperBitmap
- windows.
-
- Example 13
- This example demonstrates how to use six string gadgets which
- are automatically activated (selected) when the user release
- the gadget above.
-