00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "basewindow.h"
00021 #include "inputwidget.h"
00022 #include "colors.h"
00023
00024 using namespace YAPETUI;
00025
00026 void
00027 InputWidget::moveBackward() throw(UIException) {
00028 pos--;
00029 if (pos < 0) {
00030 pos = 0;
00031 start_pos--;
00032 }
00033
00034 if (start_pos < 0)
00035 start_pos = 0;
00036
00037 refresh();
00038 }
00039
00040 void
00041 InputWidget::moveForward() throw(UIException) {
00042 if ( ((secstring::size_type)(start_pos + pos + 1)) > buffer.length()) {
00043 refresh();
00044 return;
00045 }
00046
00047 if (pos+1 > width)
00048 start_pos++;
00049 else
00050 pos++;
00051
00052 refresh();
00053 }
00054
00055 void
00056 InputWidget::moveHome() throw(UIException) {
00057 pos = 0;
00058 start_pos = 0;
00059 refresh();
00060 }
00061
00062 void
00063 InputWidget::moveEnd() throw(UIException) {
00064 if (buffer.length() < ((secstring::size_type)width) ) {
00065 start_pos = 0;
00066 pos = buffer.length();
00067 } else {
00068 start_pos = buffer.length() - width + 1;
00069 pos = width - 1;
00070 }
00071 refresh();
00072 }
00073
00074
00075 void
00076 InputWidget::processInput(int ch) throw(UIException) {
00077 if (buffer.length()+1 > ((secstring::size_type)max_length)) return;
00078
00079 if ( ((secstring::size_type)start_pos + pos) > buffer.length())
00080 buffer.append(""+ch);
00081 else
00082 buffer.insert(start_pos+pos, 1, ch);
00083
00084 moveForward();
00085
00086
00087 text_changed = true;
00088 }
00089
00090 void
00091 InputWidget::processBackspace() throw(UIException) {
00092 if (pos + start_pos == 0) return;
00093
00094 moveBackward();
00095 processDelete();
00096 }
00097
00098 void
00099 InputWidget::processDelete() throw(UIException) {
00100 if ( ((secstring::size_type)pos + start_pos) == buffer.length()) return;
00101
00102 buffer.erase(pos + start_pos, 1);
00103 if ( ((secstring::size_type)pos + start_pos) > buffer.length()) {
00104 if (pos > 0)
00105 pos--;
00106 else
00107 start_pos--;
00108 }
00109 refresh();
00110
00111
00112 text_changed = true;
00113 }
00114
00115
00116 void
00117 InputWidget::createWindow(int sx, int sy, int w) throw(UIException) {
00118 if (window != NULL)
00119 throw UIException("May you consider deleting the window first before reallocating it");
00120
00121 window = newwin(1, w, sy, sx);
00122 if (window == NULL)
00123 throw UIException("Error creating the input window");
00124
00125 Colors::setcolor(window, INPUTWIDGET_NOFOCUS);
00126
00127 int retval = wclear(window);
00128 if (retval == ERR)
00129 throw UIException("Error clearing input widget");
00130
00131 retval = keypad(window, TRUE);
00132 if (retval == ERR)
00133 throw UIException("Error setting keypad on input widget");
00134
00135
00136 }
00137
00138 InputWidget::InputWidget(int sx, int sy, int w, int ml)
00139 throw(UIException) : window(NULL),
00140 max_length(ml),
00141 start_pos(0),
00142 pos(0),
00143 width(w),
00144 text_changed(false) {
00145 createWindow(sx, sy, w);
00146 }
00147
00148 InputWidget::~InputWidget() {
00149 clearText();
00150 wclear(window);
00151 delwin(window);
00152 }
00153
00154 int
00155 InputWidget::focus() throw(UIException) {
00156 Colors::setcolor(window, INPUTWIDGET_FOCUS);
00157
00158 int retval = wrefresh(window);
00159 if (retval == ERR)
00160 throw UIException("Error refreshing the widget");
00161
00162 retval = wmove(window, 0, pos);
00163 if (retval == ERR)
00164 throw UIException("Error moving cursor for widget");
00165
00166 curs_set(2);
00167 int ch;
00168 while ( (ch=wgetch(window)) != '\n' && ch != '\t') {
00169 switch (ch) {
00170 case KEY_UP:
00171 case KEY_LEFT:
00172 moveBackward();
00173 break;
00174 case KEY_DOWN:
00175 case KEY_RIGHT:
00176 moveForward();
00177 break;
00178 case KEY_END:
00179 case KEY_A1:
00180 moveEnd();
00181 break;
00182 case KEY_HOME:
00183 case KEY_C1:
00184 moveHome();
00185 break;
00186 case KEY_ENTER:
00187 ungetch('\n');
00188 break;
00189 case KEY_DC:
00190 case 127:
00191 processDelete();
00192 break;
00193 case KEY_BACKSPACE:
00194 case 8:
00195 processBackspace();
00196 break;
00197 #ifdef HAVE_WRESIZE
00198 case KEY_RESIZE:
00199 goto BAILOUT;
00200 break;
00201 #endif // HAVE_WRESIZE
00202 case KEY_REFRESH:
00203 BaseWindow::refreshAll();
00204 break;
00205 default:
00206 processInput(ch);
00207 break;
00208 }
00209 }
00210 BAILOUT:
00211 curs_set(0);
00212
00213 Colors::setcolor(window, INPUTWIDGET_NOFOCUS);
00214
00215 retval = wrefresh(window);
00216 if (retval == ERR)
00217 throw UIException("Error refreshing the widget");
00218 return ch;
00219 }
00220
00221 void
00222 InputWidget::refresh() throw(UIException) {
00223 int retval = werase(window);
00224 if (retval == ERR)
00225 throw UIException("Error clearing input widget");
00226
00227 if (buffer.length() > 0) {
00228 secstring sub = buffer.substr(start_pos, width);
00229 retval = mymvwaddnstr(window,
00230 0,
00231 0,
00232 sub.c_str(),
00233 width-1);
00234 if (retval == ERR)
00235 throw UIException("Error adding text to window");
00236
00237 if (pos >= width - 1)
00238 retval = wmove(window, 0, width-1);
00239 else
00240 retval = wmove(window, 0, pos);
00241
00242 if (retval == ERR)
00243 throw UIException("Error moving cursor");
00244 }
00245
00246 retval = wrefresh(window);
00247 if (retval == ERR)
00248 throw UIException("Error refreshing input widget");
00249
00250 }
00251
00252 void
00253 InputWidget::resize(int sx, int sy, int w) throw(UIException) {
00254 int retval = wclear(window);
00255 if (retval == ERR)
00256 throw UIException("Error clearing input widget");
00257
00258 retval = wrefresh(window);
00259 if (retval == ERR)
00260 throw UIException("Error refreshing input widget");
00261
00262 retval = delwin(window);
00263 if (retval == ERR)
00264 throw UIException("Error deleting input widget");
00265
00266 window = NULL;
00267 createWindow(sx, sy, w);
00268 }
00269
00270 void
00271 InputWidget::setText(secstring t) throw(UIException) {
00272 clearText();
00273 buffer = t;
00274 start_pos = 0;
00275 pos = 0;
00276 text_changed = false;
00277 refresh();
00278 }
00279
00280 void
00281 InputWidget::clearText() {
00282 for(secstring::size_type i=0; i < buffer.length(); i++)
00283 buffer[i]=0;
00284
00285 buffer.clear();
00286 wclear(window);
00287 }