release 1.14pre0
[descalc.git] / 04_disp_curses.pm
1 # ncurses output for DCT, by Shiar
2
3 # 1.13.0 200411042100 - hook to display and handle menu
4 #                     - submenus are named instead of numbered
5 #                     - refresh hook renamed to showall
6 # 1.12.0 200410312200 - define main loop (get input from Term::ReadKey)
7 # 1.11.0 200410152225 - uses class in filename instead of $set{display} check
8 # 1.10.0 200410140120 - all output functions seperated from main
9
10 use strict;
11 use warnings;
12
13 use Curses;
14 use Term::ReadKey;
15
16 use vars qw(%falias $path);
17 require $path."termcommon.pm";
18
19 sub setsize () {
20         $set{height} = $LINES-3 if $LINES>=3;
21         $set{width} = $COLS if $COLS;
22         $set{menushow} = int($set{width}/(4+$set{width}/20))+1;  # menu items to show simultaneously
23 } # setsize
24
25 push @{$hook{init}}, sub {
26         initscr;
27         ReadMode 3;  # cbreak mode
28
29         END {
30                 ReadMode 0;
31                 endwin;
32         } # restore terminal on quit
33
34         $SIG{WINCH} = sub {
35                 endwin;
36                 refresh;  # setup for new screen size
37                 setsize();  # adjust for new sizes
38                 redraw(all=>1);  # queue complete refresh
39                 draw();  # redraw rightnow
40         };
41
42         setsize();
43 }; # init
44
45 push @{$hook{showerror}}, sub {
46         attron(A_REVERSE);
47         addstr(0, 0, shift);
48         attroff(A_REVERSE);
49         clrtoeol;
50         refresh;
51
52         ReadKey; # wait for confirm
53         1 while defined ReadKey(-1); # clear key buffer
54 }; # showerror
55
56 push @{$hook{showstack}}, sub {
57         for (0..@stack-1) {
58                 addstr($set{height}-$_, 1, "$_: ".showval($stack[$_], $set{base}));
59                 clrtoeol;
60         } # show stack
61         clrtoeol($set{height}-@stack, 1);
62 }; # showstack
63
64 push @{$hook{showmenu}}, sub {
65         clrtoeol($set{height}+2, 1);
66         my $nr = -1;
67         for (grep exists $menu[0][$_], $menu[0][0]+1..$menu[0][0]+$set{menushow}) {
68                 $nr++;
69                 next unless defined $menu[0][$_];
70                 my $sub = (my $s = $menu[0][$_]) =~ s/>\w+$//;
71                 addstr($set{height}+2, $set{width}/$set{menushow}*$nr, $_);
72                 attron(A_REVERSE);
73                 addstr($s);
74                 attroff(A_REVERSE);
75                 addch('>') if $sub;  # indicate submenu
76         } # display menu txts
77 }; # showmenu
78
79 $action{more} = [-1, sub {
80         $menu[0][0] += $set{menushow};
81         $menu[0][0] = 0 if $menu[0][0] > @{$menu[0]};
82         $_->() for @{$hook{showmenu}};
83 }]; # tab
84
85 unshift @{$hook{precmd}}, sub {
86         exists $falias{$_} or return;  # handle function key
87         if ($falias{$_}==0) {
88                 shift @menu if @menu>1;  # remove current submenu
89                 redraw(menu=>1);
90                 return 1;
91         } # escape (go to parent)
92         $_ = $menu[0][$falias{$_}] and return;  # execute found menu item instead
93         error("no such menu entry");
94         return 1;
95 }; # precmd (menu item selection)
96
97 push @{$hook{showall}}, sub {
98         clear;
99         addstr($set{height}+1, 0, "> ");  # prompt
100 }; # showall
101
102 push @{$hook{showentry}}, sub {
103         addstr($set{height}+1, 2, $_[0]);
104         clrtoeol;
105         refresh;
106 }; # showentry
107
108 $hook{main} = sub {
109         while (1) {
110                 draw();
111
112                 my $key = ReadKey;  # wait for user input
113                 if ($key eq chr 27) {
114                         $key .= $_ while defined ($_ = ReadKey(-1));  # read additional keys
115                 } # escape sequence
116
117                 onkey($key);
118         } # input loop
119 }; # main
120
121 return {
122         author  => "Shiar",
123         title   => "curses output",
124         version => "1.13",
125 };
126