# Clock Client Tcl code for tkgoodstuff proc ClockDeclare {} { set Prefs_taborder(:Clients,Clock) "Misc Analog Alarm Geometry Fonts" set Prefs_taborder(:Clients,Clock,Analog) "Misc Colors" TKGDeclare Clock(24hour) 0 -typelist [list Clients Clock Misc]\ -vartype boolean\ -label "24-hour mode" TKGDeclare Clock(analog) 0 -typelist [list Clients Clock Misc]\ -vartype boolean\ -label "Analog Clock" TKGDeclare Clock(show) timeonly -typelist [list Clients Clock Misc]\ -vartype radio -radioside left -radiolist\ {{"Time Only" timeonly} {"Date Only" dateonly} {Both both}}\ -label "Digital . . ." TKGDeclare Clock(border) 0 -typelist [list Clients Clock Misc]\ -label "Width in pixels of border around clock display" TKGDeclare Clock(hourlyevent) "" -typelist [list Clients Clock Misc]\ -label "Unix command to execute every hour on the hour" # DIGITAL STUFF TKGDeclare Clock(orientation) {} -typelist [list Clients Clock Geometry]\ -vartype radio -radiolist {{Horizontal horizontal} {Vertical vertical}}\ -label "Overall Orientation"\ -help "Default depends on panel orientation" TKGDeclare Clock(aside_horiz) right -typelist [list Clients Clock Geometry]\ -label "Side of date/time taken by analog clock if horizontal." \ -vartype optionMenu -optionlist "left right top bottom" TKGDeclare Clock(aside_vert) top -typelist [list Clients Clock Geometry]\ -label "Side of date/time taken by analog clock if vertical." \ -vartype optionMenu -optionlist "left right top bottom" TKGDeclare Clock(dside_horiz_analog) top -typelist [list Clients Clock Geometry]\ -label "Side of time taken by date if horizontal and using the analog clock." \ -vartype optionMenu -optionlist "left right top bottom" TKGDeclare Clock(dside_horiz_noanalog) right -typelist [list Clients Clock Geometry]\ -label "Side of time taken by date if horizontal and not using the analog clock." \ -vartype optionMenu -optionlist "left right top bottom" TKGDeclare Clock(dside_vert) top -typelist [list Clients Clock Geometry]\ -label "Side of time taken by date if vertical." \ -vartype optionMenu -optionlist "left right top bottom" TKGDeclare Clock(BigFont) ""\ -vartype font\ -typelist [list Clients Clock Fonts]\ -label "Larger font (leave blank for a default that depends on the tkgoodstuff\ font scale)" if [Empty $Clock(BigFont)] { # set Clock(BigFont) "Times [lindex {14 18 24} $TKG(fontscale)] bold" set Clock(BigFont) tkghuge } TKGDeclare Clock(SmallFont) ""\ -vartype font\ -typelist [list Clients Clock Fonts]\ -label "Smaller font (leave blank for a default that depends on the tkgoodstuff\ font scale)"\ -help "Used for the date if showing both date and time." if [Empty $Clock(SmallFont)] { # set Clock(SmallFont) "Times [lindex {12 14 18} $TKG(fontscale)] bold" set Clock(SmallFont) tkgbig } TKGColorDeclare Clock(foreground) "" [list Clients Clock Misc]\ "Digital Foreground Color" black TKGColorDeclare Clock(background) "" [list Clients Clock Misc]\ "Background Color" # ALARM STUFF TKGDeclare Alarm(nobeep) 0 -typelist [list Clients Clock Alarm]\ -label "Don't Beep" -vartype boolean TKGDeclare Alarm(event) "" -typelist [list Clients Clock Alarm]\ -label "Unix command to execute when the alarm sounds" TKGDeclare Alarm(timefont) {Lucidatypewriter 24 bold} \ -vartype font\ -typelist [list Clients Clock Alarm] \ -label "Large Fixed Font for Time Setting" TKGColorDeclare Alarm(Analogflagcolor) {} \ [list Clients Clock Alarm] \ "Color of Alarm Flag on Analog Clock" \ $Clock(foreground) TKGDeclare Alarm(flagfont) "" -fallback tkgbigbold\ -vartype font\ -typelist [list Clients Clock Alarm]\ -label "Font for Alarm Flag on Analog Clock" TKGColorDeclare Alarm(NoAnalogflagcolor) \#f81440 \ [list Clients Clock Alarm]\ "Color to which to Change All-Digital Display to Flag Alarm" # ANALOG STUFF TKGDeclare Analog(minsize) 50 -typelist [list Clients Clock Analog Misc]\ -label "Minimum Diameter of Analog Clock" TKGDeclare Analog(expand_to_square) 1 -typelist [list Clients Clock Analog Misc]\ -vartype boolean -label "Expand to Occupy Largest Available Dimension" TKGDeclare Analog(autoresize) 1 -typelist [list Clients Clock Analog Misc]\ -vartype boolean -label "Resize Automatically (can go haywire)" TKGColorDeclare Analog(background) {} \ [list Clients Clock Analog Colors] \ "Background Color for Analog Clock" \ $Clock(background) TKGColorDeclare Analog(hubcolor) \#f81440 [list Clients Clock Analog Colors]\ "Color of Center Hub" TKGColorDeclare Analog(facecolor) \#ffffe3 [list Clients Clock Analog Colors]\ "Color of Clock Face" TKGColorDeclare Analog(minutecolor) \#000000 [list Clients Clock Analog Colors]\ "Color of Minute Hand" TKGColorDeclare Analog(hourcolor) \#000000 [list Clients Clock Analog Colors]\ "Color of Hour Hand" TKGDeclare Analog(bezel) 1 -typelist [list Clients Clock Analog Misc]\ -vartype boolean -label "Draw a Bezel (a ring)" TKGColorDeclare Analog(bezelcolor) \#f81440 [list Clients Clock Analog Colors]\ "Color of Bezel" TKGColorDeclare Analog(tickcolor) \#f81440 [list Clients Clock Analog Colors]\ "Color of Small Tick Marks" TKGColorDeclare Analog(bigtickcolor) \#000000 [list Clients Clock Analog Colors]\ "Color of Big Tick Marks" } ######## # General Clock stuff ######## proc ClockUpdate args { global Clock Clock_window Alarm set timedate [clock format [clock seconds] -format "%H %M %M %S %h %d"] scan $timedate {%s %s %s %s %s %s} Clock(hour) Clock(minute) prettyminute seconds month day foreach v { Clock(hour) Clock(minute) seconds day } { set $v [TKGZeroTrim [set $v]] } set Clock(offset) [ expr 60 - $seconds ] TKGPeriodic Clock_periodic 60 $Clock(offset) ClockUpdate if $Clock(24hour) { set Clock(modhour) $Clock(hour) set Clock(prettyhour) $Clock(hour) set Clock(prettytime) "$Clock(prettyhour):$prettyminute" if { $Alarm(enablealarms) && \ ($Clock(modhour) == $Alarm(hour)) && \ "$Clock(minute)" == "$Alarm(minute)" } { AlarmAlarm } } else { set Clock(modhour) [expr $Clock(hour) % 12] set Clock(prettyhour) [expr (($Clock(modhour) == 0) ? 12: $Clock(modhour))] if {$Clock(hour) > 11} { set Clock(ampm) pm } else { set Clock(ampm) am } set Clock(prettytime) "$Clock(prettyhour):$prettyminute" if { $Alarm(enablealarms) && \ "$Clock(ampm)" == "$Alarm(ampm)" && \ ($Clock(modhour) == ($Alarm(hour) % 12)) && \ "$Clock(minute)" == "$Alarm(minute)" } { AlarmAlarm } } set Clock(prettydate) "$month $day" if { [winfo exists $Clock_window.analog]} { AnalogUpdate } if {![Empty $Clock(hourlyevent)] && ($Clock(minute) == 0)} { eval exec $Clock(hourlyevent) & } # a hook for clients to run a process every minute TKGDoHook Clock_minute_hook } proc Clock_timedatetoggle {} { global Clock Clock_window set w $Clock_window.datetime if { $Clock(show) != "dateonly" } { if $Clock(togglestate) { $w.time.msg config -textvariable Clock(prettydate)\ -font $Clock(SmallFont) } else { $w.time.msg config -textvariable Clock(prettytime)\ -font $Clock(BigFont) } } if { $Clock(show) != "timeonly"} { if $Clock(togglestate) { $w.date.msg config -textvariable Clock(prettytime) } else { $w.date.msg config -textvariable Clock(prettydate) } } set Clock(togglestate) [expr 1 - $Clock(togglestate)] update idletasks } proc Clock_configure_window args { global Clock Clock_window Clients Alarm Analog TKG catch { destroy $Clock_window.datetime } catch { destroy $Clock_window.analog } set orientation $Clock(orientation) if [Empty $orientation] { if [In $TKG(screenedge) {left right}] { set orientation vertical } elseif [In $TKG(screenedge) {top bottom}] { set orientation horizontal } else { set orientation $TKG(orientation) } } if {$orientation == "horizontal"} { set aside $Clock(aside_horiz) if $Clock(analog) { set dside $Clock(dside_horiz_analog) } else { set dside $Clock(dside_horiz_noanalog) } } else { set aside $Clock(aside_vert) set dside $Clock(dside_vert) } # analog aside arow acolumn drow dcolumn c0 c1 r0 r1 set configlist [ list \ { 1 left 0 0 0 1 1 1 1 0 } \ { 1 right 0 1 0 0 1 1 1 0 } \ { 1 top 0 0 1 0 1 0 1 1 } \ { 1 bottom 1 0 0 0 1 0 1 1 } \ { 0 left 0 0 0 0 1 0 1 0 } \ { 0 right 0 0 0 0 1 0 1 0 } \ { 0 top 0 0 0 0 1 0 1 0 } \ { 0 bottom 0 0 0 0 1 0 1 0 } ] foreach l $configlist { if {($Clock(analog) == [lindex $l 0]) && ($aside == [lindex $l 1])} { scan [join [lrange $l 2 5]] "%d %d %d %d" arow acolumn drow dcolumn set w $Clock_window grid columnconfigure $w 0 -weight [lindex $l 6] grid columnconfigure $w 1 -weight [lindex $l 7] grid rowconfigure $w 0 -weight [lindex $l 8] grid rowconfigure $w 1 -weight [lindex $l 9] break } } if { $Clock(analog) } { setifunset Analog(width) $Analog(minsize) setifunset Analog(height) $Analog(minsize) canvas $Clock_window.analog \ -width $Analog(width) -height $Analog(height) \ -background $Analog(background) \ -highlightthickness 0 -borderwidth 0 grid $Clock_window.analog -sticky nsew -row $arow -column $acolumn grid propagate $Clock_window.analog 0 AnalogResize if $Analog(autoresize) { bind $Clock_window.analog [subst { # bind $Clock_window.analog {} set Analog(width) %w set Analog(height) %h AnalogResize ClockUpdate }] } # if $Analog(autoresize) { # TKGAddToHook TKG_expose_hook [subst { # set Analog(width) %w # set Analog(height) %h # AnalogResize # ClockUpdate # }] # } set Clock(currentfg) $Clock(foreground) } else { if $Alarm(enablealarms) { set Clock(currentfg) $Alarm(NoAnalogflagcolor) } } if { $Clock(show) != "neither"} { set dw $Clock_window.datetime grid [frame $dw -borderwidth 0 -highlightthickness 0]\ -row $drow -column $dcolumn -sticky nsew # dside daterow datecolum timerow timecolumn c0 c1 r0 r1 set configlist [list \ { left 0 0 0 1 1 1 1 0 }\ { right 0 1 0 0 1 1 1 0 }\ { top 0 0 1 0 1 0 1 1 }\ { bottom 1 0 0 0 1 0 1 1 } ] foreach l $configlist { if {$dside == [lindex $l 0]} { scan [join [lrange $l 1 4]] "%d %d %d %d" \ daterow datecolum timerow timecolumn grid columnconfigure $dw 0 -weight [lindex $l 5] grid columnconfigure $dw 1 -weight [lindex $l 6] grid rowconfigure $dw 0 -weight [lindex $l 7] grid rowconfigure $dw 1 -weight [lindex $l 8] break } } switch $dside { left { set daterow 0; set datecolumn 0; set timerow 0; set timecolumn 1 grid rowconfigure $dw 0 -weight 1 grid rowconfigure $dw 1 -weight 0 } right { set daterow 0; set datecolumn 1; set timerow 0; set timecolumn 0 grid rowconfigure $dw 0 -weight 1 grid rowconfigure $dw 1 -weight 0 } top { set daterow 0; set datecolumn 0; set timerow 1; set timecolumn 0 grid columnconfigure $dw 0 -weight 1 grid columnconfigure $dw 1 -weight 0 } bottom { set daterow 1; set datecolumn 0; set timerow 0; set timecolumn 0 grid columnconfigure $dw 0 -weight 1 grid columnconfigure $dw 1 -weight 0 } } if {$Clock(show) != "timeonly" } { frame $dw.date -borderwidth 0 -highlightthickness 0 TKGRowCol $dw.date label $dw.date.msg \ -font $Clock(SmallFont) -text "XXX XX"\ -pady 0 -borderwidth 0 -highlightthickness 0 update idletasks grid $dw.date.msg -sticky nsew update idletasks grid propagate $dw.date 0 $dw.date.msg configure \ -textvariable Clock(prettydate) grid $dw.date -sticky nsew -row $daterow -column $datecolumn } if {$Clock(show) == "dateonly"} { if { $Clock(analog) == 0 } { grid propagate $dw.date 1 $dw.date.msg configure\ -font $Clock(BigFont) -text "XXX XX" update idletasks grid propagate $dw.date 0 $dw.date.msg configure \ -textvariable Clock(prettydate) } } else { frame $dw.time -borderwidth 0 -highlightthickness 0 TKGRowCol $dw.time label $dw.time.msg\ -font $Clock(BigFont) \ -text "88:88"\ -pady 0 -borderwidth 0 -highlightthickness 0 grid $dw.time.msg -sticky nsew update idletasks grid propagate $dw.time 0 $dw.time.msg configure \ -textvariable Clock(prettytime) grid $dw.time -sticky nsew -row $timerow -column $timecolumn } ColorConfig $dw $Clock(currentfg) $Clock(background) } ClockBind ClockUpdate } proc ClockBind {} { global Clock_window Clock RecursiveBind $Clock_window <1> {Clock_MenuPost %X %Y} if [In $Clock(show) {timeonly dateonly}] { bind $Clock_window +ClockEnter } } proc Clock_MenuPost {x y} { global Clock Clock_window regexp {^(\.[^\.]*)} $Clock_window panel panel TKGPopupPost $Clock(menu) $x $y $panel focus $Clock(menu) grab set -global $Clock(menu) bind $Clock(menu) [subst -nocommands { if [string match ${Clock_window}* \ [eval winfo containing [winfo pointerxy .]]] { break } }] } proc ClockEnter {} { global Clock if !$Clock(entered) { after 800 ClockReToggle set Clock(entered) 1 } } proc ClockReToggle {} { global Clock_window Clock set stillin [string match ${Clock_window}* \ [eval winfo containing [winfo pointerxy .]]] if $stillin { if $Clock(togglestate) { Clock_timedatetoggle set Clock(togglestate) 0 after 800 ClockReToggle } else { after 800 ClockReToggle } } elseif !$Clock(togglestate) { after 250 { Clock_timedatetoggle set Clock(togglestate) 1 set Clock(entered) 0 } } else { set Clock(entered) 0 } } proc ClockInit {} {uplevel \#0 { TKGClientStrings Clock TKGPopupAdd command -label $TKG_labels(Alarm) -command AlarmView TKGPopupAdd separator set Clock_minute_hook "" }} proc ClockCreateWindow {} { global Clock Clock_window TKG TKG_labels Clock_strings Alarm # initialize various stuff set Clock(togglestate) 1 set Clock(entered) 0 set Clock(offset) 0 set Alarm(enablealarms) 0 set Clock(currentfg) $Clock(foreground) setifunset Clock(menu) .tkgpopup TKGLabelBox Clock $Clock_window configure -borderwidth $Clock(border) TKGGrid $Clock_window TKGBalloonBind $Clock_window "Click for menu" ClockUpdate Clock_configure_window } proc ClockStart {} { global Clock # set up async processing set Clock(offset) [expr 60 - [TKGZeroTrim [clock format [clock seconds] -format %S]]] TKGPeriodic Clock_periodic 60 $Clock(offset) ClockUpdate } proc ClockSuspend {} { global Clock_window TKG TKGPeriodicCancel Clock_periodic destroy $Clock_window unset TKG(balloontext,$Clock_window) } DEBUG "Loaded Clock.tcl"