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