#include #include #include #include #include #include #include #include "tip.h" WindowPtr tipWindow; static int gDone; static bool AllowColor; static bool timerEnabled = true; static ControlHandle testBtn = 0; static ControlHandle exitBtn = 0; void NewTipWindow(); void DestroyTipWindow(); void DoEvent(EventRecord &event, RgnHandle *cursorRgn); void DoUpdate(WindowPtr window); void DoMouseDown(EventRecord &event); void DoMouseMove(EventRecord &event, RgnHandle *cursorRegion); void run_tip(int id) { CurrentDevice = id; RgnHandle cursorRgn = NewRgn(); NewTipWindow(); gDone = false; do { EventRecord event; if (WaitNextEvent(everyEvent, &event, GetCaretTime(), cursorRgn)) { DoEvent(event, &cursorRgn); } if(timerEnabled) { ApplicationTimerProc(); } } while (!gDone); DestroyTipWindow(); DisposeRgn(cursorRgn); } void NewTipWindow() { OSErr error; SysEnvRec theWorld; error = SysEnvirons(1, &theWorld); AllowColor = theWorld.hasColorQD; Rect rect = qd.screenBits.bounds; InsetRect(&rect, 50, 50); rect.bottom = rect.top + 336 - 35; rect.right = rect.left + 467; Str255 title; StrToPascal(title, szWindowTitle); tipWindow = AllowColor ? NewCWindow(NULL,&rect, title, true, 0, 0, true, 0) : NewWindow(NULL,&rect, title, true, 0, 0, true, 0); GetDC(hMainWnd); if (AllowColor) { SetColor(BACK_COLOR); RGBColor bgColor; GetForeColor(&bgColor); RGBBackColor(&bgColor); } TextSize(10); for(int i = 0; tipBtns[i].name; i++) { if (!tipBtns[i].visible) continue; SetRect(&rect, tipBtns[i].x, tipBtns[i].y, tipBtns[i].x + tipBtns[i].w, tipBtns[i].y + tipBtns[i].h ); StrToPascal(title, tipBtns[i].name); ControlHandle h = NewControl(tipWindow, &rect, title, true, 0, 0, 0, 0, tipBtns[i].id); if(tipBtns[i].id == IDB_TEST) { testBtn = h; } if(tipBtns[i].id == IDB_QUIT) { exitBtn = h; } } ReleaseDC(hMainWnd); } void DestroyTipWindow() { DisposeWindow(tipWindow); } void DoEvent(EventRecord &event, RgnHandle *cursorRgn) { if(!SIOUXHandleOneEvent(&event)) { // If SIOUX didn't handle the event, then handle it ourselves switch(event.what) { case mouseDown: DoMouseDown(event); break; case updateEvt: DoUpdate((WindowPtr)event.message); break; case osEvt: DoMouseMove(event, cursorRgn); break; } } } void DoUpdate(WindowPtr window) { BeginUpdate(window); SetPort(window); EraseRect(&window->portRect); GetDC(hMainWnd); WndProc(WM_PAINT, 0); DrawControls(window); ReleaseDC(hMainWnd); GetDC(hTestMonitor); TestMonitorWndProc(); ReleaseDC(hTestMonitor); EndUpdate(window); } void DoMouseDown(EventRecord &event) { WindowPtr thisWindow; ControlHandle thisControl; int part = FindWindow(event.where, &thisWindow); switch(part) { case inSysWindow: SystemClick(&event, thisWindow); break; case inContent: if(thisWindow != FrontWindow()) { SelectWindow(thisWindow); } else if(thisWindow == tipWindow) { long id = 0; Point mouse = event.where; GetDC(hMainWnd); GlobalToLocal(&mouse); if(FindControl(mouse, thisWindow, &thisControl) == inButton) { if(TrackControl(thisControl, mouse, 0) == inButton) { id = GetControlReference(thisControl); } } ReleaseDC(hMainWnd); if(id) { WndProc(WM_COMMAND, id); } } break; case inDrag: DragWindow(thisWindow, event.where, &(*GetGrayRgn())->rgnBBox); break; case inGrow: //DoGrowWindow(thisWindow, event); break; case inGoAway: if (TrackGoAway(thisWindow, event.where)) { gDone = true; } break; } } void DoMouseMove(EventRecord &event, RgnHandle *cursorRgn) { WindowPtr thisWindow; int part = FindWindow(event.where, &thisWindow); if (thisWindow == tipWindow) { InitCursor(); // Set the cursorRegion to everything inside our window if(cursorRgn) { CopyRgn(((WindowPeek)tipWindow)->contRgn, *cursorRgn); } } } void StrToPascal(Str255 pStr, const char *str) { size_t len = strlen(str); pStr[0] = (len > 255) ? 255 : len; strncpy((char*)pStr + 1, str, 255); } /******************************************************************************* * SET COLOR *******************************************************************************/ void SetColor(long color) { if (AllowColor) { if(color == BACK_COLOR) color = LTGRAY_COLOR; // Use colors when available RGBColor rgbColor; rgbColor.red = (color & 0xFF0000) >> 8; rgbColor.green = (color & 0x00FF00) >> 0; rgbColor.blue = (color & 0x0000FF) << 8; RGBForeColor(&rgbColor); } else { // Use patterns for B&W Macs TextMode(srcCopy); switch(color) { case BACK_COLOR: case WHITE_COLOR: PenPat(&qd.white); TextMode(srcBic); break; case BLACK_COLOR: case GRAY_COLOR: PenPat(&qd.black); break; case RED_COLOR: case BLUE_COLOR: PenPat(&qd.ltGray); break; case LTGRAY_COLOR: case GREEN_COLOR: PenPat(&qd.gray); break; } } } void SetColor(long color, long monoColor) { if (AllowColor) { SetColor(color); } else { SetColor(monoColor); } } /******************************************************************************* * DRAW LED *******************************************************************************/ void DrawLed(int x, int y, long color) { Rect ledRect; SetRect(&ledRect, x, y, x + 12, y + 12); // Draw the LED SetColor(color); PaintOval(&ledRect); if (AllowColor) { // Draw a recessed outline SetColor(BLACK_COLOR); FrameOval(&ledRect); SetColor(WHITE_COLOR); FrameArc(&ledRect,45,180); } else { // Draw a non-recessed outline SetColor(BLACK_COLOR); FrameOval(&ledRect); SetColor(WHITE_COLOR); } // Draw the reflection if(color != BACK_COLOR) { ledRect.left += 3; ledRect.top += 3; ledRect.right -= 7; ledRect.bottom -= 7; OffsetRect(&ledRect,0,1); PaintRect(&ledRect); OffsetRect(&ledRect,1,-1); PaintRect(&ledRect); } } /******************************************************************************* * DRAW EDGE *******************************************************************************/ void DrawEdge(Rect *qrc, int edge, int grfFlags) { if(edge == BDR_SUNKENOUTER && AllowColor) { // Draw a sunken rectangle SetColor(GRAY_COLOR); MoveTo(qrc->left,qrc->bottom-1); LineTo(qrc->left,qrc->top); LineTo(qrc->right-1,qrc->top); SetColor(WHITE_COLOR); MoveTo(qrc->left,qrc->bottom-1); LineTo(qrc->right-1,qrc->bottom-1); LineTo(qrc->right-1,qrc->top); } else { // Draw a non-recessed rectangle SetColor(LTGRAY_COLOR); FrameRect(qrc); } } /******************************************************************************* * RECTANGLE *******************************************************************************/ void Rectangle(int left, int top, int right, int bottom) { Rect rect; SetRect(&rect, left, top, right, bottom); PaintRect(&rect); } /******************************************************************************* * TEXT OUT *******************************************************************************/ void TextOut(int x, int y, Str255 pStr) { FontInfo info; GetFontInfo(&info); MoveTo(x, y + info.ascent + info.descent); DrawString(pStr); } void TextOut(int x, int y, const char *str) { Str255 pStr; StrToPascal(pStr, str); TextOut(x, y, pStr); } void TextOutCentered(int x, int y, int w, int h, const char *str) { // convert to Pascal string Str255 pStr; StrToPascal(pStr, str); // now place the floating string in the middle const int width = TextWidth(pStr, 0, strlen(str)); if(width < w) { TextOut(x + w/2 - width/2, y, pStr); } } /******************************************************************************* * GET TEXT EXTENT *******************************************************************************/ long GetTextExtent(const char *str, unsigned long len) { // convert to Pascal string Str255 pStr; StrToPascal(pStr, str); // now place the floating string in the middle return TextWidth(pStr, 0, len); } /******************************************************************************* * GET SYSTEM TIME *******************************************************************************/ unsigned long GetSystemTime() { unsigned long time; GetDateTime (&time); return time; } /******************************************************************************* * SET WINDOW TEXT *******************************************************************************/ void SetWindowText(int id, const char *str) { Str255 pStr; StrToPascal(pStr, str); if(testBtn && id == hTestButton) { GetDC(hMainWnd); SetCTitle(testBtn, pStr); ReleaseDC(hMainWnd); } } /******************************************************************************* * ENABLE WINDOW *******************************************************************************/ void EnableWindow(int id, bool enabled) { ControlHandle hCntl; if(id == hTestButton) hCntl = testBtn; if(id == hExitButton) hCntl = exitBtn; if(hCntl) { GetDC(hMainWnd); HiliteControl(hCntl, enabled ? 0 : 255); ReleaseDC(hMainWnd); } } /******************************************************************************* * INVALIDATE RECT *******************************************************************************/ void InvalidateRect(int id) { GetDC(id); InvalRect(&qd.thePort->portRect); ReleaseDC(id); } /******************************************************************************* * POST QUIT MESSAGE *******************************************************************************/ void PostQuitMessage() { gDone = true; } /******************************************************************************* * START APPLICATION TIMER *******************************************************************************/ void StartApplicationTimer() { timerEnabled = true; } /******************************************************************************* * STOP APPLICATION TIMER *******************************************************************************/ void StopApplicationTimer() { timerEnabled = false; } /******************************************************************************* * PROCESS PENDING MESSAGES *******************************************************************************/ void ProcessPendingMessages() { EventRecord event; if (GetNextEvent(everyEvent, &event)) { DoEvent(event,NULL); } }