diff options
Diffstat (limited to 'util/fbrun/FbRun.cc')
-rw-r--r-- | util/fbrun/FbRun.cc | 227 |
1 files changed, 32 insertions, 195 deletions
diff --git a/util/fbrun/FbRun.cc b/util/fbrun/FbRun.cc index caf51ce..701f985 100644 --- a/util/fbrun/FbRun.cc +++ b/util/fbrun/FbRun.cc | |||
@@ -19,7 +19,7 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: FbRun.cc,v 1.17 2003/08/25 01:18:00 fluxgen Exp $ | 22 | // $Id: FbRun.cc,v 1.18 2003/08/27 00:20:19 fluxgen Exp $ |
23 | 23 | ||
24 | #include "FbRun.hh" | 24 | #include "FbRun.hh" |
25 | 25 | ||
@@ -50,10 +50,8 @@ | |||
50 | 50 | ||
51 | using namespace std; | 51 | using namespace std; |
52 | FbRun::FbRun(int x, int y, size_t width): | 52 | FbRun::FbRun(int x, int y, size_t width): |
53 | FbTk::FbWindow((int)DefaultScreen(FbTk::App::instance()->display()), | 53 | FbTk::TextBox(DefaultScreen(FbTk::App::instance()->display()), |
54 | x, y, | 54 | m_font, ""), |
55 | width, 10, | ||
56 | KeyPressMask | ExposureMask), | ||
57 | m_font("fixed"), | 55 | m_font("fixed"), |
58 | m_display(FbTk::App::instance()->display()), | 56 | m_display(FbTk::App::instance()->display()), |
59 | m_bevel(4), | 57 | m_bevel(4), |
@@ -61,15 +59,13 @@ FbRun::FbRun(int x, int y, size_t width): | |||
61 | m_end(false), | 59 | m_end(false), |
62 | m_current_history_item(0), | 60 | m_current_history_item(0), |
63 | m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)), | 61 | m_cursor(XCreateFontCursor(FbTk::App::instance()->display(), XC_xterm)), |
64 | m_start_pos(0), | ||
65 | m_end_pos(0), | ||
66 | m_cursor_pos(0), | ||
67 | m_pixmap(0) { | 62 | m_pixmap(0) { |
68 | 63 | ||
64 | setGC(m_gc); | ||
69 | setCursor(m_cursor); | 65 | setCursor(m_cursor); |
70 | // setting nomaximize in local resize | 66 | // setting nomaximize in local resize |
71 | resize(width, m_font.height()); | 67 | resize(width, font().height() + m_bevel); |
72 | FbTk::EventManager::instance()->add(*this, *this); | 68 | |
73 | // setup class name | 69 | // setup class name |
74 | XClassHint *class_hint = XAllocClassHint(); | 70 | XClassHint *class_hint = XAllocClassHint(); |
75 | if (class_hint == 0) | 71 | if (class_hint == 0) |
@@ -91,10 +87,12 @@ FbRun::FbRun(int x, int y, size_t width): | |||
91 | XFreePixmap(m_display, mask); | 87 | XFreePixmap(m_display, mask); |
92 | #endif // HAVE_XPM | 88 | #endif // HAVE_XPM |
93 | 89 | ||
94 | XWMHints wmhints; | 90 | if (m_pixmap) { |
95 | wmhints.flags = IconPixmapHint; | 91 | XWMHints wmhints; |
96 | wmhints.icon_pixmap = m_pixmap; | 92 | wmhints.flags = IconPixmapHint; |
97 | XSetWMHints(m_display, window(), &wmhints); | 93 | wmhints.icon_pixmap = m_pixmap; |
94 | XSetWMHints(m_display, window(), &wmhints); | ||
95 | } | ||
98 | } | 96 | } |
99 | 97 | ||
100 | 98 | ||
@@ -118,18 +116,18 @@ void FbRun::run(const std::string &command) { | |||
118 | hide(); // hide gui | 116 | hide(); // hide gui |
119 | 117 | ||
120 | // save command history to file | 118 | // save command history to file |
121 | if (m_runtext.size() != 0) { // no need to save empty command | 119 | if (text().size() != 0) { // no need to save empty command |
122 | 120 | ||
123 | // don't allow duplicates into the history file, first | 121 | // don't allow duplicates into the history file, first |
124 | // look for a duplicate | 122 | // look for a duplicate |
125 | if (m_current_history_item < m_history.size() | 123 | if (m_current_history_item < m_history.size() |
126 | && m_runtext == m_history[m_current_history_item]) { | 124 | && text() == m_history[m_current_history_item]) { |
127 | // m_current_history_item is the duplicate | 125 | // m_current_history_item is the duplicate |
128 | } else { | 126 | } else { |
129 | m_current_history_item = 0; | 127 | m_current_history_item = 0; |
130 | for (; m_current_history_item < m_history.size(); | 128 | for (; m_current_history_item < m_history.size(); |
131 | ++m_current_history_item) { | 129 | ++m_current_history_item) { |
132 | if (m_history[m_current_history_item] == m_runtext) | 130 | if (m_history[m_current_history_item] == text()) |
133 | break; | 131 | break; |
134 | } | 132 | } |
135 | } | 133 | } |
@@ -147,7 +145,7 @@ void FbRun::run(const std::string &command) { | |||
147 | inoutfile<<m_history[i]<<endl; | 145 | inoutfile<<m_history[i]<<endl; |
148 | 146 | ||
149 | // and append the current one back to the end | 147 | // and append the current one back to the end |
150 | inoutfile<<m_runtext<<endl; | 148 | inoutfile<<text()<<endl; |
151 | } else | 149 | } else |
152 | cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl; | 150 | cerr<<"FbRun Warning: Can't write command history to file: "<<m_history_file<<endl; |
153 | } | 151 | } |
@@ -184,23 +182,12 @@ bool FbRun::loadFont(const string &fontname) { | |||
184 | return false; | 182 | return false; |
185 | 183 | ||
186 | // resize to fit new font height | 184 | // resize to fit new font height |
187 | resize(width(), m_font.height() + m_bevel); | 185 | resize(width(), font().height() + m_bevel); |
188 | return true; | 186 | return true; |
189 | } | 187 | } |
190 | 188 | ||
191 | void FbRun::setForegroundColor(const FbTk::Color &color) { | 189 | void FbRun::setForegroundColor(const FbTk::Color &color) { |
192 | XSetForeground(m_display, m_gc, color.pixel()); | 190 | XSetForeground(m_display, m_gc, color.pixel()); |
193 | redrawLabel(); | ||
194 | } | ||
195 | |||
196 | void FbRun::setBackgroundColor(const FbTk::Color &color) { | ||
197 | FbTk::FbWindow::setBackgroundColor(color); | ||
198 | redrawLabel(); | ||
199 | } | ||
200 | |||
201 | void FbRun::setText(const string &text) { | ||
202 | m_runtext = text; | ||
203 | redrawLabel(); | ||
204 | } | 191 | } |
205 | 192 | ||
206 | void FbRun::setTitle(const string &title) { | 193 | void FbRun::setTitle(const string &title) { |
@@ -208,30 +195,16 @@ void FbRun::setTitle(const string &title) { | |||
208 | } | 195 | } |
209 | 196 | ||
210 | void FbRun::resize(size_t width, size_t height) { | 197 | void FbRun::resize(size_t width, size_t height) { |
211 | FbTk::FbWindow::resize(width, height); | 198 | FbTk::TextBox::resize(width, height); |
212 | setNoMaximize(); | 199 | setNoMaximize(); |
213 | } | 200 | } |
214 | 201 | ||
215 | void FbRun::redrawLabel() { | 202 | void FbRun::redrawLabel() { |
216 | clear(); | 203 | clear(); |
217 | drawString(m_bevel/2, m_font.ascent() + m_bevel/2, | ||
218 | m_runtext.c_str(), m_runtext.size()); | ||
219 | |||
220 | } | ||
221 | |||
222 | void FbRun::drawString(int x, int y, | ||
223 | const char *text, size_t len) { | ||
224 | assert(m_gc); | ||
225 | |||
226 | m_font.drawText(window(), screenNumber(), | ||
227 | m_gc, text + m_start_pos, | ||
228 | m_end_pos - m_start_pos, x, y - 2); | ||
229 | // draw cursor position | ||
230 | int cursor_pos = m_font.textWidth(text + m_start_pos, m_cursor_pos) + 1; | ||
231 | drawLine(m_gc, cursor_pos, 0, cursor_pos, m_font.height()); | ||
232 | } | 204 | } |
233 | 205 | ||
234 | void FbRun::keyPressEvent(XKeyEvent &ke) { | 206 | void FbRun::keyPressEvent(XKeyEvent &ke) { |
207 | FbTk::TextBox::keyPressEvent(ke); | ||
235 | KeySym ks; | 208 | KeySym ks; |
236 | char keychar[1]; | 209 | char keychar[1]; |
237 | XLookupString(&ke, keychar, 1, &ks, 0); | 210 | XLookupString(&ke, keychar, 1, &ks, 0); |
@@ -241,30 +214,12 @@ void FbRun::keyPressEvent(XKeyEvent &ke) { | |||
241 | if (ke.state) { // a modifier key is down | 214 | if (ke.state) { // a modifier key is down |
242 | if (ke.state == ControlMask) { | 215 | if (ke.state == ControlMask) { |
243 | switch (ks) { | 216 | switch (ks) { |
244 | case XK_b: | ||
245 | cursorLeft(); | ||
246 | break; | ||
247 | case XK_f: | ||
248 | cursorRight(); | ||
249 | break; | ||
250 | case XK_p: | 217 | case XK_p: |
251 | prevHistoryItem(); | 218 | prevHistoryItem(); |
252 | break; | 219 | break; |
253 | case XK_n: | 220 | case XK_n: |
254 | nextHistoryItem(); | 221 | nextHistoryItem(); |
255 | break; | 222 | break; |
256 | case XK_a: | ||
257 | cursorHome(); | ||
258 | break; | ||
259 | case XK_e: | ||
260 | cursorEnd(); | ||
261 | break; | ||
262 | case XK_d: | ||
263 | deleteForward(); | ||
264 | break; | ||
265 | case XK_k: | ||
266 | killToEnd(); | ||
267 | break; | ||
268 | } | 223 | } |
269 | } else if (ke.state == (Mod1Mask | ShiftMask)) { | 224 | } else if (ke.state == (Mod1Mask | ShiftMask)) { |
270 | switch (ks) { | 225 | switch (ks) { |
@@ -275,8 +230,6 @@ void FbRun::keyPressEvent(XKeyEvent &ke) { | |||
275 | lastHistoryItem(); | 230 | lastHistoryItem(); |
276 | break; | 231 | break; |
277 | } | 232 | } |
278 | } else if (ke.state == ShiftMask) { | ||
279 | if (isprint(keychar[0]))insertCharacter(ks, keychar); | ||
280 | } | 233 | } |
281 | } else { // no modifier key | 234 | } else { // no modifier key |
282 | switch (ks) { | 235 | switch (ks) { |
@@ -286,17 +239,7 @@ void FbRun::keyPressEvent(XKeyEvent &ke) { | |||
286 | FbTk::App::instance()->end(); // end program | 239 | FbTk::App::instance()->end(); // end program |
287 | break; | 240 | break; |
288 | case XK_Return: | 241 | case XK_Return: |
289 | run(m_runtext); | 242 | run(text()); |
290 | m_runtext = ""; // clear text | ||
291 | break; | ||
292 | case XK_BackSpace: | ||
293 | backspace(); | ||
294 | break; | ||
295 | case XK_Home: | ||
296 | cursorHome(); | ||
297 | break; | ||
298 | case XK_End: | ||
299 | cursorEnd(); | ||
300 | break; | 243 | break; |
301 | case XK_Up: | 244 | case XK_Up: |
302 | prevHistoryItem(); | 245 | prevHistoryItem(); |
@@ -304,24 +247,12 @@ void FbRun::keyPressEvent(XKeyEvent &ke) { | |||
304 | case XK_Down: | 247 | case XK_Down: |
305 | nextHistoryItem(); | 248 | nextHistoryItem(); |
306 | break; | 249 | break; |
307 | case XK_Left: | ||
308 | cursorLeft(); | ||
309 | break; | ||
310 | case XK_Right: | ||
311 | cursorRight(); | ||
312 | break; | ||
313 | case XK_Tab: | 250 | case XK_Tab: |
314 | tabCompleteHistory(); | 251 | tabCompleteHistory(); |
315 | break; | 252 | break; |
316 | default: | ||
317 | if (isprint(keychar[0])) insertCharacter(ks, keychar); | ||
318 | } | 253 | } |
319 | } | 254 | } |
320 | redrawLabel(); | 255 | clear(); |
321 | } | ||
322 | |||
323 | void FbRun::exposeEvent(XExposeEvent &ev) { | ||
324 | redrawLabel(); | ||
325 | } | 256 | } |
326 | 257 | ||
327 | void FbRun::setNoMaximize() { | 258 | void FbRun::setNoMaximize() { |
@@ -340,9 +271,7 @@ void FbRun::prevHistoryItem() { | |||
340 | XBell(m_display, 0); | 271 | XBell(m_display, 0); |
341 | } else { | 272 | } else { |
342 | m_current_history_item--; | 273 | m_current_history_item--; |
343 | m_runtext = m_history[m_current_history_item]; | 274 | setText(m_history[m_current_history_item]); |
344 | m_cursor_pos = m_end_pos = m_runtext.size(); | ||
345 | adjustStartPos(); | ||
346 | } | 275 | } |
347 | } | 276 | } |
348 | 277 | ||
@@ -353,13 +282,9 @@ void FbRun::nextHistoryItem() { | |||
353 | m_current_history_item++; | 282 | m_current_history_item++; |
354 | if (m_current_history_item == m_history.size()) { | 283 | if (m_current_history_item == m_history.size()) { |
355 | m_current_history_item = m_history.size(); | 284 | m_current_history_item = m_history.size(); |
356 | m_runtext = ""; | 285 | setText(""); |
357 | m_start_pos = m_cursor_pos = m_end_pos = 0; | 286 | } else |
358 | } else { | 287 | setText(m_history[m_current_history_item]); |
359 | m_runtext = m_history[m_current_history_item]; | ||
360 | m_cursor_pos = m_end_pos = m_runtext.size(); | ||
361 | adjustStartPos(); | ||
362 | } | ||
363 | } | 288 | } |
364 | } | 289 | } |
365 | 290 | ||
@@ -368,9 +293,7 @@ void FbRun::firstHistoryItem() { | |||
368 | XBell(m_display, 0); | 293 | XBell(m_display, 0); |
369 | } else { | 294 | } else { |
370 | m_current_history_item = 0; | 295 | m_current_history_item = 0; |
371 | m_runtext = m_history[m_current_history_item]; | 296 | setText(m_history[m_current_history_item]); |
372 | m_cursor_pos = m_end_pos = m_runtext.size(); | ||
373 | adjustStartPos(); | ||
374 | } | 297 | } |
375 | } | 298 | } |
376 | 299 | ||
@@ -380,8 +303,7 @@ void FbRun::lastHistoryItem() { | |||
380 | XBell(m_display, 0); | 303 | XBell(m_display, 0); |
381 | } else { | 304 | } else { |
382 | m_current_history_item = m_history.size(); | 305 | m_current_history_item = m_history.size(); |
383 | m_runtext = ""; | 306 | setText(""); |
384 | m_start_pos = m_cursor_pos = m_end_pos = 0; | ||
385 | } | 307 | } |
386 | } | 308 | } |
387 | 309 | ||
@@ -390,12 +312,11 @@ void FbRun::tabCompleteHistory() { | |||
390 | XBell(m_display, 0); | 312 | XBell(m_display, 0); |
391 | } else { | 313 | } else { |
392 | int history_item = m_current_history_item - 1; | 314 | int history_item = m_current_history_item - 1; |
393 | string prefix = m_runtext.substr(0, m_cursor_pos); | 315 | string prefix = text().substr(0, cursorPosition()); |
394 | while (history_item > - 1) { | 316 | while (history_item > - 1) { |
395 | if (m_history[history_item].find(prefix) == 0) { | 317 | if (m_history[history_item].find(prefix) == 0) { |
396 | m_current_history_item = history_item; | 318 | m_current_history_item = history_item; |
397 | m_runtext = m_history[m_current_history_item]; | 319 | setText(m_history[m_current_history_item]); |
398 | adjustEndPos(); | ||
399 | break; | 320 | break; |
400 | } | 321 | } |
401 | history_item--; | 322 | history_item--; |
@@ -404,92 +325,8 @@ void FbRun::tabCompleteHistory() { | |||
404 | } | 325 | } |
405 | } | 326 | } |
406 | 327 | ||
407 | void FbRun::cursorLeft() { | 328 | void FbRun::insertCharacter(char keychar) { |
408 | if (m_cursor_pos) | 329 | char val[2] = {keychar, 0}; |
409 | m_cursor_pos--; | 330 | insertText(val); |
410 | else if (m_start_pos) { | ||
411 | m_start_pos--; | ||
412 | adjustEndPos(); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | void FbRun::cursorRight() { | ||
417 | if (m_start_pos + m_cursor_pos < m_end_pos) | ||
418 | m_cursor_pos++; | ||
419 | else if (m_end_pos < m_runtext.size()) { | ||
420 | m_cursor_pos++; | ||
421 | m_end_pos++; | ||
422 | adjustStartPos(); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | void FbRun::cursorHome() { | ||
427 | m_start_pos = m_cursor_pos = 0; | ||
428 | adjustEndPos(); | ||
429 | } | 331 | } |
430 | 332 | ||
431 | void FbRun::cursorEnd() { | ||
432 | m_cursor_pos = m_end_pos = m_runtext.size(); | ||
433 | adjustStartPos(); | ||
434 | } | ||
435 | |||
436 | void FbRun::backspace() { | ||
437 | if (m_start_pos || m_cursor_pos) { | ||
438 | m_runtext.erase(m_start_pos + m_cursor_pos - 1, 1); | ||
439 | if (m_cursor_pos) | ||
440 | m_cursor_pos--; | ||
441 | else | ||
442 | m_start_pos--; | ||
443 | adjustEndPos(); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | void FbRun::deleteForward() { | ||
448 | if (m_start_pos + m_cursor_pos < m_end_pos) { | ||
449 | m_runtext.erase(m_start_pos + m_cursor_pos, 1); | ||
450 | adjustEndPos(); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | void FbRun::killToEnd() { | ||
455 | if (m_start_pos + m_cursor_pos < m_end_pos) { | ||
456 | m_runtext.erase(m_start_pos + m_cursor_pos); | ||
457 | adjustEndPos(); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | void FbRun::insertCharacter(KeySym ks, char *keychar) { | ||
462 | char in_char[2] = {keychar[0], 0}; | ||
463 | m_runtext.insert(m_start_pos + m_cursor_pos, in_char); | ||
464 | m_cursor_pos++; | ||
465 | m_end_pos++; | ||
466 | if (m_start_pos + m_cursor_pos < m_end_pos) | ||
467 | adjustEndPos(); | ||
468 | else | ||
469 | adjustStartPos(); | ||
470 | } | ||
471 | |||
472 | void FbRun::adjustEndPos() { | ||
473 | m_end_pos = m_runtext.size(); | ||
474 | const char *text = m_runtext.c_str(); | ||
475 | int text_width = m_font.textWidth(text + m_start_pos, m_end_pos - m_start_pos); | ||
476 | while (text_width > width()) { | ||
477 | m_end_pos--; | ||
478 | text_width = m_font.textWidth(text + m_start_pos, m_end_pos - m_start_pos); | ||
479 | } | ||
480 | } | ||
481 | |||
482 | void FbRun::adjustStartPos() { | ||
483 | const char *text = m_runtext.c_str(); | ||
484 | int text_width = m_font.textWidth(text + m_start_pos, m_end_pos - m_start_pos); | ||
485 | if (text_width < width()) return; | ||
486 | int start_pos = 0; | ||
487 | text_width = m_font.textWidth(text + start_pos, m_end_pos - start_pos); | ||
488 | while (text_width > width()) { | ||
489 | start_pos++; | ||
490 | text_width = m_font.textWidth(text + start_pos, m_end_pos - start_pos); | ||
491 | } | ||
492 | // adjust m_cursor_pos according relative to change to m_start_pos | ||
493 | m_cursor_pos -= start_pos - m_start_pos; | ||
494 | m_start_pos = start_pos; | ||
495 | } | ||