X-Git-Url: http://git.shiar.net/descalc.git/blobdiff_plain/4e1d9535fda6685e53ce570ca4e4cd6c260f55d3..090ac304afe801cb3e72ced0941ff2a874a98cc9:/04_disp_curses.pm diff --git a/04_disp_curses.pm b/04_disp_curses.pm new file mode 100644 index 0000000..be3da3c --- /dev/null +++ b/04_disp_curses.pm @@ -0,0 +1,126 @@ +# ncurses output for DCT, by Shiar + +# 1.13.0 200411042100 - hook to display and handle menu +# - submenus are named instead of numbered +# - refresh hook renamed to showall +# 1.12.0 200410312200 - define main loop (get input from Term::ReadKey) +# 1.11.0 200410152225 - uses class in filename instead of $set{display} check +# 1.10.0 200410140120 - all output functions seperated from main + +use strict; +use warnings; + +use Curses; +use Term::ReadKey; + +use vars qw(%falias $path); +require $path."termcommon.pm"; + +sub setsize () { + $set{height} = $LINES-3 if $LINES>=3; + $set{width} = $COLS if $COLS; + $set{menushow} = int($set{width}/(4+$set{width}/20))+1; # menu items to show simultaneously +} # setsize + +push @{$hook{init}}, sub { + initscr; + ReadMode 3; # cbreak mode + + END { + ReadMode 0; + endwin; + } # restore terminal on quit + + $SIG{WINCH} = sub { + endwin; + refresh; # setup for new screen size + setsize(); # adjust for new sizes + redraw(all=>1); # queue complete refresh + draw(); # redraw rightnow + }; + + setsize(); +}; # init + +push @{$hook{showerror}}, sub { + attron(A_REVERSE); + addstr(0, 0, shift); + attroff(A_REVERSE); + clrtoeol; + refresh; + + ReadKey; # wait for confirm + 1 while defined ReadKey(-1); # clear key buffer +}; # showerror + +push @{$hook{showstack}}, sub { + for (0..@stack-1) { + addstr($set{height}-$_, 1, "$_: ".showval($stack[$_], $set{base})); + clrtoeol; + } # show stack + clrtoeol($set{height}-@stack, 1); +}; # showstack + +push @{$hook{showmenu}}, sub { + clrtoeol($set{height}+2, 1); + my $nr = -1; + for (grep exists $menu[0][$_], $menu[0][0]+1..$menu[0][0]+$set{menushow}) { + $nr++; + next unless defined $menu[0][$_]; + my $sub = (my $s = $menu[0][$_]) =~ s/>\w+$//; + addstr($set{height}+2, $set{width}/$set{menushow}*$nr, $_); + attron(A_REVERSE); + addstr($s); + attroff(A_REVERSE); + addch('>') if $sub; # indicate submenu + } # display menu txts +}; # showmenu + +$action{more} = [-1, sub { + $menu[0][0] += $set{menushow}; + $menu[0][0] = 0 if $menu[0][0] > @{$menu[0]}; + $_->() for @{$hook{showmenu}}; +}]; # tab + +unshift @{$hook{precmd}}, sub { + exists $falias{$_} or return; # handle function key + if ($falias{$_}==0) { + shift @menu if @menu>1; # remove current submenu + redraw(menu=>1); + return 1; + } # escape (go to parent) + $_ = $menu[0][$falias{$_}] and return; # execute found menu item instead + error("no such menu entry"); + return 1; +}; # precmd (menu item selection) + +push @{$hook{showall}}, sub { + clear; + addstr($set{height}+1, 0, "> "); # prompt +}; # showall + +push @{$hook{showentry}}, sub { + addstr($set{height}+1, 2, $_[0]); + clrtoeol; + refresh; +}; # showentry + +$hook{main} = sub { + while (1) { + draw(); + + my $key = ReadKey; # wait for user input + if ($key eq chr 27) { + $key .= $_ while defined ($_ = ReadKey(-1)); # read additional keys + } # escape sequence + + onkey($key); + } # input loop +}; # main + +return { + author => "Shiar", + title => "curses output", + version => "1.13", +}; +