blob: a5347137fbbabfa255d36c6d6702fb315e26bfc7 [file] [log] [blame]
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +05301// * this is for making emacs happy: -*-Mode: C++;-*-
2/****************************************************************************
Steve Kondikae271bc2015-11-15 02:50:53 +01003 * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc. *
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +05304 * *
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 ****************************************************************************/
29
30/****************************************************************************
31 * Author: Juergen Pfeifer, 1999 *
32 ****************************************************************************/
33
34#include "internal.h"
35
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +053036#include <cursesw.h>
37
Steve Kondikae271bc2015-11-15 02:50:53 +010038MODULE_ID("$Id: cursespad.cc,v 1.17 2013/03/30 19:45:36 tom Exp $")
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +053039
40NCursesPad::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)
46{
47 w = ::newpad(nlines, ncols);
48 if (static_cast<WINDOW*>(0) == w) {
49 count--;
50 err_handler("Cannot construct window");
51 }
52 alloced = TRUE;
53}
54
55
56int NCursesPad::driver (int key)
57{
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;
77
78 default: return(key);
79 }
80}
81
82
83void NCursesPad::operator()(void)
84{
85 NCursesWindow* W = Win();
86
87 if (static_cast<NCursesWindow*>(0) != W) {
88 int Width = W->width();
89 int Height = W->height();
90
91 int req = REQ_PAD_REFRESH;
92
93 W->keypad(TRUE);
94 W->meta(TRUE);
95 refresh();
96
97 do {
98 bool changed = FALSE;
99
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;
113 }
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;
125 }
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;
137 }
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;
149 }
150 else
151 OnNavigationError(req);
152 break;
153
154 default:
155 OnUnknownOperation(req);
156 }
157
158 if (changed) {
159 noutrefresh();
160 W->syncup();
161 OnOperation(req);
162 viewWin->refresh();
163 }
164 } while( (req=driver(W->getch())) != REQ_PAD_EXIT );
165 }
166}
167
168
169int NCursesPad::refresh()
170{
171 int res = noutrefresh();
172 if (res==OK && (static_cast<NCursesWindow*>(0) != viewWin)) {
173 res = (viewWin->refresh());
174 }
175 return(res);
176}
177
178int NCursesPad::noutrefresh()
179{
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();
191 }
192 }
193 return (res);
194}
195
196void NCursesPad::setWindow(NCursesWindow& view,
197 int v_grid NCURSES_PARAM_INIT(1),
198 int h_grid NCURSES_PARAM_INIT(1))
199{
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;
207 }
208}
209
210void NCursesPad::setSubWindow(NCursesWindow& sub)
211{
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;
218}
219
220void NCursesFramedPad::OnOperation(int pad_req)
221{
Steve Kondikae271bc2015-11-15 02:50:53 +0100222 (void) pad_req;
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530223 NCursesWindow* W = Win();
224 NCursesWindow* W2 = getWindow();
225
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;
230
Steve Kondikae271bc2015-11-15 02:50:53 +0100231 int my_width = width();
232
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 {
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530240 h_len = 1;
Steve Kondikae271bc2015-11-15 02:50:53 +0100241 }
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530242
Steve Kondikae271bc2015-11-15 02:50:53 +0100243 int my_height = height();
244
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 {
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530252 v_len = 1;
Steve Kondikae271bc2015-11-15 02:50:53 +0100253 }
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530254
Steve Kondikae271bc2015-11-15 02:50:53 +0100255 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;
261 }
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530262
Steve Kondikae271bc2015-11-15 02:50:53 +0100263 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;
269 }
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +0530270
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);
278 }
279 else {
280 for(i=1;i<=v_len;i++)
281 W2->addch(row+i,Width+1,' ');
282 }
283 W2->attroff(A_REVERSE);
284
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);
292 }
293 else {
294 for(i=1;i<=h_len;i++)
295 W2->addch(Height+1,col+i,' ');
296 }
297 W2->attroff(A_REVERSE);
298 }
299}