You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
3.9 KiB
244 lines
3.9 KiB
#!/usr/bin/env bash
|
|
|
|
# GLOBALS
|
|
|
|
declare UI_CROW UI_CCOL USER_INPUT
|
|
|
|
# TERMINAL AND CURSOR INFO
|
|
|
|
term_size() case $1 in
|
|
c) echo $(tput cols)
|
|
;;
|
|
l) echo $(tput lines)
|
|
;;
|
|
*) echo $(tput lines) $(tput cols)
|
|
esac
|
|
|
|
cursor_position() {
|
|
echo $UI_CROW $UI_CCOL
|
|
}
|
|
|
|
cursor_line() {
|
|
echo $UI_CROW
|
|
}
|
|
|
|
cursor_col() {
|
|
echo $UI_CCOL
|
|
}
|
|
|
|
# CURSOR POSITION
|
|
|
|
cursor_set() {
|
|
UI_CROW=$1
|
|
UI_CCOL=$2
|
|
tput cup $UI_CROW $UI_CCOL
|
|
}
|
|
|
|
cmove_top() {
|
|
UI_CROW=0
|
|
UI_CCOL=${1:-0}
|
|
cursor_set $UI_CROW $UI_CCOL
|
|
}
|
|
|
|
cmove_bottom() {
|
|
UI_CROW=$(( $(term_size l) - 1 ))
|
|
UI_CCOL=${1:-0}
|
|
cursor_set $UI_CROW $UI_CCOL
|
|
}
|
|
|
|
cmove_row() {
|
|
UI_CROW=$1
|
|
cursor_set $UI_CROW $UI_CCOL
|
|
}
|
|
|
|
cmove_col() {
|
|
UI_CCOL=$1
|
|
cursor_set $UI_CROW $UI_CCOL
|
|
}
|
|
|
|
cmove_up() {
|
|
local mv
|
|
mv=${1:-1}
|
|
: $((UI_CROW - $mv))
|
|
UI_CROW=$(( $_ >= 0 ? (UI_CROW - mv) : 0 ))
|
|
cmove_row $UI_CROW
|
|
}
|
|
|
|
cmove_down() {
|
|
local mv limit
|
|
mv=${1:-1}
|
|
limit=$(($(term_size l) - 1))
|
|
: $((UI_CROW + $mv))
|
|
UI_CROW=$(( $_ < limit ? (UI_CROW + mv) : limit ))
|
|
cmove_row $UI_CROW
|
|
}
|
|
|
|
cmove_left() {
|
|
local mv
|
|
mv=${1:-1}
|
|
: $((UI_CCOL - $mv))
|
|
UI_CCOL=$(( $_ >= 0 ? (UI_CCOL - mv) : 0 ))
|
|
cmove_col $UI_CCOL
|
|
}
|
|
|
|
cmove_right() {
|
|
local mv limit
|
|
mv=${1:-1}
|
|
limit=$(($(term_size c) - 1))
|
|
: $((UI_CCOL + $mv))
|
|
UI_CCOL=$(( $_ < limit ? (UI_CCOL + mv) : limit ))
|
|
cmove_col $UI_CCOL
|
|
}
|
|
|
|
cmove_home() {
|
|
UI_CCOL=0
|
|
cmove_col $UI_CCOL
|
|
}
|
|
|
|
cmove_end() {
|
|
UI_CCOL=$(($(term_size c) - 1))
|
|
cmove_col $UI_CCOL
|
|
}
|
|
|
|
# CLEAR TERMINAL, LINE AND REGION
|
|
|
|
clear_terminal() {
|
|
clear
|
|
UI_CROW=0
|
|
UI_CCOL=0
|
|
}
|
|
|
|
clear_line() {
|
|
UI_CROW=${1:-$(cursor_line)}
|
|
cursor_set $UI_CROW 0
|
|
tput el
|
|
}
|
|
|
|
clear_region() {
|
|
local row col width height fill line
|
|
|
|
row=$1
|
|
col=$2
|
|
width=$3
|
|
height=$((row + $4 - 1))
|
|
|
|
printf -v fill "%${width}s" ''
|
|
|
|
for line in $(seq -s ' ' $row $height ); do
|
|
cursor_set $line $col
|
|
printf '%s' "$fill"
|
|
done
|
|
}
|
|
|
|
# FRAMES AND WINDOWS
|
|
|
|
draw_frame() {
|
|
local row col width height fill line
|
|
|
|
row=$1
|
|
col=$2
|
|
width=$3
|
|
height=$((row + $4 - 2))
|
|
|
|
printf -v fill "%$((width - 2))s" ''
|
|
|
|
cursor_set $row $col
|
|
printf '%s' "┌${fill// /─}┐"
|
|
((row++))
|
|
for line in $(seq -s ' ' $row $height ); do
|
|
cursor_set $line $col
|
|
printf '%s' "│${fill}│"
|
|
((row++))
|
|
done
|
|
cursor_set $row $col
|
|
printf '%s' "└${fill// /─}┘"
|
|
}
|
|
|
|
draw_title_bar() {
|
|
local fill
|
|
printf -v fill "%$(($3 - 2))s" ''
|
|
cursor_set $(( $1 + 2 )) $2
|
|
printf '%s' "├${fill// /─}┤"
|
|
}
|
|
|
|
draw_status_bar() {
|
|
local fill
|
|
printf -v fill "%$(($3 - 2))s" ''
|
|
cursor_set $(($1 + $4 - 3)) $2
|
|
printf '%s' "├${fill// /─}┤"
|
|
}
|
|
|
|
# STRINGS
|
|
|
|
print_label() {
|
|
local str align col_start col_end column line_width len
|
|
|
|
str="$1"
|
|
len=$(str_len "$str")
|
|
col_start=0
|
|
col_end=$(term_size c)
|
|
align=left
|
|
|
|
case $# in
|
|
2) if in_string 'left right center' "$2"; then
|
|
align=$2
|
|
else
|
|
col_start=${2%,*}
|
|
col_end=${2#*,}
|
|
fi
|
|
;;
|
|
3) align=$2
|
|
col_start=${3%,*}
|
|
col_end=$((${3#*,} + 1))
|
|
;;
|
|
esac
|
|
|
|
line_width=$(( col_end - col_start ))
|
|
|
|
case $align in
|
|
left) column=$col_start;;
|
|
right) column=$((col_start + line_width - len));;
|
|
center) column=$((col_start + ((line_width - len) / 2) ));;
|
|
esac
|
|
|
|
cursor_set $UI_CROW $column
|
|
printf '%s' "$str"
|
|
}
|
|
|
|
str_len() {
|
|
echo "${#1}"
|
|
}
|
|
|
|
in_string() [[ "$1" == *"$2"* ]]
|
|
|
|
# WIDGETS
|
|
|
|
input_bar() {
|
|
local prompt position border line
|
|
|
|
prompt="$1"
|
|
position=bottom
|
|
border=1
|
|
line=$(($(term_size l) - 3))
|
|
|
|
case $# in
|
|
2) in_string 'top bottom' "$2" && position=$2 || border=$2;;
|
|
3) position=$2; border=$3;;
|
|
esac
|
|
|
|
if ((border)); then
|
|
[[ $position = top ]] && line=0
|
|
draw_frame $line 0 $(term_size c) 3
|
|
cmove_up
|
|
cmove_right 2
|
|
else
|
|
case $position in
|
|
top) cmove_top 1;;
|
|
bottom) cmove_bottom 1;;
|
|
esac
|
|
fi
|
|
|
|
read -rep "$prompt " USER_INPUT
|
|
}
|
|
|
|
|
|
|