mac-tip/mac-cpp-source/tip/tip_main.cpp

417 lines
12 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <SIOUX.h>
#include <Windows.h>
#include <Quickdraw.h>
#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);
}
}