Re: Factor

Factor: the language, the theory, and the practice.

RGBA Clock

Tuesday, August 29, 2023

#colors #time #ui

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.