Stopwatch

A simple stopwatch, with one-millisecond resolution.

screenshot

stopwatch

#!/usr/bin/pinafore
import "pinafore-gnome" in
with GTK. in
let

    datatype State of
        Stopped Duration;
        Running Time;
    end;

    toggleStopwatch: WholeModel +Time -> WholeModel State -> Action Unit =
    fn now, r =>
    do
        n <- get now;
        oldstate <- get r;
        newstate <-
            pure $
            oldstate >-
            match
                Stopped.State d => Running.State $ negate.Duration d +.Time n;
                Running.State t => Stopped.State $ n -.Time t
            end;
        r := newstate;
    end;

    showStopwatch: State -> Time -> Text =
    fn state, n =>
    state >-
    match
        Stopped.State d => "[" <>.Text show d <>.Text "]";
        Running.State t => show $ n -.Time t
    end;

    ui: WholeModel +Time -> WholeModel State -> Widget =
    fn now, r =>
    button.Widget {showStopwatch %r %now} {toggleStopwatch now r};

in
do
    now <- newClock.Time $ Seconds 0.001;
    r <- newMem.WholeModel;
    r := Stopped.State zero.Duration;
    run $
        fn gtk =>
        open.Window gtk (150,40) {"Stopwatch"} $ ui now r;
end