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