RGBA Clock
Tuesday, August 29, 2023
Today, I’d like to build a little UI gadget clock that changes color as the time changes in Factor.
Unix time is measured as the time – usually seconds – since the Unix epoch at 00:00:00 UTC on January 1, 1970. It is used on many systems and, perhaps, will cause Year 2038 problems on some when it exceeds the maximum value of a signed 32-bit integer.
This is perfect – we need a way to convert a timestamp into a rgba color – we can calculate a unix time in integer seconds and then take each 8-bit segment to refer to a red, green, blue, and alpha value.
: timestamp>rgba ( timestamp -- color/f )
timestamp>unix-time >integer
24 2^ /mod 16 2^ /mod 8 2^ /mod
[ 255 /f ] 4 napply <rgba> ;
We can then extend a UI
label to
have a timer that starts when the gadget becomes visible and updates its
background colors based on the current
time and chooses
an appropriate foreground text color to match. For that we can use the
contrast-text-color
word from the colors.contrast
vocabulary to
select either white-over-background or black-over-background depending on
the relative luminance of
the background color.
TUPLE: rgba-clock < label timer ;
M: rgba-clock graft*
[ timer>> start-timer ] [ call-next-method ] bi ;
M: rgba-clock ungraft*
[ timer>> stop-timer ] [ call-next-method ] bi ;
: update-colors ( color label -- )
[ [ contrast-text-color ] dip font>> foreground<< ]
[ [ <solid> ] dip interior<< ] 2bi ;
: <rgba-clock> ( -- gadget )
"99:99:99" rgba-clock new-label
monospace-font >>font
dup '[
_ now
[ timestamp>hms >>string ]
[ timestamp>rgba swap update-colors ] bi
] f 1 seconds <timer> >>timer ;
And then we can try it out!
IN: scratchpad <rgba-clock> gadget.
This is on my GitHub.