libncurses: updated to 6.0
[tomato.git] / release / src / router / libncurses / c++ / cursespad.cc
bloba5347137fbbabfa255d36c6d6702fb315e26bfc7
1 // * this is for making emacs happy: -*-Mode: C++;-*-
2 /****************************************************************************
3 * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
4 * *
5 * Permission is hereby granted, free of charge, to any person obtaining a *
6 * copy of this software and associated documentation files (the *
7 * "Software"), to deal in the Software without restriction, including *
8 * without limitation the rights to use, copy, modify, merge, publish, *
9 * distribute, distribute with modifications, sublicense, and/or sell *
10 * copies of the Software, and to permit persons to whom the Software is *
11 * furnished to do so, subject to the following conditions: *
12 * *
13 * The above copyright notice and this permission notice shall be included *
14 * in all copies or substantial portions of the Software. *
15 * *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * *
24 * Except as contained in this notice, the name(s) of the above copyright *
25 * holders shall not be used in advertising or otherwise to promote the *
26 * sale, use or other dealings in this Software without prior written *
27 * authorization. *
28 ****************************************************************************/
30 /****************************************************************************
31 * Author: Juergen Pfeifer, 1999 *
32 ****************************************************************************/
34 #include "internal.h"
36 #include <cursesw.h>
38 MODULE_ID("$Id: cursespad.cc,v 1.17 2013/03/30 19:45:36 tom Exp $")
40 NCursesPad::NCursesPad(int nlines, int ncols)
41 : NCursesWindow(),
42 viewWin(static_cast<NCursesWindow*>(0)),
43 viewSub(static_cast<NCursesWindow*>(0)),
44 h_gridsize(0), v_gridsize(0),
45 min_row(0), min_col(0)
47 w = ::newpad(nlines, ncols);
48 if (static_cast<WINDOW*>(0) == w) {
49 count--;
50 err_handler("Cannot construct window");
52 alloced = TRUE;
56 int NCursesPad::driver (int key)
58 // Default implementation
59 switch(key) {
60 case KEY_UP:
61 // =======
62 return REQ_PAD_UP;
63 case KEY_DOWN:
64 // =========
65 return REQ_PAD_DOWN;
66 case KEY_LEFT:
67 // =========
68 return REQ_PAD_LEFT;
69 case KEY_RIGHT:
70 // ==========
71 return REQ_PAD_RIGHT;
72 case KEY_EXIT:
73 // =========
74 case CTRL('X'):
75 // ==========
76 return REQ_PAD_EXIT;
78 default: return(key);
83 void NCursesPad::operator()(void)
85 NCursesWindow* W = Win();
87 if (static_cast<NCursesWindow*>(0) != W) {
88 int Width = W->width();
89 int Height = W->height();
91 int req = REQ_PAD_REFRESH;
93 W->keypad(TRUE);
94 W->meta(TRUE);
95 refresh();
97 do {
98 bool changed = FALSE;
100 switch (req) {
101 case REQ_PAD_REFRESH:
102 // ================
103 changed = TRUE;
104 break;
105 case REQ_PAD_LEFT:
106 // =============
107 if (min_col > 0) {
108 changed = TRUE;
109 if (min_col < h_gridsize)
110 min_col = 0;
111 else
112 min_col -= h_gridsize;
114 else
115 OnNavigationError(req);
116 break;
117 case REQ_PAD_RIGHT:
118 // ==============
119 if (min_col < (width() - Width - 1)) {
120 changed = TRUE;
121 if (min_col > (width() - Width - h_gridsize - 1))
122 min_col = width() - Width - 1;
123 else
124 min_col += h_gridsize;
126 else
127 OnNavigationError(req);
128 break;
129 case REQ_PAD_UP:
130 // ===========
131 if (min_row > 0) {
132 changed = TRUE;
133 if (min_row < v_gridsize)
134 min_row = 0;
135 else
136 min_row -= v_gridsize;
138 else
139 OnNavigationError(req);
140 break;
141 case REQ_PAD_DOWN:
142 // =============
143 if (min_row < (height() - Height - 1)) {
144 changed = TRUE;
145 if (min_row > (height() - Height - v_gridsize - 1))
146 min_row = height() - Height - 1;
147 else
148 min_row += v_gridsize;
150 else
151 OnNavigationError(req);
152 break;
154 default:
155 OnUnknownOperation(req);
158 if (changed) {
159 noutrefresh();
160 W->syncup();
161 OnOperation(req);
162 viewWin->refresh();
164 } while( (req=driver(W->getch())) != REQ_PAD_EXIT );
169 int NCursesPad::refresh()
171 int res = noutrefresh();
172 if (res==OK && (static_cast<NCursesWindow*>(0) != viewWin)) {
173 res = (viewWin->refresh());
175 return(res);
178 int NCursesPad::noutrefresh()
180 int res = OK;
181 NCursesWindow* W = Win();
182 if (static_cast<NCursesWindow*>(0) != W) {
183 int high = W->maxy();
184 int wide = W->maxx();
185 res = copywin(*W, min_row, min_col,
186 0, 0, high, wide,
187 FALSE);
188 if (res==OK) {
189 W->syncup();
190 res = viewWin->noutrefresh();
193 return (res);
196 void NCursesPad::setWindow(NCursesWindow& view,
197 int v_grid NCURSES_PARAM_INIT(1),
198 int h_grid NCURSES_PARAM_INIT(1))
200 viewWin = &view;
201 min_row = min_col = 0;
202 if (h_grid <=0 || v_grid <= 0)
203 err_handler("Illegal Gridsize");
204 else {
205 h_gridsize = h_grid;
206 v_gridsize = v_grid;
210 void NCursesPad::setSubWindow(NCursesWindow& sub)
212 if (static_cast<NCursesWindow*>(0) == viewWin)
213 err_handler("Pad has no viewport");
214 assert(viewWin != 0);
215 if (!viewWin->isDescendant(sub))
216 THROW(new NCursesException("NCursesFramePad", E_SYSTEM_ERROR));
217 viewSub = &sub;
220 void NCursesFramedPad::OnOperation(int pad_req)
222 (void) pad_req;
223 NCursesWindow* W = Win();
224 NCursesWindow* W2 = getWindow();
226 if ((static_cast<NCursesWindow*>(0) != W) && (static_cast<NCursesWindow*>(0) != W2)) {
227 int Width = W->width();
228 int Height = W->height();
229 int i, row, col, h_len, v_len;
231 int my_width = width();
233 if (my_width != 0) {
234 h_len = (Width*Width + my_width - 1) / my_width;
235 if (h_len==0)
236 h_len = 1;
237 if (h_len > Width)
238 h_len = Width;
239 } else {
240 h_len = 1;
243 int my_height = height();
245 if (my_height != 0) {
246 v_len = (Height*Height + my_height - 1) / my_height;
247 if (v_len==0)
248 v_len = 1;
249 if (v_len > Height)
250 v_len = Height;
251 } else {
252 v_len = 1;
255 if (my_width != 0) {
256 col = (min_col * Width + my_width - 1) / my_width;
257 if (col + h_len > Width)
258 col = Width - h_len;
259 } else {
260 col = 0;
263 if (my_height != 0) {
264 row = (min_row * Height + my_height - 1) / my_height;
265 if (row + v_len > Height)
266 row = Height - v_len;
267 } else {
268 row = 0;
271 W2->vline(1,Width+1,Height);
272 W2->attron(A_REVERSE);
273 if (v_len>=2) {
274 W2->addch(row+1,Width+1,ACS_UARROW);
275 for(i=2;i<v_len;i++)
276 W2->addch(row+i,Width+1,' ');
277 W2->addch(row+v_len,Width+1,ACS_DARROW);
279 else {
280 for(i=1;i<=v_len;i++)
281 W2->addch(row+i,Width+1,' ');
283 W2->attroff(A_REVERSE);
285 W2->hline(Height+1,1,Width);
286 W2->attron(A_REVERSE);
287 if (h_len >= 2) {
288 W2->addch(Height+1,col+1,ACS_LARROW);
289 for(i=2;i<h_len;i++)
290 W2->addch(Height+1,col+i,' ');
291 W2->addch(Height+1,col+h_len,ACS_RARROW);
293 else {
294 for(i=1;i<=h_len;i++)
295 W2->addch(Height+1,col+i,' ');
297 W2->attroff(A_REVERSE);