home *** CD-ROM | disk | FTP | other *** search
- (c) Copyright 1989-1999 Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice, and
- is provided "as is" without warranty of any kind, either expressed or implied.
- The entire risk as to the use of this information is assumed by the user.
-
-
-
-
- Disabled Render - How to Supply an Alternate
- Image for a Gadget Which Is Disabled
-
- Adam Keith Levin
- Commodore-Amiga Technical Support
-
-
-
-
- Intuition allows boolean gadgets to be rendered in many different ways -
- as plain text, as a simple line drawing or even as a custom bit mapped image.
- Intuition also provides several ways to show when a boolean gadget has been
- selected by the user. Its rendering can be changed by complementing the
- colors, drawing a box around the gadget, replacing the border or image with
- a different border or image or by no change at all.
-
- However, Intuition provides only one method for showing when a gadget is
- disabled and that is by ghosting. A gadget which is disabled is temporarily
- not available for use. Intuition indicates this by ghosting the gadget's
- image. Ghosting is accomplished by overlaying a fine grid of pixels onto
- the gadget. This makes the image look "fuzzy". When a disabled gadget is
- subsequently enabled, the ghosting is removed and the gadget is again
- available for use.
-
- The program listed below shows an alternate method for indicating when a
- boolean gadget is disabled. You can use this program to provide a whole new
- custom image for the disabled gadget instead of using the ghosting feature
- of Intuition.
-
- The ghosting feature of Intuition is provided through two routines OffGadget
- and OnGadget. The program below provides two new routines, myOffGadget and
- myOnGadget. Use these carefully. They are not meant to be replacements for
- OffGadget and OnGadget as they are not set up to handle more than one gadget
- at a time. They also work only with boolean gadgets.
-
- The routine myOffGadget will cause the given gadget to stop generating both
- GADGETDOWN and GADGETUP events just as OffGadget will, but by a different
- method. The myOffGadget routine does not set the GADGDISABLED flag in the
- Flags field like OffGadget does. This means that if your application is
- handling the disabling of multiple gadgets and you have used myOffGadget
- then you cannot check the status of the gadget by looking at the Flags field
- as you normally would.
-
- Instead, you can look at the UserData field of the gadget. The myOffGadget
- routine must save a copy of the old GadgetRender and SelectRender pointers
- and 2 IDCMP flags since it changes these and must restore them later. To
- do this a pointer to a structure containing this information is placed in
- the gadget's UserData field. So, if the UserData field is not NULL then
- myOffGadget has been called and the gadget is disabled - the UserData field
- contains a pointer to the information needed to re-enable the gadget.
- If the UserData field is NULL, myOffGadget has not been called and the gadget
- is enabled.
-
- The example below handles the disabled rendering of image gadgets, not text
- or border gadgets. However, the method used is extensible to rendering these
- other forms as well. The example also assumes that boolean gadgets of fixed
- size are used as opposed to those which use GRELWIDTH, GRELHEIGHT, etc.
-
- If the disabled rendering does not completely cover the original imagery,
- some of the original gadget will still be visible. The example code
- defines the disabled rendering as slightly larger than the gadget rendering,
- so this is not a problem. For more details on how the program works, see
- the comments in the code.
-
- Even though Intuition only provides one method for indicating to the user
- that a gadget is disabled, it is not difficult to extend Intuition to provide
- an alternative method. The DisabledRender program shows you how.
-
-
- ------------------- Lauren, code starts here -----------------------
-
- /*
-
- DisabledRender
-
- A method for supplying a boolean gadget with alternate
- (ie non-ghosted) imagery when it is disabled.
-
- Adam Keith Levin Commodore-Amiga Technical Support
-
- Created with Manx's Aztec C v3.6a
- For Manx, Compile with: cc DisabledRender.c +L
- and Link with: ln DisabledRender.o -lc32
-
-
-
- O V E R V I E W
-
- A window with three boolean gadgets is created.
- Two of the gadgets ("gadget1" and "gadget2") do nothing, but
- have both gadget and select imagery. The third gadget ("control")
- alternately disables and enables the other two gadgets.
-
- Gadget1 is disabled and enabled normally, using OffGadget() and OnGadget().
- Gadget2 is disabled by
- 1. Removing it from the gadget list.
- 2. Setting its GadgetRender and SelectRender fields to point
- at a third "DisabledRender" Image structure.
- 3. Clearing the GADGIMMEDIATE and RELVERIFY bits in its
- Activation flags field to prevent GADGETDOWN/GADGETUP events.
- 4. Saving the displaced information from steps 2 and 3 in a
- special SavedGadgetData structure.
- 5. Adding the gadget to the gadget list in its previous position.
- 6. Calling RefreshGadgets() to display the "disabled" image.
-
- Gadget2 is enabled by
- 1. Removing it from the gadget list.
- 2. Restoring its previous GadgetRender and SelectRender fields.
- 3. Restoring the previous GADGIMMEDIATE and RELVERIFY bits in its
- Activation flags field. (The information for steps 2 and 3
- is retrieved from the SavedGadgetData structure).
- 4. Adding it to the gadget list in its previous position.
- 5. Calling RefreshGadgets() to display the gadget image.
-
- Messages announcing gadget events are written
- to the window via the console device.
-
- */
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuitionbase.h>
- #include <libraries/dos.h>
- #include <stdio.h>
-
- struct IntuitionBase *IntuitionBase;
-
-
- /* Image data for normal rendering of gadget1 and gadget2. */
- USHORT newGadgetRenderData[] =
- {
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0007,0xFF80,0x0007,0xFF80,
- 0x0007,0xFF80,0x0007,0xFF80,0x0007,0xFF80,0x0007,0xFF80,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0001,0xFE60,0x0001,0xFE60,0x0001,0xFE60,0x0001,0xFE60,
- 0x0000,0x0060,0x0001,0xFFE0
- };
-
- /* Image data for select rendering of gadget1 and gadget2. */
- USHORT newSelectRenderData[] =
- {
- 0xFFFF,0xFF80,0xFFFF,0xFF80,0xFFFF,0xFF80,0xFFFF,0xFF80,
- 0xFFFF,0xFF80,0xFFFF,0xFF80,0xFFFF,0xFF80,0xFFFF,0xFF80,
- 0xFFFF,0xFF80,0xFFFF,0xFF80,0xFFFF,0xFF80,0xFFFF,0xFF80,
- 0x0000,0x0000,0x0000,0x0000,0x3FFF,0xFE60,0x3FFF,0xFE60,
- 0x3FFF,0xFE60,0x3FFF,0xFE60,0x3FFF,0xFE60,0x3FFF,0xFE60,
- 0x3FFF,0xFE60,0x3FFF,0xFE60,0x3FFF,0xFE60,0x3FFF,0xFE60,
- 0x0000,0x0060,0x3FFF,0xFFE0
- };
-
- /* Image data for disabled rendering of gadget2. */
- USHORT newDisabledRenderData[] =
- {
- 0x03FF,0x0000,0x1E01,0xE000,0x7380,0x3800,0xC0E0,0x0C00,
- 0xC038,0x0C00,0xC00E,0x0C00,0x7003,0xB800,0x1E01,0xE000,
- 0x03FF,0x0000,0x03FF,0x03FF,0x1E01,0xE3FF,0x7380,0x3BFF,
- 0xC0E0,0x0FFF,0xC038,0x0FFF,0xC00E,0x0FFF,0x7003,0xBBFF,
- 0x1E01,0xE3FF,0x03FF,0x03FF
- };
-
-
- /*
- Make the default RenderData the newRenderData arrays.
- If they are in chip RAM, they will be used as they are;
- if in fast RAM, they will be copied to chip RAM by chipImage().
- */
- USHORT *gadgetRenderData = (USHORT *) &newGadgetRenderData,
- *selectRenderData = (USHORT *) &newSelectRenderData,
- *disabledRenderData = (USHORT *) &newDisabledRenderData;
-
-
- /* The ImageData fields will be filled by prepImage()
- once a chip RAM pointer is obtained from chipImage().
- */
- struct Image gadgetRender = {0,0,27,13,2,NULL,0x0003,0x0000,NULL},
- selectRender = {0,0,27,13,2,NULL,0x0003,0x0000,NULL},
- disabledRender = {5,4,22,9,2,NULL,0x0003,0x0000,NULL};
-
-
- /* Imagery for the control gadget. */
- SHORT vertices[] = { 0,0,75,0,75,12,0,12,0,0 };
- struct Border border = { -1,-1,3,0,JAM1,5,vertices,NULL };
- struct IntuiText intuiText = { 3,0,JAM2,8,2,NULL,(UBYTE *)"CONTROL",NULL };
-
-
- /* Constants for GadgetID. */
- #define GADGET1 0
- #define GADGET2 1
- #define CONTROL 2
-
- struct Gadget control =
- {
- NULL,
- 129,38,
- 74,11,
- NULL,
- RELVERIFY|TOGGLESELECT,
- BOOLGADGET,
- (APTR)&border,
- NULL,
- &intuiText,
- NULL,
- NULL,
- CONTROL,
- NULL
- };
-
- struct Gadget gadget2 =
- {
- &control,
- 178,18,
- 27,13,
- GADGHIMAGE|GADGIMAGE,
- RELVERIFY,
- BOOLGADGET,
- (APTR)&gadgetRender,
- (APTR)&selectRender,
- NULL,
- NULL,
- NULL,
- GADGET2,
- NULL
- };
-
- struct Gadget gadget1 =
- {
- &gadget2,
- 128,18,
- 27,13,
- GADGHIMAGE|GADGIMAGE,
- RELVERIFY,
- BOOLGADGET,
- (APTR)&gadgetRender,
- (APTR)&selectRender,
- NULL,
- NULL,
- NULL,
- GADGET1,
- NULL
- };
-
-
- /* The return value from OpenDevice() is used to
- tell whether the console.device was opened or not.
- */
- LONG consoleOpen = 1L;
-
- struct IOStdReq *console;
- struct MsgPort *msgPort;
- struct Window *window;
- struct NewWindow newWindow =
- {
- 148,47,
- 340,105,
- 0,1,
- GADGETUP|CLOSEWINDOW,
- WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|ACTIVATE|NOCAREREFRESH,
- NULL, /* The gadget list will be attached later. */
- NULL,
- (UBYTE *)"DisabledRender",
- NULL,
- NULL,
- 5,5,
- -1,-1,
- WBENCHSCREEN
- };
-
-
- /* Anchor for AllocRemember. */
- struct Remember *remember = NULL;
-
- /* Console control sequence characters to set top offset
- of text and to turn window cursor off.
- */
- char conPrep[] =
- {
- 0x9b, 0x35, 0x35, 0x79, 0x9b, 0x30, 0x20, 0x70, 0x00
- };
-
- /* Indication of where this program started from. */
- BOOL fromCLI = FALSE;
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- BOOL windowOpen=TRUE; /* FALSE once user has clicked close gadget. */
- ULONG class; /* IntuiMessage Class. */
- APTR iAddress; /* IntuiMessage IAddress. */
- struct IntuiMessage *intuiMessage;
- BOOL prepImage();
- void cPrint(), doGadget(), cleanExit();
-
-
- /* If started from CLI, set global variable to TRUE. */
- if (argc) fromCLI = TRUE;
-
- IntuitionBase =
- (struct IntuitionBase *) OpenLibrary("intuition.library", 0L);
-
- if (IntuitionBase == NULL)
- cleanExit("\nUnable to open \"intuition.library\".\n",
- ERROR_INVALID_RESIDENT_LIBRARY);
-
- /* Ensure that gadget imagery is in chip RAM. */
- if (prepImage() != TRUE)
- cleanExit("\nInsufficent chip RAM for gadget imagery.\n",
- ERROR_NO_FREE_STORE);
-
- window = (struct Window *) OpenWindow(&newWindow);
- if (window == NULL)
- cleanExit("\nUnable to open a window.\n", RETURN_FAIL);
-
- msgPort = (struct MsgPort *) CreatePort("DisabledRender", 0L);
- if (msgPort == NULL)
- cleanExit("\nUnable to create a message port.\n", RETURN_FAIL);
-
- console = (struct IOStdReq *) CreateStdIO(msgPort);
- if (console == NULL)
- cleanExit("\nUnable to create a standard I/O requester.\n",
- RETURN_FAIL);
-
- console->io_Data = (APTR) window;
- console->io_Length = (LONG) sizeof(*window);
-
- consoleOpen = OpenDevice("console.device", 0L, console, 0L);
- if (consoleOpen != 0L)
- cleanExit("\nUnable to open \"console.device\".\n", RETURN_FAIL);
-
- /* Send control sequences to set top offset and invisible cursor. */
- cPrint(console, conPrep);
-
- /* Print a welcome message. */
- cPrint(console, "Gadget events are announced here.\n");
-
- /* Add the gadget list and see that it is displayed. */
- (void) AddGList(window, &gadget1, -1, -1, NULL);
- RefreshGadgets(&gadget1, window, NULL);
-
- /* Intuition event processing loop. */
- while (windowOpen)
- {
- (void) Wait(1<<window->UserPort->mp_SigBit);
- while (intuiMessage = (struct IntuiMessage *) GetMsg(window->UserPort))
- {
- class = intuiMessage->Class;
- iAddress = intuiMessage->IAddress;
- ReplyMsg(intuiMessage);
-
- switch (class)
- {
- case (CLOSEWINDOW):
- windowOpen = FALSE;
- cPrint(console, "\nCLOSEWINDOW.");
- Delay(2L * TICKS_PER_SECOND);
- break;
- case (GADGETUP):
- cPrint(console, "\nGADGETUP: ");
- doGadget(window, ((struct Gadget *)iAddress)->GadgetID);
- break;
- default:
- break;
- } /* end switch(class) */
- } /* end while(intuiMessage... */
- } /* end while(windowOpen) */
-
- cleanExit(NULL, RETURN_OK);
- }
-
-
- /* Return code from chipImage() to prepImage(). */
- #define cI_ORIG 0 /* Array was already in chip RAM. */
- #define cI_COPY 1 /* Array was copied to chip RAM. */
- #define cI_FAIL 2 /* Array could not be copied to chip RAM. */
-
- /*
- prepImage
- Ensures that the gadget imagery is in chip RAM.
- */
- BOOL
- prepImage()
- {
- /* Ensure that gadgetRenderData points to an array in chip RAM. */
- if (chipImage(&gadgetRenderData, sizeof(newGadgetRenderData)) == cI_FAIL)
- return(FALSE);
-
- /* Fill the ImageData field of the gadgetRender Image structure. */
- gadgetRender.ImageData = gadgetRenderData;
-
- if (chipImage(&selectRenderData, sizeof(newSelectRenderData)) == cI_FAIL)
- return(FALSE);
- selectRender.ImageData = selectRenderData;
-
- if (chipImage(&disabledRenderData, sizeof(newDisabledRenderData)) == cI_FAIL)
- return(FALSE);
- disabledRender.ImageData = disabledRenderData;
-
- return(TRUE);
- }
-
-
- /* chipImage
- Ensures that the array pointed to by imageData is in
- chip RAM. It creates a chip RAM copy if necessary.
- */
- int
- chipImage(imageData, sizeOfImageData)
- USHORT **imageData;
- int sizeOfImageData;
- {
- USHORT *tmpImageData;
-
- /* If it is already in CHIP RAM, return. */
- if (TypeOfMem(*imageData) & MEMF_CHIP) return(cI_ORIG);
-
- /* Otherwise create a copy in CHIP RAM and point imageData to it. */
- else
- {
- tmpImageData = (USHORT *)
- AllocRemember(&remember, sizeOfImageData, MEMF_CHIP|MEMF_PUBLIC);
-
- if (tmpImageData != NULL)
- {
- CopyMem(*imageData, tmpImageData, sizeOfImageData);
- *imageData = tmpImageData;
- return(cI_COPY);
- }
- }
- return(cI_FAIL);
- }
-
-
- /*
- doGadget
- Handles the gadget events. "Gadget1" and "gadget2" do nothing.
- "Control" alternately disables and enables gadget1 and gadget2.
- */
- void
- doGadget(window, gadgetID)
- struct Window *window;
- USHORT gadgetID;
- {
- static BOOL on=TRUE;
- void cPrint(), myOffGadget(), myOnGadget();
-
- switch (gadgetID)
- {
- case (GADGET1):
- cPrint(console, "Left gadget.");
- break;
- case (GADGET2):
- cPrint(console, "Right gadget.");
- break;
- case (CONTROL):
- cPrint(console, "Control gadget.\nLeft and right gadgets are now ");
- if (on)
- {
- /* Normal method of disabling. Image will be ghosted. */
- OffGadget(&gadget1, window, NULL);
-
- /* Alternate method of disabling. "Disabled" image
- will be displayed.
- */
- myOffGadget(&gadget2, window, NULL, &disabledRender);
-
- on = FALSE;
- cPrint(console, "disabled.");
- }
- else
- {
- /* Normal method of enabling. */
- OnGadget(&gadget1, window, NULL);
-
- /* Alternate method of enabling. */
- myOnGadget(&gadget2, window, NULL);
-
- on = TRUE;
- cPrint(console, "enabled.");
- }
- break;
- default:
- cPrint(console, "Unknown gadget.");
- break;
- }
- }
-
-
- /* A mask to clear and restore the corresponding Activation flags. */
- #define GI_RV (GADGIMMEDIATE|RELVERIFY)
-
- /* A structure to hold gadget information while the gadget is disabled. */
- struct SavedGadgetData
- {
- USHORT Activation;
- APTR gadgetRender;
- APTR selectRender;
- };
-
- /* Since there is only one gadget to be disabled with this example method,
- an instance of the SavedGadgetData structure is declared.
- If several gadgets will be disabled, it is advised that memory
- for each be allocated at runtime.
- */
- struct SavedGadgetData savedGadgetData;
-
-
- /* myOffGadget
- Disables a boolean gadget by clearing the GADGIMMEDIATE and RELVERIFY
- Activation flags and swaping in a third "disabled" image for
- both the gadget and select images. The removed information is saved
- in a SavedGadgetData structure which is hung off of Gadget->UserID.
- */
- void
- myOffGadget(gadget, window, requester, image)
- struct Gadget *gadget;
- struct Window *window;
- struct Requester *requester;
- struct Image *image;
- {
- USHORT position;
-
- /* Ensure that this gadget is not currently disabled by
- either the normal method or by the method in this example.
- This test should always fail, but the check is here nonetheless.
- */
- if ((gadget->Flags & GADGDISABLED) || (gadget->UserData != NULL))
- return;
-
- /* Remove the gadget so changes may be made. */
- position = RemoveGadget(window, gadget);
-
- /* Save Gadget and Select renderings. */
- savedGadgetData.gadgetRender = gadget->GadgetRender;
- savedGadgetData.selectRender = gadget->SelectRender;
-
- /* Swap in disabledRender image. */
- gadget->GadgetRender = gadget->SelectRender = image;
-
- /* Save the current GI_RV state. */
- savedGadgetData.Activation = gadget->Activation & GI_RV;
-
- /* Keep gadget from causing IDCMP messages by clearing
- both the GADGIMMEDIATE and RELVERIFY Activation Flags.
- */
- gadget->Activation &= ~GI_RV;
-
- /* Put the address of the savedGadgetData structure in the UserData
- field of the gadget, to be used when it is re-enabled.
- */
- gadget->UserData = (APTR) &savedGadgetData;
-
- (void) AddGadget(window, gadget, position);
- RefreshGadgets(gadget, window, requester);
- }
-
-
- /* myOnGadget
- Enables a gadget by restoring the GADGIMMEDIATE and RELVERIFY
- Activation flags as well as the gadget and select images.
- The information is retrieved from the SavedGadgetData structure.
- */
- void
- myOnGadget(gadget, window, requester)
- struct Gadget *gadget;
- struct Window *window;
- struct Requester *requester;
- {
- USHORT position;
-
-
- /* Ensure that this gadget was disabled. */
- if (gadget->UserData == NULL) return;
-
- position = RemoveGadget(window, gadget);
-
- /* Restore the Gadget and Select rendering. */
- gadget->GadgetRender = savedGadgetData.gadgetRender;
- gadget->SelectRender = savedGadgetData.selectRender;
-
- /* Restore the gadget's ability to cause IDCMP messages
- by restoring the previous state of the
- GADGIMMEDIATE and RELVERIFY Activation Flags.
- */
- gadget->Activation |= savedGadgetData.Activation;
-
- /* Clear the gadget's UserData field to indicate that it is enabled. */
- gadget->UserData = NULL;
-
- (void) AddGadget(window, gadget, position);
- RefreshGadgets(gadget, window, requester);
- }
-
-
- /*
- cPrint
- Sends the given (NULL terminated) string to the given console window.
- */
- void
- cPrint(ioStdReq, string)
- struct IOStdReq *ioStdReq;
- char *string;
- {
- if (*string)
- {
- ioStdReq->io_Data = (APTR) string;
- ioStdReq->io_Length = -1L;
- ioStdReq->io_Command = CMD_WRITE;
-
- (void) DoIO(ioStdReq);
- }
- }
-
-
- /* cleanExit
- Prints an exit message.
- Replys to any pending console messages, closes the console.device,
- deletes the I/O request block and the message Port.
- Replys to any pending Intuition messages, closes the window.
- Frees any allocated memory.
- Closes the Intuition library.
- Exits with an exit value.
- */
-
- void
- cleanExit(exitString, exitValue)
- char *exitString;
- int exitValue;
- {
- struct FileHandle *fileHandle;
- struct Message *message;
- struct IntuiMessage *intuiMessage;
-
- if (*exitString)
- {
- fileHandle = (struct FileHandle *)
- Open("CON:138/100/358/50/DisabledRender Message", MODE_OLDFILE);
- if (fileHandle != NULL)
- {
- (void) Write(fileHandle, exitString, strlen(exitString));
- Delay(10L * TICKS_PER_SECOND);
- Close(fileHandle);
- }
- else
- {
- if (fromCLI)
- (void) fprintf(stderr, exitString);
- }
- }
-
- if (consoleOpen == 0) CloseDevice(console);
-
- if (console) DeleteStdIO(console);
-
- if (msgPort)
- {
- while (message = (struct Message *) GetMsg(msgPort))
- ReplyMsg(message);
- DeletePort(msgPort);
- }
-
- if (window)
- {
- while (intuiMessage = (struct IntuiMessage *) GetMsg(window->UserPort))
- ReplyMsg(intuiMessage);
- CloseWindow(window);
- }
-
- if (remember) FreeRemember(&remember, TRUE);
-
- if (IntuitionBase) CloseLibrary(IntuitionBase);
-
- exit(exitValue);
- }
-
-
-
-