Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
TubeTest.c
/* |
File: TubeTest.c |
Contains: The TubeTest program is a simple demonstration of how to use the Palette |
Manager in a color program. It has a special color palette that is associated |
with the main window. The colors are animated using the Palette Manager |
to give a flowing tube effect. The program is very simple, and the Palette |
Manager and drawing parts are put in separate subroutines to make it easier |
to figure out what is happening. |
The program is still a complete Macintosh application with a Main Event Loop, |
so there is the extra code to run the MEL. |
There is a resource file that is necessary as well, to define the Menus, Window, |
Dialog, and Palette resources used in the program. |
See Sample and TESample for the general structure and MultiFinder techniques that |
we recommend that you use when building a new application. |
Written by: BJ |
Copyright: Copyright © 1988-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
08/2000 JM Carbonized, non-Carbon code is commented out |
for demonstration purposes. |
7/14/1999 KG Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include "CarbonPrefix.h" |
#include <Quickdraw.h> |
#include <Palettes.h> |
#include <Events.h> |
#include <Menus.h> |
#include <Windows.h> |
#include <Dialogs.h> |
#include <Devices.h> |
#include <Events.h> |
#include <ToolUtils.h> |
#include <Sound.h> |
#include <Gestalt.h> |
/* Constants */ |
#define appleID 1000 /* resource IDs/menu IDs for Apple, */ |
#define fileID 1001 /* File and */ |
#define editID 1002 /* Edit menus */ |
#define appleM 0 /* Index for each menu in myMenus (array of menu handles) */ |
#define fileM 1 |
#define editM 2 |
#define menuCount 3 /* Total number of menus */ |
#define windowID 1000 /* Resource ID for main window */ |
#define aboutMeDLOG 1000 /* And Resource ID for About box dialog. */ |
#define tubularItem 1 /* When checked, animation of colors. */ |
#define quitItem 3 /* Quit in the menu of course. */ |
#define aboutMeCommand 1 /* Menu item in apple menu for About TubeTest item */ |
#define totalColors 152 /* use 150 colors in our palette for drawing eyes. */ |
#define numColors 150 /* to skip black and white. */ |
/* Globals */ |
MenuHandle myMenus[menuCount]; |
Rect dragRect; /* Rectangle used to mark bounds for dragging window */ |
Boolean doneFlag, /* true if user has chosen Quit command */ |
tubeCheck; /* if true, the menu is checked, and we animate. */ |
EventRecord myEvent; |
WindowPtr myWindow, |
whichWindow; |
char theChar; |
OSErr error; |
SysEnvRec theWorld; |
/* Prototypes */ |
void DrawEyes(); |
void SetUpMenus(); |
void ShiftyColors(); |
void ShowAboutMeDialog(); |
void DoCommand(long int mResult); |
/* Make the 2.0 Interface for passing Points to the Toolbox by address, |
emulate the 3.0 method of passing Points by value. This list only contains |
the affected routines actually used in this sample, and is not intended to |
be a comprehensive list of the affected routines. */ |
#ifdef MPW2 |
# define FindWindow FINDWINDOW |
# define MenuSelect MENUSELECT |
#endif |
void main() |
{ |
/* |
** Test the computer to be sure we can do color. |
** If not we would crash, which would be bad. |
** If we canÕt run, just beep and exit. |
*/ |
/*error = SysEnvirons(1, &theWorld); |
if (theWorld.hasColorQD == false) { |
SysBeep (50); |
ExitToShell(); // If no color QD, we must leave. |
};*/ |
long result; |
BitMap bitMap; |
error = Gestalt(gestaltQuickdrawVersion, &result); |
if (result < gestalt8BitQD) { |
SysBeep (50); |
ExitToShell(); |
} |
/*InitGraf(&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
TEInit(); |
InitDialogs(nil);*/ |
InitCursor(); |
GetQDGlobalsScreenBits(&bitMap); |
//SetRect(&dragRect, 4, 24, qd.screenBits.bounds.right - 4, qd.screenBits.bounds.bottom - 4); |
SetRect(&dragRect, 4, 24, bitMap.bounds.right - 4, bitMap.bounds.bottom - 4); |
doneFlag = false; /* flag to detect when Quit command is chosen */ |
tubeCheck = false; /* flag for animating color is initially off. */ |
/* |
** Open the color window. |
*/ |
myWindow = GetNewCWindow(windowID, nil, (WindowPtr) -1); |
//SetPort(myWindow); |
SetPortWindowPort(myWindow); |
/* |
** Set up menus last, since the menu drawing can then use |
** the palette we have for our window. |
** Makes the Apple look better, in particular. |
*/ |
SetUpMenus(); |
/* |
** Main Event Loop |
*/ |
do { |
//SystemTask(); //er, what does(did) this do? |
if (GetNextEvent(everyEvent, &myEvent)) { |
switch (myEvent.what) { /* case on event type */ |
case mouseDown: |
switch (FindWindow(myEvent.where, &whichWindow)) { |
case inSysWindow: /* desk accessory window: call Desk Manager to handle it */ |
//SystemClick(&myEvent, whichWindow); |
break; |
case inMenuBar: /* Menu bar: learn which command, then execute it. */ |
DoCommand(MenuSelect(myEvent.where)); |
break; |
case inDrag: /* title bar: call Window Manager to drag */ |
DragWindow(whichWindow, myEvent.where, &dragRect); |
break; |
case inContent: /* body of application window: */ |
if (whichWindow != FrontWindow()) |
SelectWindow(whichWindow); /* and make it active if not */ |
break; |
} |
break; |
case updateEvt: /* Update the eyes in window. */ |
if ((WindowPtr) myEvent.message == myWindow) { |
BeginUpdate((WindowPtr) myEvent.message); |
DrawEyes(); |
EndUpdate((WindowPtr) myEvent.message); |
} |
break; |
case keyDown: |
case autoKey: /* key pressed once or held down to repeat */ |
if (myWindow == FrontWindow()) { |
theChar = (myEvent.message & charCodeMask); /* get the char */ |
/* |
** If Command key down, do it as a Menu Command. |
*/ |
if (myEvent.modifiers & cmdKey) |
DoCommand(MenuKey(theChar)); |
} |
break; |
} |
} |
/* |
** If we have menu item checked, go ahead and animate colors. |
*/ |
if (tubeCheck) ShiftyColors(); |
} while (!doneFlag); |
/* |
** clean up after palette manager, |
** so he can chuck the palette in use. |
*/ |
//DisposeWindow (myWindow); |
} |
/* |
** This routine will update the window when required by update events. It |
** will draw two circular dudes that are indexed in colors through the colors |
** we are using. 0 and 1 are skipped, since those are white and black in the |
** palette. |
*/ |
void DrawEyes() |
{ |
Rect tempRect; |
int i; |
SetRect(&tempRect, numColors, numColors, numColors, numColors); |
for (i = 2; i <= totalColors; i++) { |
PmForeColor(i); |
FrameOval (&tempRect); |
InsetRect (&tempRect, -1, -1); |
} |
SetRect(&tempRect, numColors*3, numColors, numColors*3, numColors); |
for (i = totalColors; i >= 2; i--) { |
PmForeColor(i); |
FrameOval (&tempRect); |
InsetRect (&tempRect, -1, -1); |
} |
} |
/* |
** Read menu descriptions from resource file into memory |
** and store handles in myMenus array. |
** Insert into MenuBar and draw. |
*/ |
void SetUpMenus() |
{ |
int i; |
myMenus[appleM] = GetMenu(appleID); /* read Apple menu from resource file */ |
AppendResMenu(myMenus[appleM], 'DRVR'); /* add desk accessory names to Apple menu */ |
myMenus[fileM] = GetMenu(fileID); /* read file menu from resource file */ |
myMenus[editM] = GetMenu(editID); /* read edit menu from resource file */ |
for (i = 0; i < menuCount; i++) |
InsertMenu(myMenus[i], 0); /* install menus in menu bar */ |
DrawMenuBar(); /* and draw menu bar */ |
} |
/* |
** Use the Palette currently attached to the main window to animate the colors |
** in the circular eye shapes. This will rotate them around to give the flowing |
** tube effect. We make the palette into a color table so we can move entries |
** around. We have to skip the first two entries since those are black and white. |
** (entries 0 and 1) |
*/ |
void ShiftyColors() |
{ |
PaletteHandle currPalette; |
CTabHandle destCTab; |
ColorSpec lastCSpec; |
//SetPort (myWindow); |
SetPortWindowPort(myWindow); |
currPalette = GetPalette(myWindow); |
destCTab = (CTabHandle) NewHandle(sizeof(ColorTable)+(totalColors*sizeof(ColorSpec))); |
if (destCTab == nil) return; |
Palette2CTab(currPalette, destCTab); |
/* |
** Move the colors around in the color table, skipping 0 and 1, and moving |
** all the elements down by one, and copying the element at 2 back to the |
** end of the table. The effect is to rotate the colors in the table. |
*/ |
lastCSpec = (*destCTab)->ctTable[2]; /* pull first one off. */ |
BlockMove (&(*destCTab)->ctTable[3], |
&(*destCTab)->ctTable[2], |
(numColors) * sizeof(ColorSpec) ); /* copy all one entry down. */ |
(*destCTab)->ctTable[totalColors-1] = lastCSpec; /* put last color back on front. */ |
AnimatePalette(myWindow, destCTab, 2, 2, numColors); |
DisposeHandle ((Handle) destCTab); |
} |
/* |
** Display the dialog box in response to the 'About TubeTest' menu item |
*/ |
void ShowAboutMeDialog() |
{ |
DialogPtr theDialog; |
short itemHit; |
theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1); |
ModalDialog(nil, &itemHit); |
DisposeDialog(theDialog); |
} |
/* |
** Execute menu command specified by mResult, |
** the result of MenuSelect |
*/ |
void DoCommand(long int mResult) |
{ |
short theItem, /* menu item number from mResult low-order word */ |
theMenu; /* menu number from mResult high-order word */ |
//Str255 name; /* desk accessory name */ |
//int temp; |
//Boolean dummy; |
theItem = LoWord(mResult); /* call Toolbox Utility routines to */ |
theMenu = HiWord(mResult); /* set menu item number and menu */ |
switch (theMenu) { /* switch on menu ID */ |
case appleID: |
if (theItem == aboutMeCommand) |
ShowAboutMeDialog(); |
else { |
/*GetMenuItemText(myMenus[appleM], theItem, name); |
temp = OpenDeskAcc(name);*/ |
//SetPort(myWindow); |
SetPortWindowPort(myWindow); |
} |
break; |
case fileID: |
if (theItem == quitItem) |
doneFlag = true; |
else if (theItem == tubularItem) { |
tubeCheck = !tubeCheck; |
//CheckItem(myMenus[fileM], tubularItem, tubeCheck); |
CheckMenuItem(myMenus[fileM], tubularItem, tubeCheck); |
} |
break; |
case editID: |
//dummy = SystemEdit(theItem - 1); /* Pass the command on to the Desk Manager. */ |
break; |
} |
HiliteMenu(0); /* Unhighlight menu title */ |
/* (highlighted by MenuSelect) */ |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-12