ncurses 6.0 - patch 20170729
[ncurses.git] / test / popup_msg.c
1 /****************************************************************************
2  * Copyright (c) 2017 Free Software Foundation, Inc.                        *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28 /*
29  * $Id: popup_msg.c,v 1.7 2017/04/15 19:16:41 tom Exp $
30  *
31  * Show a multi-line message in a window which may extend beyond the screen.
32  *
33  * Thomas Dickey - 2017/4/15.
34  */
35
36 #include <test.priv.h>
37
38 #include <popup_msg.h>
39
40 static WINDOW *old_window;
41
42 static void
43 begin_popup(void)
44 {
45     doupdate();
46     old_window = dupwin(curscr);
47 }
48
49 static void
50 end_popup(void)
51 {
52     touchwin(old_window);
53     wnoutrefresh(old_window);
54     doupdate();
55     delwin(old_window);
56 }
57
58 /*
59  * Display a temporary window, e.g., to display a help-message.
60  */
61 void
62 popup_msg(WINDOW *parent, const char *const *msg)
63 {
64     int x0 = 4;
65     int y0 = 2;
66     int y1 = 0;
67     int y2 = 0;
68     int wide = getmaxx(parent) - ((x0 + 1) * 2);
69     int high = getmaxy(parent) - ((y0 + 1) * 2);
70     WINDOW *help;
71     WINDOW *data;
72     int n;
73     int width = 0;
74     int length;
75     int last_y;
76     int ch = ERR;
77
78     for (n = 0; msg[n] != 0; ++n) {
79         int check = (int) strlen(msg[n]);
80         if (width < check)
81             width = check;
82     }
83     length = n;
84
85     if ((help = newwin(high, wide, y0, x0)) == 0)
86         return;
87     if ((data = newpad(length + 1, width)) == 0)
88         return;
89
90     begin_popup();
91
92     keypad(data, TRUE);
93
94     for (n = 0; n < length; ++n) {
95         waddstr(data, msg[n]);
96         if ((n + 1) < length) {
97             waddch(data, '\n');
98         }
99     }
100     y2 = getcury(data);
101     last_y = (y2 - (high - 3));
102
103     do {
104         switch (ch) {
105         case KEY_HOME:
106             y1 = 0;
107             break;
108         case KEY_END:
109             y1 = last_y;
110             break;
111         case KEY_PREVIOUS:
112         case KEY_PPAGE:
113             if (y1 > 0) {
114                 y1 -= high / 2;
115                 if (y1 < 0)
116                     y1 = 0;
117             } else {
118                 beep();
119             }
120             break;
121         case KEY_NEXT:
122         case KEY_NPAGE:
123             if (y1 < last_y) {
124                 y1 += high / 2;
125                 if (y1 > last_y)
126                     y1 = last_y;
127             } else {
128                 beep();
129             }
130             break;
131         case CTRL('P'):
132         case KEY_UP:
133             if (y1 > 0)
134                 --y1;
135             else
136                 beep();
137             break;
138         case CTRL('N'):
139         case KEY_DOWN:
140             if (y1 < last_y)
141                 ++y1;
142             else
143                 beep();
144             break;
145         default:
146             beep();
147             break;
148         case ERR:
149             break;
150         }
151         werase(help);
152         box(help, 0, 0);
153         wnoutrefresh(help);
154         pnoutrefresh(data, y1, 0, y0 + 1, x0 + 1, high, wide);
155         doupdate();
156     } while ((ch = wgetch(data)) != ERR && ch != QUIT && ch != ESCAPE);
157     werase(help);
158     wrefresh(help);
159     delwin(help);
160     delwin(data);
161
162     end_popup();
163 }
164
165 void
166 popup_msg2(WINDOW *parent, char **msg)
167 {
168     popup_msg(parent, (const char *const *) msg);
169 }