163 lines
5.6 KiB
Bash
Executable File
163 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# TUI timer setter — vim keys, big-digit hh:mm:ss
|
|
|
|
# ── Setup ──────────────────────────────────────────────────────────────────────
|
|
cleanup() { tput cnorm; tput rmcup; }
|
|
trap cleanup EXIT INT TERM
|
|
|
|
tput smcup
|
|
tput civis
|
|
|
|
# ── Colors ─────────────────────────────────────────────────────────────────────
|
|
R="$(tput sgr0)"
|
|
NORMAL="$(tput bold)$(tput setaf 7)"
|
|
SELECT="$(tput bold)$(tput setaf 6)" # cyan — active field
|
|
TITLE="$(tput bold)$(tput setaf 5)" # magenta
|
|
DIM="$(tput dim)$(tput setaf 7)"
|
|
ERR="$(tput bold)$(tput setaf 1)" # red
|
|
|
|
# ── Block digits — DIGITS[digit*5 + row] ───────────────────────────────────────
|
|
DIGITS=(
|
|
"█████" "█ █" "█ █" "█ █" "█████" # 0
|
|
" █ " " █ " " █ " " █ " " █ " # 1
|
|
"█████" " █" "█████" "█ " "█████" # 2
|
|
"█████" " █" "█████" " █" "█████" # 3
|
|
"█ █" "█ █" "█████" " █" " █" # 4
|
|
"█████" "█ " "█████" " █" "█████" # 5
|
|
"█████" "█ " "█████" "█ █" "█████" # 6
|
|
"█████" " █" " █" " █" " █" # 7
|
|
"█████" "█ █" "█████" "█ █" "█████" # 8
|
|
"█████" "█ █" "█████" " █" "█████" # 9
|
|
)
|
|
COLON=(" " "█" " " "█" " ")
|
|
|
|
# ── State ──────────────────────────────────────────────────────────────────────
|
|
VALUES=(0 0 0)
|
|
LIMITS=(23 59 59)
|
|
LABELS=("HOURS" "MINUTES" "SECONDS")
|
|
FIELD=0
|
|
SHOW_ERR=0
|
|
|
|
# ── Draw helpers ───────────────────────────────────────────────────────────────
|
|
draw_field() { # draw_field row col val active
|
|
local y=$1 x=$2 val=$3 active=$4
|
|
local tens=$((val / 10)) units=$((val % 10))
|
|
local color; [[ $active -eq 1 ]] && color=$SELECT || color=$NORMAL
|
|
for row in 0 1 2 3 4; do
|
|
tput cup $((y + row)) $x
|
|
printf '%s%s %s%s' \
|
|
"$color" \
|
|
"${DIGITS[$((tens * 5 + row))]}" \
|
|
"${DIGITS[$((units * 5 + row))]}" \
|
|
"$R"
|
|
done
|
|
}
|
|
|
|
draw_colon() { # draw_colon row col
|
|
local y=$1 x=$2
|
|
for row in 0 1 2 3 4; do
|
|
tput cup $((y + row)) $((x + 1))
|
|
printf '%s%s%s' "$DIM" "${COLON[$row]}" "$R"
|
|
done
|
|
}
|
|
|
|
draw() {
|
|
local W H
|
|
W=$(tput cols); H=$(tput lines)
|
|
|
|
printf '\033[2J\033[H' # clear + home (no flicker vs tput clear)
|
|
|
|
# Title
|
|
local title="─── T I M E R ───"
|
|
tput cup 2 $(( (W - ${#title}) / 2 ))
|
|
printf '%s%s%s' "$TITLE" "$title" "$R"
|
|
|
|
# Layout: field(11) + colon(3) + field(11) + colon(3) + field(11) = 39 wide
|
|
local sx=$(( (W - 39) / 2 ))
|
|
local dy=$(( (H - 5) / 2 - 1 ))
|
|
(( dy < 4 )) && dy=4
|
|
|
|
local -a fx=( $sx $((sx + 14)) $((sx + 28)) )
|
|
local -a cx=( $((sx + 11)) $((sx + 25)) )
|
|
|
|
for i in 0 1 2; do
|
|
local active=0; [[ $i -eq $FIELD ]] && active=1
|
|
draw_field $dy "${fx[$i]}" "${VALUES[$i]}" $active
|
|
done
|
|
for x in "${cx[@]}"; do
|
|
draw_colon $dy $x
|
|
done
|
|
|
|
# Labels
|
|
local ly=$((dy + 6))
|
|
for i in 0 1 2; do
|
|
local label="${LABELS[$i]}"
|
|
local lx=$(( fx[$i] + (11 - ${#label}) / 2 ))
|
|
tput cup $ly $lx
|
|
if [[ $i -eq $FIELD ]]; then
|
|
printf '%s%s%s' "$SELECT" "$label" "$R"
|
|
else
|
|
printf '%s%s%s' "$DIM" "$label" "$R"
|
|
fi
|
|
done
|
|
|
|
# Error
|
|
if [[ $SHOW_ERR -eq 1 ]]; then
|
|
local msg="set a non-zero time first"
|
|
tput cup $((ly + 2)) $(( (W - ${#msg}) / 2 ))
|
|
printf '%s%s%s' "$ERR" "$msg" "$R"
|
|
fi
|
|
|
|
# Hint
|
|
local hint="h/l field j/k adjust Enter start q cancel"
|
|
tput cup $((H - 2)) $(( (W - ${#hint}) / 2 ))
|
|
printf '%s%s%s' "$DIM" "$hint" "$R"
|
|
}
|
|
|
|
# ── Key reader — handles ESC sequences (arrow keys) ───────────────────────────
|
|
read_key() {
|
|
local key seq
|
|
IFS= read -rsn1 key
|
|
if [[ "$key" == $'\033' ]]; then
|
|
IFS= read -rsn2 -t 0.05 seq 2>/dev/null || true
|
|
key="$key$seq"
|
|
fi
|
|
printf '%s' "$key"
|
|
}
|
|
|
|
# ── Main loop ──────────────────────────────────────────────────────────────────
|
|
while true; do
|
|
draw
|
|
SHOW_ERR=0
|
|
key=$(read_key)
|
|
|
|
case "$key" in
|
|
q|$'\033')
|
|
exit 0
|
|
;;
|
|
h|$'\033[D')
|
|
FIELD=$(( (FIELD + 2) % 3 ))
|
|
;;
|
|
l|$'\033[C')
|
|
FIELD=$(( (FIELD + 1) % 3 ))
|
|
;;
|
|
k|$'\033[A')
|
|
VALUES[$FIELD]=$(( (VALUES[$FIELD] + 1) % (LIMITS[$FIELD] + 1) ))
|
|
;;
|
|
j|$'\033[B')
|
|
VALUES[$FIELD]=$(( (VALUES[$FIELD] - 1 + LIMITS[$FIELD] + 1) % (LIMITS[$FIELD] + 1) ))
|
|
;;
|
|
$'\n'|$'\r')
|
|
total=$(( VALUES[0] * 3600 + VALUES[1] * 60 + VALUES[2] ))
|
|
if (( total == 0 )); then
|
|
SHOW_ERR=1
|
|
else
|
|
label=$(printf '%02d:%02d:%02d' "${VALUES[0]}" "${VALUES[1]}" "${VALUES[2]}")
|
|
setsid bash "$HOME/.config/scripts/timer-notify.sh" "$total" "$label" &>/dev/null &
|
|
disown
|
|
exit 0
|
|
fi
|
|
;;
|
|
esac
|
|
done
|