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