diff options
-rw-r--r-- | src/ui/tui.sh | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/ui/tui.sh b/src/ui/tui.sh index df7eeb5..2049fcc 100644 --- a/src/ui/tui.sh +++ b/src/ui/tui.sh @@ -170,6 +170,148 @@ tui_show_menu() { local title="${1}" shift 1 + local w= + local label= + local lsth= + local scrh= + local scrbh= + local h= + local y= + local x= + local i= + local bline='' + local lline='' + local focus=0 + local scrbpos= + local scrpos=0 + local curpos=0 + + # Calculate size and draw the box. + w=$(expr ${#title} + 4) + for label in "${@}"; do + if [ $(expr ${#label} + 6) -gt ${w} ]; then + w=$(expr ${#label} + 6) + fi + done + lsth=${#} + h=$(($lsth + 8)) + if [ ${h} -gt $(term_lines) ]; then + h=$(term_lines) + fi + scrh=$(($h - 8)) + scrbh=$(($scrh * $scrh / $lsth)) + read -r y x <<-EOF + $(_tui_box ${w} ${h}) + EOF + + # Build box and label lines. + i=0 + while [ ${i} -lt $(($w - 6)) ]; do + bline="${bline}-" + lline="${lline} " + i=$(($i + 1)) + done + + # Write the title. + term_cursor_down 1 + term_cursor_forward 2 + term_write "${title}" + + # Event loop. + while :; do + # Draw a button. + term_cursor_position $(($y + $h - 2)) $(($x + $w - 6)) + if [ ${focus} -eq 1 ]; then + term_attr_on reverse + term_write '[OK]' + term_attr_off reverse + else + term_write '[OK]' + fi + + # Draw a box. + term_cursor_position $(($y + 3)) $(($x + 2)) + term_write "+${bline}+" + term_cursor_position $(($y + $h - 4)) $(($x + 2)) + term_write "+${bline}+" + i=0 + # Add ${lsth} - 1 to always round up to the next integer. + scrbpos=$(expr \ + \( ${scrpos} \* ${scrh} + ${lsth} - 1 \) / ${lsth}) + while [ ${i} -lt ${scrh} ]; do + term_cursor_position $(($y + 4 + $i)) $(($x + 2)) + term_write '|' + term_cursor_position $(($y + 4 + $i)) $(($x + $w - 3)) + if [ ${i} -ge ${scrbpos} ] && \ + [ ${i} -lt $(($scrbpos + $scrbh)) ] + then + term_attr_on reverse + term_write ' ' + term_attr_off reverse + else + term_write '|' + fi + i=$(($i + 1)) + done + + # Draw labels. + i=0 + for label in "${@}"; do + [ ${i} -ge ${scrpos} ] || continue + [ ${i} -lt $(($scrpos + $scrh)) ] || break + if [ ${i} -eq ${curpos} ]; then + term_attr_on reverse + term_cursor_position \ + $(($y + 4 + $i - $scrpos)) $(($x + 3)) + term_write "${lline}" + term_cursor_position \ + $(($y + 4 + $i - $scrpos)) $(($x + 3)) + term_write "${label}" + term_attr_off reverse + else + term_cursor_position \ + $(($y + 4 + $i - $scrpos)) $(($x + 3)) + term_write "${lline}" + term_cursor_position \ + $(($y + 4 + $i - $scrpos)) $(($x + 3)) + term_write "${label}" + fi + i=$(($i + 1)) + done + + # Input. + key="$(term_getch)" + if [ "x${key}" = xKEY_TAB ]; then + focus=$(expr \( ${focus} + 1 \) % 2) + elif [ ${focus} -eq 0 ]; then + case "${key}" in + KEY_ENTER) break;; + KEY_UP) + [ ${curpos} -gt 0 ] || continue + curpos=$(($curpos - 1)) + # TODO: scrpos + ;; + KEY_DOWN) + [ ${curpos} -lt ${lsth} ] || continue + curpos=$(($curpos + 1)) + # TODO: scrpos + ;; + KEY_HOME) + curpos=0 + scrpos=0 + ;; + KEY_END) + curpos=$(($lsth - 1)) + # TODO: scrpos + ;; + KEY_*);; + esac + elif [ ${focus} -eq 1 ]; then + case "${key}" in + KEY_ENTER | KEY_SPACE) break;; + esac + fi + done return 0 } |