It is almost never safe to assume your code is perfect

Geoff Canyon gcanyon at gmail.com
Fri Oct 4 00:36:40 CEST 2013


Back in 2005(!) Malte came up with the brilliant idea of using oval
graphics with their arcangle set to 0 in order to easily create the hands
of a clock. Interestingly, the rendering of oval graphics seems to have
changed since then -- setting the arcangle to 0 now doesn't draw the angle
itself, so there is no hand. You can still set the arcangle to something
like 5 and the linesize to 10 to get the tip of a hand the way some stylish
clocks/watches do.

Malte posted his 12 line solution, and others set about improving it. Here
was my final entry, which I remember being quite happy with:


on openCard
   setTime
end openCard

local sHourAngle -- the angle for the hour hand
local sMinuteAngle -- the angle for the minute hand

on setTime
   put word 1 of the long time into T
   put T && the long seconds into fld "time"
   split T using ":"
   get 90 - (30 * T[1]) - trunc(T[2] / 2)
   if it is not sHourAngle then
     put it into sHourAngle
     set the startangle of grc "hour" to sHourAngle
   end if
   get 90 - (6 * T[2]) - trunc(T[3] / 10)
   if it is not sMinuteAngle then
     put it into sMinuteAngle
     set the startangle of grc "minute" to sMinuteAngle
   end if
   set the startangle of grc "second" to 90 - (6 * T[3])
   send "setTime" to me in (1 - (the long seconds mod 1)) seconds
end setTime


It requires two local variables and is 17 lines long -- 5 lines longer than
Malte's, but more efficient because of its send..in construction, and
because it only updates the minute and hour hands when needed.


Here is the original
thread<http://lists.runrev.com/pipermail/use-livecode/2005-May/058249.html>.
It came up in conversation today, so I went and looked it up. Of course,
looking at my code now, I immediately see it for the glaring hack job that
it is. Here is my update, in 11 lines counting the "on" and "end," and
still only updating the minute and hour hands when needed.


on mouseUp
   setTime
end mouseUp

on setTime
   put word 1 of the long time into T
   put T && the long seconds into fld "time"
   split T using ":"
   set the startangle of grc "second" to 90 - (6 * T[3])
   if T[3] mod 10 = 0 then
      set the startangle of grc "minute" to 90 - (6 * T[2]) - (T[3] div 10)
      if T[2] mod 2 = 0 then set the startangle of grc "hour" to 90 - (30 *
T[1]) - (T[2] div 2)
   end if
   send "setTime" to me in (1 - (the long seconds mod 1)) seconds
end setTime

I could drop it a further two lines with this in place of the if structure:

on setTime
   put word 1 of the long time into T
   put T && the long seconds into fld "time"
   split T using ":"
   set the startangle of grc "second" to 90 - (6 * T[3])
   if T[3] mod 10 = 0 then set the startangle of grc "minute" to 90 - (6 *
T[2]) - (T[3] div 10)
   if T[3] mod 10 = 0 and  T[2] mod 2 = 0 then set the startangle of grc
"hour" to 90 - (30 * T[1]) - (T[2] div 2)
   send "setTime" to me in (1 - (the long seconds mod 1)) seconds
end setTime

Never be satisfied.

gc


More information about the use-livecode mailing list