home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-21 | 11.9 KB | 508 lines | [TEXT/PJMM] |
- {This program was written by Eric Kilk in 1985, as a Desk Accessory. It was revived in 1995 by Ken Long,}
- {who turned it into an application. After he posted it to alt.sources.mac, I (Ingemar R), modified it to give it}
- {some functionality I found lacking. New features:}
- {}
- {• Updates automatically}
- {• Resizeable}
- {• More hour marks}
- {• Optional digits (3, 6, 9 and 12), roman or arabic}
- {• Black or white}
- {}
- {Do you feel like working some more on it? Colorize? Seconds? Circular WDEF? Put it in the menu bar?}
- {More options?}
- {}
- {- Fixes 21 of april:}
- {• Checked the "can background" flag so it updates when in the background}
- {• Modified the hands so they draw correctly}
-
- program NewWatch;
-
- const
- appleID = 1;
- fileID = 2;
- editID = 3;
- optionsID = 4;
-
- helpItem = 1;
- defaultItem = 2;
- quitItem = 4;
-
- kTwoPi = 6.2831;
-
- var
- appleMenu, fileMenu, editMenu, optionsMenu: MenuHandle;
-
- clockWindow, whatWindow: WindowPtr;
- dragRect: Rect;
-
- type
- settingsType = record
- black: Boolean;
- display: Integer;
- end;
- var
- settings: SettingsType;
-
- gDone, gHasWNE: Boolean;
- gPrevDateTime: DateTimeRec;
-
- type
- WindowTemplate = record
- boundsRect: Rect;
- procID: Integer;
- visible: Boolean;
- filler1: Boolean;
- goAwayFlag: Boolean;
- filler2: Boolean;
- refCon: LongInt;
- title: Str255;
- end;
- WindowTPtr = ^WindowTemplate;
- WindowTHnd = ^WindowTPtr;
- var
- wt: WindowTHnd;
-
-
-
- procedure EK;
- begin
- Move(-3, 0);
- Line(0, 4);
- Move(1, -4);
- Line(1, 0);
- Move(-1, 2);
- Line(0, 0);
- Move(0, 2);
- Line(1, 0);
- Move(2, -4);
- Line(0, 4);
- Move(1, -2);
- Line(2, -2);
- Move(-1, 3);
- Line(1, 1);
- end; {EK}
-
- procedure DrawHands (dateTime: DateTimeRec);
- var
- mx, my, hx, hy: Integer; {• hand end-points */}
- minUnit, min, hr: double; {• time */}
- cxSize, cySize: Integer;
- hourRgn, minuteRgn: RgnHandle;
- begin
- SetPort(clockWindow);
- cxSize := (clockWindow^.portRect.right - clockWindow^.portRect.left) div 2;
- cySize := (clockWindow^.portRect.bottom - clockWindow^.portRect.top) div 2;
- SetOrigin(-cxSize, -cySize); {• make 0,0 in center */}
-
- minUnit := dateTime.minute / 60.0;
- min := minUnit * kTwoPi; {• 2*pi */}
- hr := (dateTime.hour + minUnit) / 12.0 * kTwoPi;
- mx := Trunc(0.75 * cxSize * sin(min));
- my := Trunc(-0.75 * cySize * cos(min));
- hx := Trunc(0.5 * cxSize * sin(hr));
- hy := Trunc(-0.5 * cySize * cos(hr));
-
- hourRgn := NewRgn;
- minuteRgn := NewRgn;
-
- OpenRgn;
- MoveTo(0, 0); {• create the minute hand region}
- LineTo(mx, my);
- if abs(mx) > abs(my) then
- Line(0, 1)
- else
- Line(1, 0);
- Line(-mx, -my);
- LineTo(0, 0);
- CloseRgn(minuteRgn);
- OpenRgn;
- MoveTo(0, 0); {• create the hour hand region}
- LineTo(hx, hy);
- if abs(hx) > abs(hy) then
- Line(0, 1)
- else
- Line(1, 0);
- Line(-hx, -hy);
- LineTo(0, 0);
- CloseRgn(hourRgn);
-
- UnionRgn(hourRgn, minuteRgn, minuteRgn);
-
- PaintRgn(minuteRgn); {• draw the hands.}
- DisposeRgn(minuteRgn);
- DisposeRgn(hourRgn);
-
- MoveTo(0, 0); {• erase the center dot.}
- PenPat(white);
- LineTo(0, 0);
- PenPat(black);
- end; {DrawHands}
-
- procedure ShowClock;
- {• draw the entire clock face */}
- var
- dateTime: DateTimeRec; {• date gets read into here */}
-
- cxSize, cySize: Integer;
-
- fInfo: FontInfo;
- theTextSize: Integer;
- begin
- SetPort(clockWindow);
- PenNormal;
- if settings.black then
- PaintRect(clockWindow^.portRect)
- else
- EraseRect(clockWindow^.portRect);
-
- cxSize := (clockWindow^.portRect.right - clockWindow^.portRect.left) div 2;
- cySize := (clockWindow^.portRect.bottom - clockWindow^.portRect.top) div 2;
-
- GetTime(dateTime);
- if (dateTime.hour > 11) then
- dateTime.hour := dateTime.hour - 12;
- SetOrigin(-cxSize, -cySize); {• make 0,0 in center */}
- PenMode(srcXor);
-
- {The text size is determined from the smallest side!}
- if cxSize > cySize then
- theTextSize := cySize div 5
- else
- theTextSize := cxSize div 5;
-
- TextSize(theTextSize);
- GetFontInfo(fInfo);
-
- if (settings.display = 0) or (theTextSize < 6) then
- begin
- MoveTo(0, cySize - 2);
- Line(0, 0); {• draw 4 ticks.}
- MoveTo(cxSize - 2, 0);
- Line(0, 0);
- MoveTo(0, -cySize + 1);
- Line(0, 0);
- MoveTo(-cxSize + 1, 0);
- Line(0, 0);
- end
- else if settings.display = 1 then
- begin
- PenMode(patXor);
- if settings.black then
- ForeColor(whiteColor);
- MoveTo(0 - StringWidth('6') div 2, cySize - 2);
- DrawString('6');
- MoveTo(cxSize - 0 - StringWidth('3'), 0 + fInfo.ascent div 2);
- DrawString('3');
- MoveTo(0 - StringWidth('12') div 2, -cySize + 0 + fInfo.ascent);
- DrawString('12');
- MoveTo(-cxSize + 1, 0 + fInfo.ascent div 2);
- DrawString('9');
- ForeColor(blackColor);
- end
- else
- begin
- if settings.black then
- ForeColor(whiteColor);
- PenMode(patXor);
- MoveTo(0 - StringWidth('VI') div 2, cySize - 2);
- DrawString('VI');
- MoveTo(cxSize - 0 - StringWidth('III'), 0 + fInfo.ascent div 2);
- DrawString('III');
- MoveTo(0 - StringWidth('XII') div 2, -cySize + 0 + fInfo.ascent);
- DrawString('XII');
- MoveTo(-cxSize + 1, 0 + fInfo.ascent div 2);
- DrawString('IX');
- ForeColor(blackColor);
- end;
-
- {Draw the rest of the marks}
- MoveTo(Trunc((cxSize - 2) * 0.866), Trunc((cySize - 2) * 0.5));
- Line(0, 0);
- MoveTo(Trunc((cxSize - 2) * 0.5), Trunc((cySize - 2) * 0.866));
- Line(0, 0);
- MoveTo(-Trunc((cxSize - 2) * 0.866), Trunc((cySize - 2) * 0.5));
- Line(0, 0);
- MoveTo(-Trunc((cxSize - 2) * 0.5), Trunc((cySize - 2) * 0.866));
- Line(0, 0);
- MoveTo(Trunc((cxSize - 2) * 0.866), -Trunc((cySize - 2) * 0.5));
- Line(0, 0);
- MoveTo(Trunc((cxSize - 2) * 0.5), -Trunc((cySize - 2) * 0.866));
- Line(0, 0);
- MoveTo(-Trunc((cxSize - 2) * 0.866), -Trunc((cySize - 2) * 0.5));
- Line(0, 0);
- MoveTo(-Trunc((cxSize - 2) * 0.5), -Trunc((cySize - 2) * 0.866));
- Line(0, 0);
-
- {Draw EK}
- MoveTo(0, cySize div 2); {5}
- EK;
-
- DrawHands(dateTime);
-
- gPrevDateTime := dateTime;
- end; {ShowClock}
-
- procedure BackgroundTask;
- var
- dateTime: DateTimeRec; {• date gets read into here */}
- begin
- GetTime(dateTime);
- if dateTime.minute <> gPrevDateTime.minute then
- begin
- SetPort(clockWindow);
- PenMode(srcXor);
- DrawHands(gPrevDateTime);
- PenMode(srcXor);
- DrawHands(dateTime);
- gPrevDateTime := dateTime;
- end;
- end; {BackgroundTask}
-
- procedure SetUpWindow;
- var
- wr: Rect;
- begin
- dragRect := screenBits.bounds;
-
- clockWindow := GetNewWindow(128, nil, WindowPtr(-1));
- SetPort(clockWindow);
- end; {SetUpWindow}
-
- procedure SetUpMenus;
- begin
- appleMenu := NewMenu(appleID, stringof(char($14)));
- InsertMenu(appleMenu, 0);
- fileMenu := NewMenu(fileID, 'File');
- InsertMenu(fileMenu, 0);
- editMenu := NewMenu(editID, 'Edit');
- InsertMenu(editMenu, 0);
- optionsMenu := NewMenu(optionsID, 'Options');
- InsertMenu(optionsMenu, 0);
- AppendMenu(appleMenu, 'About NewWatch…');
- AddResMenu(appleMenu, 'DRVR');
- AppendMenu(fileMenu, 'Help/H;Standard size/N;(-;Quit/Q');
- AppendMenu(editMenu, 'Undo/Z;(-;Cut/X;Copy/C;Paste/V;Clear');
- AppendMenu(optionsMenu, 'White;Black;(-;Dots;Arabic;Roman');
- DrawMenuBar;
- end; {SetUpMenus}
-
- procedure AdjustMenus;
- var
- wp: WindowPeek;
- kind: Integer;
- DA: Boolean;
- procedure Enable (menu: MenuHandle; item: Integer; ok: Boolean);
- begin
- if ok then
- EnableItem(menu, item)
- else
- DisableItem(menu, item);
- end; {Enable}
- begin
- wp := WindowPeek(FrontWindow);
- if wp = nil then
- kind := 0
- else
- kind := wp^.windowKind;
- DA := kind < 0;
-
- Enable(editMenu, 1, DA);
- Enable(editMenu, 3, DA);
- Enable(editMenu, 4, DA);
- Enable(editMenu, 5, DA);
- Enable(editMenu, 6, DA);
-
- CheckItem(optionsMenu, 1, not settings.black);
- CheckItem(optionsMenu, 2, settings.black);
-
- CheckItem(optionsMenu, 4, settings.display = 0);
- CheckItem(optionsMenu, 5, settings.display = 1);
- CheckItem(optionsMenu, 6, settings.display = 2);
- end; {AdjustMenus}
-
- procedure HandleMenu (mSelect: LongInt);
- var
- menuID: Integer;
- menuItem: Integer;
- name: Str255;
- savePort: GrafPtr;
- theFrontWindow: WindowPeek;
- begin
- menuID := HiWord(mSelect);
- menuItem := LoWord(mSelect);
-
- case menuID of
- appleID:
- if menuItem = 1 then
- begin
- if Alert(128, nil) = 1 then {About…}
- ;
- end
- else
- begin
- GetPort(savePort);
- GetItem(appleMenu, menuItem, name);
- if OpenDeskAcc(name) = 0 then
- ;
- SetPort(savePort);
- end;
- fileID:
- case menuItem of
- helpItem:
- begin
- if Alert(129, nil) = 1 then {Show help text}
- ;
- end;
- defaultItem:
- begin
- SizeWindow(clockWindow, 32, 32, false);
- SetPort(clockWindow);
- InvalRect(clockWindow^.portRect);
- {Move it to some safe place too}
- MoveWindow(clockWindow, 40, 40, true);
- end;
- quitItem:
- gDone := true;
- end; {case}
- editID:
- if not SystemEdit(menuItem - 1) then
- SysBeep(5);
- optionsID:
- begin
- case menuItem of
- 1:
- settings.black := false;
- 2:
- settings.black := true;
- otherwise
- settings.display := menuItem - 4;
- end; {case}
- InvalRect(clockWindow^.portRect);
- AdjustMenus;
- end;
- end;
- end; {HandleMenu}
-
- procedure InitMacintosh;
- const
- _WaitNextEvent = $A860;
- _Unimplemented = $A89F;
- begin
- {$IFC UNDEFINED THINK_PASCAL}
- MaxApplZone;
-
- InitGraf(@qd.thePort);
- InitFonts;
- FlushEvents(everyEvent, 0);
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(nil);
- {$ENDC}
- InitCursor;
-
- gHasWNE := NGetTrapAddress(_WaitNextEvent, ToolTrap) <> NGetTrapAddress(_Unimplemented, ToolTrap);
- end;
-
- procedure HandleMouseDown (var theEvent: EventRecord);
- var
- theWindow: WindowPtr;
- windowCode: Integer;
- growResult: Longint;
- begin
- windowCode := FindWindow(theEvent.where, theWindow);
-
- case windowCode of
- inSysWindow:
- SystemClick(theEvent, theWindow);
- inMenuBar:
- begin
- AdjustMenus;
- HandleMenu(MenuSelect(theEvent.where));
- end;
- inDrag: {We should not have any, but just in case someone hacks it…}
- if theWindow = clockWindow then
- DragWindow(clockWindow, theEvent.where, dragRect);
- inContent:
- if theWindow = clockWindow then
- begin
- if theWindow <> FrontWindow then
- SelectWindow(clockWindow)
- else if BAnd(theEvent.modifiers, optionKey) <> 0 then {Option-klick = resize!}
- begin
- growResult := GrowWindow(clockWindow, theEvent.where, GetGrayRgn^^.rgnBBox);
- if growResult <> 0 then
- begin
- SizeWindow(clockWindow, LoWord(growResult), HiWord(growResult), false);
- SetPort(clockWindow);
- InvalRect(clockWindow^.portRect);
- end;
- end
- else
- DragWindow(clockWindow, theEvent.where, dragRect);
- end;
- { inGoAway: }
- { if (theWindow = clockWindow) then if TrackGoAway(clockWindow, theEvent.where) then}
- { gDone := true;}
- end;
- end;
-
- procedure HandleEvent;
- var
- ok: Boolean;
- theEvent: EventRecord;
- begin
- HiliteMenu(0);
-
- if gHasWNE then
- ok := WaitNextEvent(everyEvent, theEvent, 120, nil) {sleeptime of 2 seconds - we don't need more!}
- else
- begin
- SystemTask; {• Handle desk accessories.}
- ok := GetNextEvent(everyEvent, theEvent);
- end;
-
- if ok then
- case theEvent.what of
- mouseDown:
- HandleMouseDown(theEvent);
- keyDown, autoKey:
- if BAnd(theEvent.modifiers, cmdKey) <> 0 then
- begin
- AdjustMenus;
- HandleMenu(MenuKey(char(BAnd(theEvent.message, charCodeMask))));
- end;
- updateEvt:
- begin
- BeginUpdate(clockWindow);
- ShowClock;
- EndUpdate(clockWindow);
- end;
- activateEvt:
- InvalRect(clockWindow^.portRect);
- end
- else
- BackgroundTask;
- end; {HandleEvent}
-
- { main program }
- begin
- InitMacintosh;
- SetUpMenus;
- SetUpWindow;
- settings := SettingsType(GetWRefCon(clockWindow));
- ShowClock;
-
- while not gDone do
- HandleEvent;
-
- SetPort(clockWindow);
-
- wt := WindowTHnd(GetResource('WIND', 128));
- wt^^.boundsRect := clockWindow^.portRect;
- LocalToGlobal(wt^^.boundsRect.topLeft);
- LocalToGlobal(wt^^.boundsRect.botRight);
- wt^^.refCon := Longint(settings);
- ChangedResource(Handle(wt));
-
- end.