]> git.tuebingen.mpg.de Git - gsu.git/commitdiff
gui: Implement descriptive tree items. pu
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 24 Oct 2023 21:55:27 +0000 (23:55 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Mon, 29 Apr 2024 15:24:56 +0000 (17:24 +0200)
A restriction of the current gui module is that the text shown in the
menu items must also be a valid identifier for the corresponding bash
function. In particular no whitespace is allowed there.

To overcome this restriction we introduce the concept of a menu item
identifier and an optional menu item description. If the description
is absent, the identifier is used as the description, providing
backward compatibility.

README.md
gui
subcommand

index 1fbcef9872ce9f5ef0ae6bb642d8a501993f448b..f08718c3a1d6d57fde03babb18f3056b8a79401e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -431,23 +431,27 @@ contents of the kernel log buffer. Bash code which defines the menu
 tree could look like this:
 
                menu_tree='
-                       load_average
-                       processes
-                       hardware/
-                               cpu
-                               scsi
-                       storage/
-                               df
-                               mdstat
-                       log/
-                               syslog
-                               dmesg
+                       load_average System load
+                       processes Running processes of a user
+                       hardware/ Hardware related information
+                               cpu Show prozessor type and features
+                               scsi Show SCSI devices
+                       storage/ Filesystems and software raid
+                               df List of mounted filesystems
+                               mdstat Status of software raid arrays
+                       log/ System and kernel logs
+                               syslog System log
+                               dmesg Kernel log
                '
 
-In this tree, `hardware/`, `block_devices/` and `log/` are the only
-internal nodes. Note that these are written with a trailing slash
-character while the leaf nodes have no slash at the end. All entries
-of the menu tree must be indented by tab characters.
+Each line of the menu tree consists of an identifier, suffixed with an
+optional slash, and a description. The identifier becomes part of the
+name of a bash function and should only contain alphabetic characters
+and underscores. The description becomes the text shown as the menu
+item. Identifiers suffixed with a slash are regarded as internal nodes
+which represent submenus. In the above tree, `hardware/`, `storage/`
+and `log/` are internal nodes. All entries of the menu tree must be
+properly indented by tab characters.
 
 ___Action handlers___
 
@@ -463,7 +467,7 @@ handler for the `df` node:
                }
 
 The function name `lsi_df` is derived from the name of the script
-(`lsi`) and the name of the leaf node (`df`). The function simply
+(`lsi`) and the identifier of the leaf node (`df`). The function simply
 passes the output of the `df(1)` command as the first argument to the
 public gsu function `gsu_msgbox()` which runs dialog(1) to display
 a message box that shows the given text.
@@ -496,24 +500,24 @@ to do is to source the gsu gui module and to call `gsu_gui()`:
 
 ___Example___
 
-The complete lsi script below can be used as a starting point
-for your own gsu gui application. If you cut and paste it, be
-sure to not turn tab characters into space characters.
+The complete lsi script below can be used as a starting point for your
+own gsu gui application. If you cut and paste it, be sure to not turn
+tab characters into space characters. The script must be named "lsi".
 
                #!/bin/bash
 
                menu_tree='
-                       load_average
-                       processes
-                       hardware/
-                               cpu
-                               scsi
-                       storage/
-                               df
-                               mdstat
-                       log/
-                               syslog
-                               dmesg
+                       load_average System load
+                       processes Running processes of a user
+                       hardware/ Hardware related information
+                               cpu Show prozessor type and features
+                               scsi Show SCSI devices
+                       storage/ Filesystems and software raid
+                               df List of mounted filesystems
+                               mdstat Status of software raid arrays
+                       log/ System and kernel logs
+                               syslog System log
+                               dmesg Kernel log
                '
 
                lsi_load_average()
diff --git a/gui b/gui
index fbcbb01e49dce6d7c6e55045c5286e2652411549..83da0cd6b7c06b117647551b7f0eae14795a1006 100644 (file)
--- a/gui
+++ b/gui
@@ -95,15 +95,16 @@ gsu_msgbox()
 
 _gsu_menu()
 {
-       local header=${1:-root} dflt_item=$2 items=$3
+       local header=$1 dflt_item=$2
        local geom
 
+       shift 2
        _get_geometry
        geom=$result
        result="$(dialog --no-lines --no-items \
                --default-item "$dflt_item" \
-               --menu "$gsu_banner_txt ($header)"  \
-               $geom 16 $items 3>&1 1>&2 2>&3 3>&-)"
+               --menu "$gsu_banner_txt"$'\n'"Current location: $header" \
+               $geom 16 "$@" 3>&1 1>&2 2>&3 3>&-)"
        _set_dialog_ret $?
 }
 
