systemdict begin /ClassGlassCanvas ClassCanvas dictbegin /Hours 0 def /Minutes 0 def /Seconds 0 def /ShowSeconds? false def /X 0 def /Y 0 def /Width 0 def /Height 0 def dictend classbegin /Transparent false def /DragFrame? false def /HourLength .25 def /HourWidth .06 def /MinLength .38 def /MinWidth .04 def /SecLength .38 def /SecWidth .02 def /HandRadius .04 def /CenterRadius .05 def /MarkerRadius .44 def /MarkerWidth .04 def /Cursor cursordict /busy get cursordict /busy_m get cursorfont newcursor def /Menuable? true def /QuitNotify { currentprocess killprocessgroup } def /Menu /Grid framebuffer /new ClassMenu send def [ [(Quit) /QuitNotify] ] /setitemlist Menu send /path { % x y w h => - /AnalogClockPath self send } def /AnalogClockPath { % x y w h => - matrix currentmatrix % x y w h mat 5 1 roll 4 2 roll % mat w h x y translate scale .5 .5 translate % mat /DrawHands self send /DrawCenter self send /DrawMarkers self send setmatrix % } def /DrawHands { /DrawHourHand self send /DrawMinuteHand self send ShowSeconds? { /DrawSecondHand self send } if } def /DrawHourHand { % - => - HourLength HourWidth Hours Minutes 60 div add -30 mul /DrawHand self send } def /DrawMinuteHand { % - => - MinLength MinWidth Minutes -6 mul /DrawHand self send } def /DrawSecondHand { % - => - SecLength SecWidth Seconds -6 mul /DrawHand self send } def /DrawHand { % rad wid rot => dup rotate 3 1 roll dup 2 div neg HandRadius moveto dup 0 rlineto exch dup 0 exch rlineto exch neg 0 rlineto neg 0 exch rlineto closepath neg rotate } def /DrawCenter { % - => - 0 0 CenterRadius 0 360 arc closepath } def /DrawMarkers { % - => - /Times-Bold findfont .09 scalefont setfont 12 { MarkerWidth -.5 mul MarkerRadius moveto MarkerWidth 0 rlineto 0 .5 MarkerRadius sub rlineto MarkerWidth neg 0 rlineto closepath -30 rotate } repeat } def /Paint { % - => - matrix currentmatrix Width Height scale .5 .5 translate /DrawHands self send BG3 setcolor fill /DrawCenter self send BG0 setcolor fill /DrawMarkers self send BG setcolor fill setmatrix } def /preferredsize { % - => w h 200 200 } def /minsize { % - => w h 2 2 } def /reshape { % x y w h => - 4 copy /Height exch def /Width exch def /Y exch def /X exch def /reshape super send } def /move { /move super send gsave Parent setcanvas /location self send /Y exch def /X exch def grestore } def /updateshape { gsave Parent setcanvas X Y Width Height /reshape self send grestore } def /mod+ { % a b => c exch 1 index 2 copy div cvi mul sub dup 0 lt { add } { exch pop } ifelse } def /settime { % hour min sec => - /Seconds exch def /Minutes exch def /Hours exch def (settime H % M % S %\n)[Hours Minutes Seconds]dbgprintf /updateshape self send } def /showseconds { % bool => - /ShowSeconds? exch def } def /Trackable? true def /TrackStart { % event => false | [list] true dup /Name get AdjustButton eq { /TrackMotion /BBoxMotion load promote /TrackStop /BBoxStop load promote BBoxStart /Default true } { gsave self setcanvas /ClockScale self send dup begin XLocation dup mul YLocation dup mul add sqrt end grestore MarkerRadius ge { /TrackMotion /MoveMotion load promote /TrackStop /MoveStop load promote MoveStart /Default true } { pop false } ifelse grestore } ifelse } def /BBoxMotion { % event => - gsave TrackDictBegin % x y X1 Y1 points2rect % x y w h TrackDictEnd /reshape self send grestore } def /Selectable? true def /SelectableType /Graphic def /InSelection? { % event sel => bool gsave pop /ClockScale self send begin XLocation dup mul YLocation dup mul add end CenterRadius dup mul le grestore (InSelection? => %\n)[2 index]dbgprintf } def /NewSelection { % event rank => sel exch pop self /new ClassTimeSelection send Hours Minutes Seconds /settime 4 index send } def /ClockScale { self setcanvas Width Height scale .5 .5 translate } def /SelectedRegion null def /SelectedX 0 def /SelectedY 0 def /SelectAt { % event sel => - gsave 1 index begin /ClockScale self send XLocation YLocation end 1 index dup mul 1 index dup mul add sqrt dup CenterRadius le { pop /Center } { MarkerRadius ge { /Marker } { /DrawHourHand self send 2 copy pointinpath newpath { /Hour } { /DrawMinuteHand self send 2 copy pointinpath newpath { /Minute } { ShowSeconds? { /DrawSecondHand self send 2 copy pointinpath newpath { /Second } { null } ifelse } { null } ifelse } ifelse } ifelse } ifelse } ifelse grestore /SelectedRegion exch promote /SelectedY exch promote /SelectedX exch promote (SelectAt %\n)[SelectedRegion]dbgprintf pop pop } def /angle { % dx dy 2 copy 0 eq exch 0 eq and { 0 } { exch atan 90 exch sub 360 mod+ } ifelse } def /changetime { % h m s => - 10 dict begin /s exch def /m exch def /h exch def /Seconds Seconds s add dup 60 div floor m add /m exch def 60 mod+ store /Minutes Minutes m add dup 60 div floor h add /h exch def 60 mod+ store /Hours Hours h add 24 mod+ store end /updateshape self send } def /AdjustTo { % event sel => - % (AdjustTo %\n)[SelectedRegion]dbgprintf gsave 1 index begin /ClockScale self send SelectedRegion { /Marker { XLocation YLocation SelectedX SelectedY xysub /location self send xyadd /move self send } /Center { } /Hour { XLocation YLocation angle 30 div floor Hours floor sub dup 0 eq { pop } { dup 6 ge { 12 sub } if dup -6 lt { 12 add } if 0 0 /changetime self send } ifelse } /Minute { XLocation YLocation angle 6 div floor Minutes floor sub dup 0 eq { pop } { dup 30 ge { 60 sub } if dup -30 lt { 60 add } if 0 exch 0 /changetime self send } ifelse } /Second { XLocation YLocation angle 6 div floor Seconds floor sub dup 0 eq { pop } { dup 30 ge { 60 sub } if dup -30 lt { 60 add } if 0 exch 0 exch /changetime self send } ifelse } } case end grestore pop pop } def /DragCanvas null def /DragAt { % event sel => - Hours Minutes Seconds /settime 4 index send (H % M % S %\n)[Hours Minutes Seconds]dbgprintf /DragCanvas framebuffer createoverlay promote /DragTo self send } def /Margin 3 def /DragTo { % event sel => - gsave DragCanvas setcanvas erasepage /Preview? 1 index send { % ev sel 0 setgray TextFont setfont /CurrentText self send % ev string exch begin XLocation YLocation end % string x y 2 copy 4 index stringwidth pop Margin 2 mul add TextFont fontheight Margin 2 mul add rectpath stroke % string x y moveto Margin dup TextFont fontdescent add rmoveto show }{ pop pop /DragCanvas unpromote } ifelse grestore } def /CurrentText { % - => str /ContentsAscii /query 3 -1 roll send not {(???)} if } def /AttachInsertionPoint { % event sel pos-name => - % (AttachInsertionPoint\n)[]dbgprintf pop pop pop } def /clearselectable { % - => - } def /cancel {} def classend def /ClassTimeSelection ClassSelection [ /Hours /Minutes /Seconds ] classbegin /CanRenderAs [ /Hours /Minutes /Seconds /ContentsAscii ] def /deselect { Holder null ne { /paint Holder send } if } def /copy { % dest-sel => -- mark { /Hours /Minutes /Seconds } { dup load } forall counttomark 2 idiv { def } repeat pop } def /InSelection? { % event sel => bool Holder null eq { pop pop false } { /InSelection? Holder send } ifelse } def /singlerequest { % oldval key => newval Holder null ne { dup { % oldval key /ContentsAscii { pop pop (%:%:%) [Hours cvi Minutes cvi Seconds cvi] sprintf } /Default { CanRenderAs 1 index arraycontains? { load exch pop } { pop pop /UnknownRequest } ifelse } } case % newval } { null } ifelse } def /settime { % h m s => - /Seconds exch def /Minutes exch def /Hours exch def } def classend def end % systemdict /window framebuffer /new ClassGlassCanvas send def /new ClassEventMgr send /activate window send 10 10 /preferredsize window send /reshape window send /map window send %/traceclass ClassGlassCanvas send