1// * this is for making emacs happy: -*-Mode: C++;-*- 2/**************************************************************************** 3 * Copyright (c) 1998-2007,2008 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 ****************************************************************************/ 29 30/**************************************************************************** 31 * Author: Juergen Pfeifer, 1999 * 32 ****************************************************************************/ 33 34#include "internal.h" 35 36#include <etip.h> 37#include <cursesw.h> 38 39MODULE_ID("$Id: cursespad.cc,v 1.13 2008/08/04 18:59:22 tom Exp $") 40 41NCursesPad::NCursesPad(int nlines, int ncols) 42 : NCursesWindow(), 43 viewWin(static_cast<NCursesWindow*>(0)), 44 viewSub(static_cast<NCursesWindow*>(0)), 45 h_gridsize(0), v_gridsize(0), 46 min_row(0), min_col(0) 47{ 48 w = ::newpad(nlines, ncols); 49 if (static_cast<WINDOW*>(0) == w) { 50 count--; 51 err_handler("Cannot construct window"); 52 } 53 alloced = TRUE; 54} 55 56 57int NCursesPad::driver (int key) 58{ 59 // Default implementation 60 switch(key) { 61 case KEY_UP: 62 // ======= 63 return REQ_PAD_UP; 64 case KEY_DOWN: 65 // ========= 66 return REQ_PAD_DOWN; 67 case KEY_LEFT: 68 // ========= 69 return REQ_PAD_LEFT; 70 case KEY_RIGHT: 71 // ========== 72 return REQ_PAD_RIGHT; 73 case KEY_EXIT: 74 // ========= 75 case CTRL('X'): 76 // ========== 77 return REQ_PAD_EXIT; 78 79 default: return(key); 80 } 81} 82 83 84void NCursesPad::operator()(void) 85{ 86 NCursesWindow* W = Win(); 87 88 if (static_cast<NCursesWindow*>(0) != W) { 89 int Width = W->width(); 90 int Height = W->height(); 91 92 int req = REQ_PAD_REFRESH; 93 94 W->keypad(TRUE); 95 W->meta(TRUE); 96 refresh(); 97 98 do { 99 bool changed = FALSE; 100 101 switch (req) { 102 case REQ_PAD_REFRESH: 103 // ================ 104 changed = TRUE; 105 break; 106 case REQ_PAD_LEFT: 107 // ============= 108 if (min_col > 0) { 109 changed = TRUE; 110 if (min_col < h_gridsize) 111 min_col = 0; 112 else 113 min_col -= h_gridsize; 114 } 115 else 116 OnNavigationError(req); 117 break; 118 case REQ_PAD_RIGHT: 119 // ============== 120 if (min_col < (width() - Width - 1)) { 121 changed = TRUE; 122 if (min_col > (width() - Width - h_gridsize - 1)) 123 min_col = width() - Width - 1; 124 else 125 min_col += h_gridsize; 126 } 127 else 128 OnNavigationError(req); 129 break; 130 case REQ_PAD_UP: 131 // =========== 132 if (min_row > 0) { 133 changed = TRUE; 134 if (min_row < v_gridsize) 135 min_row = 0; 136 else 137 min_row -= v_gridsize; 138 } 139 else 140 OnNavigationError(req); 141 break; 142 case REQ_PAD_DOWN: 143 // ============= 144 if (min_row < (height() - Height - 1)) { 145 changed = TRUE; 146 if (min_row > (height() - Height - v_gridsize - 1)) 147 min_row = height() - Height - 1; 148 else 149 min_row += v_gridsize; 150 } 151 else 152 OnNavigationError(req); 153 break; 154 155 default: 156 OnUnknownOperation(req); 157 } 158 159 if (changed) { 160 noutrefresh(); 161 W->syncup(); 162 OnOperation(req); 163 viewWin->refresh(); 164 } 165 } while( (req=driver(W->getch())) != REQ_PAD_EXIT ); 166 } 167} 168 169 170int NCursesPad::refresh() 171{ 172 int res = noutrefresh(); 173 if (res==OK && (static_cast<NCursesWindow*>(0) != viewWin)) { 174 res = (viewWin->refresh()); 175 } 176 return(res); 177} 178 179int NCursesPad::noutrefresh() 180{ 181 int res = OK; 182 NCursesWindow* W = Win(); 183 if (static_cast<NCursesWindow*>(0) != W) { 184 int high = W->maxy(); 185 int wide = W->maxx(); 186 res = copywin(*W, min_row, min_col, 187 0, 0, high, wide, 188 FALSE); 189 if (res==OK) { 190 W->syncup(); 191 res = viewWin->noutrefresh(); 192 } 193 } 194 return (res); 195} 196 197void NCursesPad::setWindow(NCursesWindow& view, 198 int v_grid NCURSES_PARAM_INIT(1), 199 int h_grid NCURSES_PARAM_INIT(1)) 200{ 201 viewWin = &view; 202 min_row = min_col = 0; 203 if (h_grid <=0 || v_grid <= 0) 204 err_handler("Illegal Gridsize"); 205 else { 206 h_gridsize = h_grid; 207 v_gridsize = v_grid; 208 } 209} 210 211void NCursesPad::setSubWindow(NCursesWindow& sub) 212{ 213 if (static_cast<NCursesWindow*>(0) == viewWin) 214 err_handler("Pad has no viewport"); 215 assert(viewWin != 0); 216 if (!viewWin->isDescendant(sub)) 217 THROW(new NCursesException("NCursesFramePad", E_SYSTEM_ERROR)); 218 viewSub = ⊂ 219} 220 221void NCursesFramedPad::OnOperation(int pad_req) 222{ 223 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 231 h_len = (Width*Width + width() - 1)/width(); 232 if (h_len==0) 233 h_len = 1; 234 if (h_len > Width) 235 h_len = Width; 236 237 v_len = (Height*Height + height() - 1)/height(); 238 if (v_len==0) 239 v_len = 1; 240 if (v_len > Height) 241 v_len = Height; 242 243 col = (min_col * Width + width() - 1) / width(); 244 if (col + h_len > Width) 245 col = Width - h_len; 246 247 row = (min_row * Height + height() - 1) / height(); 248 if (row + v_len > Height) 249 row = Height - v_len; 250 251 W2->vline(1,Width+1,Height); 252 W2->attron(A_REVERSE); 253 if (v_len>=2) { 254 W2->addch(row+1,Width+1,ACS_UARROW); 255 for(i=2;i<v_len;i++) 256 W2->addch(row+i,Width+1,' '); 257 W2->addch(row+v_len,Width+1,ACS_DARROW); 258 } 259 else { 260 for(i=1;i<=v_len;i++) 261 W2->addch(row+i,Width+1,' '); 262 } 263 W2->attroff(A_REVERSE); 264 265 W2->hline(Height+1,1,Width); 266 W2->attron(A_REVERSE); 267 if (h_len >= 2) { 268 W2->addch(Height+1,col+1,ACS_LARROW); 269 for(i=2;i<h_len;i++) 270 W2->addch(Height+1,col+i,' '); 271 W2->addch(Height+1,col+h_len,ACS_RARROW); 272 } 273 else { 274 for(i=1;i<=h_len;i++) 275 W2->addch(Height+1,col+i,' '); 276 } 277 W2->attroff(A_REVERSE); 278 } 279} 280