@@ -154,26 +155,46 @@ _get_root_nodes()
 
 _browse()
 {
-       local header=$1 tree=$2
-       local -a subtree=($3)
-       local old_header dflt_item=${subtree[0]}
-
+       local root_item=$1 tree=$2 subtree=$3
+       local -a items arr
+       local -A ids
+       local old_root dflt_item
+       local item id OIFS
+       local -i i=0
+
+       while read -a arr; do
+               ((${#arr[@]} == 0)) && continue
+               id=${arr[0]}
+               if ((${#arr[@]} > 1)); then
+                       unset arr[0];
+                       item=${arr[*]}
+                       if [[ "${id:$((${#id} - 1)):1}" == '/' ]]; then
+                               item+=/
+                       else
+                               item="• $item"
+                       fi
+               else
+                       item=$id
+               fi
+               items[$i]=$item
+               ids["$item"]=$id
+               let i++
+       done <<< "$subtree"
+       dflt_item=${items[0]}
        while :; do
-               _gsu_menu "$header" "$dflt_item" "${subtree[*]}"
+               _gsu_menu "$root_item" "$dflt_item" "${items[@]}"
                ((ret < 0)) && return
-               dflt_item=$result
                [[ -z "$result" ]] && return # menu was cancelled
-               if [[ "${result%/}" != "$result" ]]; then
-                       old_header="$header"
-                       header="$result"
-                       _get_subtree "$tree" "$header"
+               dflt_item=$result
+               id=${ids["$result"]}
+               if [[ "${id:$((${#id} - 1)):1}" == '/' ]]; then
+                       _get_subtree "$tree" "$id"
                        ((ret < 0)) && return
-                       _browse "$header" "$tree" "$result"
+                       _browse "${dflt_item%/}" "$tree" "$result"
                        ((ret < 0)) && return
-                       header="$old_header"
                        continue
                fi
-               eval ${gsu_name}_$result
+               eval ${gsu_name}_${id}
        done
 }
 
@@ -188,5 +209,5 @@ gsu_gui()
        fi
        _get_root_nodes "$tree"
        subtree="$result"
-       _browse "main menu" "$tree" "$subtree"
+       _browse 'Main menu' "$tree" "$subtree"
 }
index e5c0001e4903299e8e9e4f430a03373fd18b0e5a..d37481cdbdccb5b62268d3b788de84b61a2ab347 100644 (file)
@@ -168,20 +168,25 @@ gsu_getopts()
 _gsu_print_available_commands()
 {
        local cmd cmds
-       local -i count=0
+       local -i maxlen=0 cols width=80 count=0
 
+       result=$(stty size 2>/dev/null)
+       if (($? == 0)); then
+               gsu_is_a_number "${result#* }"
+               ((ret >= 0)) && ((result > 0)) && width=$result
+       fi
        _gsu_available_commands
-       cmds="$result"
-       printf 'Available commands:\n'
+       cmds=$result
+       for cmd in $cmds; do
+               ((${#cmd} > maxlen)) && maxlen=${#cmd}
+       done
+       let maxlen++
+       ((width < maxlen)) && cols=1 || cols=$((width / maxlen))
+       printf 'Available commands:'
        for cmd in $cmds; do
-               printf '%s' "$cmd"
+               ((count % cols == 0)) && printf '\n'
+               printf '%-*s' $maxlen $cmd
                let ++count
-               if ((count % 4)); then
-                       printf '\t'
-                       ((${#cmd} < 8)) && printf '\t'
-               else
-                       printf '\n'
-               fi
        done
        printf '\n'
 }
@@ -679,7 +684,21 @@ com_help()
                                y/\n/'"$tab"'/
 
                                # and print the sucker
-                               p'
+                               p
+                       ' | {
+                               local -a cmds=() descs=()
+                               local -i i maxlen=1
+                               local cmd desc
+                               while read cmd desc; do
+                                       ((maxlen < ${#cmd})) && maxlen=${#cmd}
+                                       cmds[${#cmds[@]}]=$cmd
+                                       descs[${#descs[@]}]=$desc
+                               done
+                               for ((i = 0; i < ${#cmds[@]}; i++)); do
+                                       printf '%-*s %s\n' $maxlen ${cmds[$i]} \
+                                               "${descs[$i]}"
+                               done
+                       }
                printf "\n# Try %s help <command> for info on <command>, or %s help -a to see\n" \
                        "$gsu_name" "$gsu_name"
                printf '# also the subcommands which are automatically generated by gsu.\n'