Автор Гілка: Тренінг по bash: урок 3  (Прочитано 2366 раз)

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Я бачу що людям не цікаво займатися простими речами тому пропоную зробити щось веселіше.

Напишіть функцію для виводу меню з рамкою, підсвіткою вибраного пункту меню, керуванням клавішами курсору та вибором пункту меню по клавіші Enter.
[Fedora Linux]

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Тренінг по bash: урок 3
« Відповідей #1 : 2007-10-25 14:13:32 »
#!/bin/bash

set -ue

clear

gotoxy() {
  local x="$1"
  local y="$2"
  
  tput cup "$y" "$x"
}

#
# Draw vertical line at given column.
#
vline() {
  local x="$1"
  local from_y="$2"
  local to_y="$3"
  
  local y
  for((y=$from_y;y<=$to_y;y++))
  do
    gotoxy "$x" "$y"
    echo -n "#"
  done
}

#
# Draw horizontal line at given row.
#
hline() {
  local y="$1"
  local from_x="$2"
  local to_x="$3"
  
  gotoxy "$from_x" "$y"
  
  local x
  for((x=$from_x;x<=$to_x;x++))
  do
    echo -n "#"
  done
}

box() {
  local from_x="$1"
  local from_y="$2"
  local to_x="$3"
  local to_y="$4"
  
  vline "$from_x" "$from_y" "$to_y"
  vline "$to_x" "$from_y" "$to_y"
  
  hline "$from_y" "$from_x" "$to_x"
  hline "$to_y" "$from_x" "$to_x"
}

bold() {
  tput smso
}

offbold() {
  tput rmso
}

draw_item() {
  local x="$1"
  local y="$2"
  local i="$3"
  local ITEM="$4"
  
  gotoxy $(($x+2)) $(($y + $i+2))
  echo -n "$ITEM"
  let i=i+1
}

refresh_menu() {
  local x="$1"
  local y="$2"
  local pos="$3"
  shift 3
  
  local i=0 ITEM
  for ITEM in "$@"
  do
    [[ $pos == $i ]] && bold
    draw_item $x $y $i "$ITEM"
    [[ $pos == $i ]] && offbold
    let i=i+1
  done
}

menu() {
  local x="$1"
  local y="$2"
  shift 2
  

  # Determine keyboard codes
  local UP=`tput cuu1` DOWN=`echo -ne '\e[B'` LEFT=`tput cub1` RIGHT=`tput cuf1`
  
  local max_length=0 ITEM
  for ITEM in "$@"
  do
    [[ ${#ITEM} > $max_length ]] && max_length=${#ITEM}
  done
  
  box "$x" "$y" $(($x+$max_length+3)) $(($y+$#+3))
  
  local pos=0
  refresh_menu $x $y $pos "$@"
  
  local REPLY
  while true
  do
    IFS='' read -r -t1 -n3 -s REPLY || continue
    
    case "$REPLY" in
      "$UP")
         pos=$(($pos-1))
         [[ 0 > "$pos" ]] && pos=$(($#-1))
      ;;
      "$DOWN")
         pos=$(($pos+1))
         [[ $pos -ge $# ]] && pos=0
      ;;
      "")
        
        SELECTED_ITEM_NUMBER=$pos
        
        local TMP
        TMP=( "$@" )
        SELECTED_ITEM="${TMP[$pos]}"
        
        return 0
      ;;
    esac
    
    refresh_menu $x $y $pos "$@"
  done
}

# Make cursor invisible
tput civis
  
menu 2 2 "яблуко" "вишня" "апельсин"

# Make cursor visible again
tput cvvis

clear
echo "Selected item number: $SELECTED_ITEM_NUMBER"
echo "Selected item: $SELECTED_ITEM"
[Fedora Linux]