#! /usr/bin/env bash ###### Default environment variables ###### STOPWATCH_LABEL=${STOPWATCH_LABEL:-stopwatch} TIMER_LABEL=${TIMER_LABEL:-timer} DEFAULT_MODE=${DEFAULT_MODE:-timer} DEFAULT_STOPWATCH=${DEFAULT_STOPWATCH:-0} DEFAULT_TIMER=${DEFAULT_TIMER:-60} PLAY_LABEL=${PLAY_LABEL:-(playing)} PAUSE_LABEL=${PAUSE_LABEL:-(paused)} TIMER_LOOP=${TIMER_LOOP:-false} NEUTRAL_COLOR=${NEUTRAL_COLOR:-#000000} ###### Default environment variables ###### ###### Functions ###### error() { echo Error: "$@" 1>&2 } next_mode() { mode=$(( (mode + 1) % ${#modes[@]} )) set_mode } play_pause() { $running && pause || play } play() { running=true status_symbol=$PLAY_LABEL } pause() { running=false status_symbol=$PAUSE_LABEL } reset_times() { unset time set_mode } set_mode() { case ${modes[$mode]} in 'timer' ) running=false status_symbol=$PAUSE_LABEL initial_time=${initial_time-$DEFAULT_TIMER} time=$initial_time incr=-1 ;; 'stopwatch' ) running=false status_symbol=$PAUSE_LABEL time=${time-$DEFAULT_STOPWATCH} fgcolor='#FFFFFF' bgcolor=$NEUTRAL_COLOR incr=1 ;; esac } compute_color() { t=$1 hue360=$(( 120*t/initial_time )) tmp=$(( hue360 % 120 - 60 )) tmp=$(( (60 - ${tmp#-})*255/60 )) if (( hue360 < 60 && hue360 >= 0 )); then R=255 G=$tmp B=0 elif (( hue360 <= 120 && hue360 >= 60 )); then R=$tmp G=255 B=0 fi printf '#%06X\n' $(( R*16*16*16*16 + G*16*16 + B )) } prettify_time() { seconds=$time if (( time >= 60 )); then minutes=$(( time / 60 )) seconds=$(( time % 60 )) (( seconds < 10 )) && seconds=0$seconds fi if (( minutes >= 60 )); then hours=$(( minutes / 60 )) minutes=$(( minutes % 60 )) (( minutes < 10 )) && minutes=0$minutes fi echo $hours${hours+:}$minutes${minutes+:}$seconds } ###### Functions ###### ###### Internal variables ###### modes=([0]='timer' [1]='stopwatch') labels=([0]="$TIMER_LABEL" [1]="$STOPWATCH_LABEL") ###### Internal variables ###### ###### First run initialization ###### if [[ ! -v time ]]; then for i in "${!modes[@]}"; do if [[ "${modes[$i]}" == "$DEFAULT_MODE" ]]; then mode=$i fi done set_mode fi ###### First run initialization ###### ###### Click processing ###### case $BLOCK_BUTTON in 1 ) play_pause ;; 2 ) reset_times ;; 3 ) next_mode reset_times pause ;; 4 ) $running && pause initial_time=$(( initial_time + 1 )) time=$initial_time ;; 5 ) $running && pause initial_time=$(( initial_time - 1 )) time=$initial_time ;; esac ###### Click processing ###### ###### Time increment ###### $running && time=$(( time + incr )) if (( mode == 0 )); then if (( time <= 0 )); then bgcolor='#FF0000' fgcolor=$NEUTRAL_COLOR time=0 pause elif (( time > 0 )); then fgcolor=$(compute_color $time) bgcolor=$NEUTRAL_COLOR fi else bgcolor=$NEUTRAL_COLOR fgcolor='#FFFFFF' fi full_text="${labels[$mode]} $status_symbol $(prettify_time)" if (( mode == 0 && time == 0 )); then $TIMER_LOOP && reset_times && play fi ###### Time increment ###### ###### Output ###### cat << EOF {"full_text":"$full_text",\ "status_symbol":"$status_symbol",\ "time":"$time",\ "initial_time":"$initial_time",\ "incr":"$incr",\ "running":"$running",\ "mode":"$mode",\ "color":"$fgcolor",\ "background":"$bgcolor"} EOF ###### Output ######