From c53b179ee3e4fe45a90f578e1e63852a0a2d6df1 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Fri, 23 Sep 2011 14:04:23 +0200 Subject: [PATCH] Add gsu_gui. The dialog-based shell library for earth-shaking graphical user interfaces that don't suck. Its main entry function gsu_gui() allows to pass a tree to control the menus. --- misc/gsu/gui | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 misc/gsu/gui diff --git a/misc/gsu/gui b/misc/gsu/gui new file mode 100644 index 0000000..30c95a4 --- /dev/null +++ b/misc/gsu/gui @@ -0,0 +1,207 @@ +#!/bin/bash + +if [[ $(type -t gsu_is_a_number) != "function" ]]; then + GSU_DIR=${GSU_DIR:=$HOME/.gsu} + . $GSU_DIR/common || exit 1 +fi + +export GSU_NODE_NAME_PATTERN='[a-zA-Z_]' + +get_geometry() +{ + local x y + result="$(stty size)" + if (($? != 0)); then + gsu_msg "fatal: could not get terminal geometry" + exit 1 + fi + x="${result#* }" + y="${result%% *}" + (($x > 190)) && x=190 + result="$y $x" +} + +gsu_infobox() +{ + get_geometry + dialog --infobox "$1" $result +} + +gsu_checklist_all_on() +{ + local header="$1" + local items="$2" + local i state opts num=0 + + get_geometry + ops="$result 16" + for i in $items; do + let num++ + opts+=" $i $num on" + done + result=$(dialog --checklist "$header" $opts 3>&1 1>&2 2>&3 3>&-) + ret="$?" +} + +gsu_radiolist() +{ + local header="$1" + local selected_item="$2" + local items="$3" + local i state ops num=0 + + get_geometry + ops="$result 16" + for i in $items; do + let num++ + if [[ "$i" == "$selected_item" ]]; then + state="on" + else + state="off" + fi + ops+=" $i $num $state" + done + result=$(dialog --radiolist "$header" $ops 3>&1 1>&2 2>&3 3>&-) + ret="$?" +} + +gsu_inputbox() +{ + local g text="$1" init="$2" + + get_geometry + g="$result" + result="$(dialog --inputbox "$text" $g "$init" 3>&1 1>&2 2>&3 3>&-)" + ret="$?" +} + +gsu_textbox() +{ + local file="$1" + + get_geometry + dialog --textbox "$file" $result +} + +# dialog segfaults if message is too long. Hence we always use a temporary file +gsu_msgbox() +{ + local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)" + + if (($? != 0)); then + dialog --msgbox "mktemp error" 0 0 + return + fi + echo "$1" > "$tmp" + gsu_textbox "$tmp" + rm -f "$tmp" +} + +gsu_cmd_output_box() +{ + local tmp="$(mktemp)" + + if (($? != 0)); then + dialog --msgbox "mktemp error" 0 0 + return + fi + $@ > "$tmp" 2>&1 + echo "exit code: $?" >> "$tmp" + gsu_textbox "$tmp" + rm -f "$tmp" +} + +gsu_yesno() +{ + local text="$1" + + get_geometry + dialog --yesno "$text" $result + ret=$? + if (($ret == 0)); then + result="yes" + elif (($ret == 1)); then + result="no" + else + result= + fi +} + +gsu_menu() +{ + local header="${1:-root}" + local items="$2" + local i state opts num=0 + + get_geometry + opts="$result 16" + for i in $items; do + let num++ + opts+=" $i $num" + done + result="$(dialog --menu "$header" $opts 3>&1 1>&2 2>&3 3>&-)" + ret="$?" +} + +_get_level() +{ + local tmp="${1%%$GSU_NODE_NAME_PATTERN*}" + result="${#tmp}" +} + +_get_subtree() +{ + local tree="$1" root="${2%/}" + local TAB=' ' + + first="$(grep -n "$root/" <<< "$tree")" + [[ -z "$first" ]] && return + + line_num="${first%%:*}" + _get_level "${first#*:}" + level="$result" + + #echo "line: $line_num, root: $root, indent level: $level" + result="$(sed -e "1,${line_num}d;" <<< "$tree" \ + | sed -e "/^$TAB\{1,$level\}$GSU_NODE_NAME_PATTERN/,\$d" \ + | sed -e "/^$TAB\{$(($level + 2))\}/d")" + ret="$level" +} + +_get_root_nodes() +{ + local tree="$1" TAB=' ' + + result="$(grep "^${TAB}${GSU_NODE_NAME_PATTERN}" <<< "$tree")" +} + +_browse() +{ + local header="$1" old_header + local tree="$2" subtree="$3" + + while :; do + gsu_menu "$header" "$subtree" + (($ret != 0)) && return + [[ -z "$result" ]] && return + if [[ "${result%/}" != "$result" ]]; then + old_header="$header" + header="$result" + _get_subtree "$tree" "$header" + _browse "$header" "$tree" "$result" + header="$old_header" + continue + fi + eval ${gsu_name}_$result + done +} + +gsu_gui() +{ + local tree="$1" subtree + + _gsu_setup + _get_root_nodes "$tree" + subtree="$result" + _browse "$gsu_name main menu" "$tree" "$subtree" +} -- 2.30.2