fltk  1.3.5-source
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X.
  Fossies Dox: fltk-1.3.5-source.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_Input.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // Input widget for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2016 by Bill Spitzak and others.
7 //
8 // This library is free software. Distribution and use rights are outlined in
9 // the file "COPYING" which should have been included with this file. If this
10 // file is missing or damaged, see the license at:
11 //
12 // http://www.fltk.org/COPYING.php
13 //
14 // Please report all bugs and problems on the following page:
15 //
16 // http://www.fltk.org/str.php
17 //
18 
19 // This is the "user interface", it decodes user actions into what to
20 // do to the text. See also Fl_Input_.cxx, where the text is actually
21 // manipulated (and some ui, in particular the mouse, is done...).
22 // In theory you can replace this code with another subclass to change
23 // the keybindings.
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <FL/Fl.H>
28 #include <FL/Fl_Window.H>
29 #include <FL/Fl_Input.H>
30 #include <FL/fl_draw.H>
31 #include <FL/fl_ask.H>
32 #include "flstring.h"
33 
34 #include <FL/Fl_Float_Input.H>
35 #include <FL/Fl_Int_Input.H>
36 #include <FL/Fl_Multiline_Input.H>
37 #include <FL/Fl_Output.H>
38 #include <FL/Fl_Multiline_Output.H>
39 #include <FL/Fl_Secret_Input.H>
40 
41 #ifdef HAVE_LOCALE_H
42 # include <locale.h>
43 #endif
44 
45 
47  if (input_type() == FL_HIDDEN_INPUT) return;
48  Fl_Boxtype b = box();
49  if (damage() & FL_DAMAGE_ALL) draw_box(b, color());
51  w()-Fl::box_dw(b), h()-Fl::box_dh(b));
52 }
53 
54 // kludge so shift causes selection to extend:
56  return position(p, Fl::event_state(FL_SHIFT) ? mark() : p);
57 }
58 
61 }
62 
63 // Old text from FLTK 1.1 for reference:
64 // If you define NORMAL_INPUT_MOVE as zero you will get the peculiar fltk
65 // behavior where moving off the end of an input field will move the
66 // cursor into the next field:
67 // define it as 1 to prevent cursor movement from going to next field:
68 //
69 // Note: this has been replaced by Fl::option(Fl::OPTION_ARROW_FOCUS)
70 // in FLTK 1.3. This option has "inverted" values:
71 // 1 = Arrow keys move focus (previously 0)
72 // 0 = Arrow keys don't move focus (previously 1)
73 // Hence we define ...
74 //
75 #define NORMAL_INPUT_MOVE (Fl::option(Fl::OPTION_ARROW_FOCUS) ? 0 : 1)
76 
77 #define ctrl(x) ((x)^0x40)
78 
79 // List of characters that are legal in a floating point input field.
80 // This text string is created at run-time to take the current locale
81 // into account (for example, continental Europe uses a comma instead
82 // of a decimal point). For back compatibility reasons, we always
83 // allow the decimal point.
84 #ifdef HAVE_LOCALECONV
85 static const char *standard_fp_chars = ".eE+-";
86 static const char *legal_fp_chars = 0L;
87 #else
88 static const char *legal_fp_chars = ".eE+-";
89 #endif
90 
91 // Move cursor up specified #lines
92 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
93 //
94 int Fl_Input::kf_lines_up(int repeat_num) {
95  int i = position();
96  if (!line_start(i)) {
97  //UNNEEDED if (input_type()==FL_MULTILINE_INPUT && !Fl::option(Fl::OPTION_ARROW_FOCUS)) return 1;
98  return NORMAL_INPUT_MOVE;
99  }
100  while(repeat_num--) {
101  i = line_start(i);
102  if (!i) break;
103  i--;
104  }
106  return 1;
107 }
108 
109 // Move cursor down specified #lines
110 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
111 //
112 int Fl_Input::kf_lines_down(int repeat_num) {
113  int i = position();
114  if (line_end(i) >= size()) {
115  //UNNEEDED if (input_type()==FL_MULTILINE_INPUT && !Fl::option(Fl::OPTION_ARROW_FOCUS)) return 1;
116  return NORMAL_INPUT_MOVE;
117  }
118  while (repeat_num--) {
119  i = line_end(i);
120  if (i >= size()) break;
121  i++;
122  }
124  return 1;
125 }
126 
127 // Move up a page
129  return kf_lines_up(linesPerPage());
130 }
131 
132 // Move down a page
134  return kf_lines_down(linesPerPage());
135 }
136 
137 // Toggle insert mode
139  if (readonly()) { fl_beep(); return 1; }
140  return 1; // \todo: needs insert mode
141 }
142 
143 // Delete word right
145  if (readonly()) { fl_beep(); return 1; }
146  if (mark() != position()) return cut();
147  cut(position(), word_end(position()));
148  return 1;
149 }
150 
151 // Delete word left
153  if (readonly()) { fl_beep(); return 1; }
154  if (mark() != position()) return cut();
156  return 1;
157 }
158 
159 // Delete to start of line
161  if (readonly()) { fl_beep(); return 1; }
162  if (mark() != position()) return cut();
164  return 1;
165 }
166 
167 // Delete to end of line
169  if (readonly()) { fl_beep(); return 1; }
170  if (mark() != position()) return cut();
171  cut(position(), line_end(position()));
172  return 1;
173 }
174 
176  if (readonly()) { fl_beep(); return 1; }
177  if (mark() != position()) return cut();
178  else return cut(1);
179 }
180 
182  if (readonly()) { fl_beep(); return 1; }
183  if (mark() != position()) cut();
184  else cut(-1);
185  return 1;
186 }
187 
188 // Move cursor to start of line
191 }
192 
193 // Move cursor to end of line
196 }
197 
198 // Clear to end of line
200  if (readonly()) { fl_beep(); return 1; }
201  if (position()>=size()) return 0;
202  int i = line_end(position());
203  if (i == position() && i < size()) i++;
204  cut(position(), i);
205  return copy_cuts();
206 }
207 
208 // Move cursor one character to the left
209 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
210 //
213  return Fl::option(Fl::OPTION_ARROW_FOCUS) ? i : 1;
214 }
215 
216 // Move cursor one character to the right
217 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
218 //
221  return Fl::option(Fl::OPTION_ARROW_FOCUS) ? i : 1;
222 }
223 
224 // Move cursor word-left
227  return 1;
228 }
229 
230 // Move cursor word-right
233  return 1;
234 }
235 
236 // Move cursor up one line and to the start of line (paragraph up)
238  if (line_start(position())==position() && position()>0)
240  else
242 }
243 
244 // Move cursor down one line and to the end of line (paragraph down)
246  if (line_end(position())==position() && position()<size())
248  else
250 }
251 
252 // Move to top of document
254  shift_position(0);
255  return 1;
256 }
257 
258 // Move to bottom of document
260  shift_position(size());
261  return 1;
262 }
263 
264 // Select all text in the widget
266  position(0,size());
267  return 1;
268 }
269 
270 // Undo.
272  if (readonly()) { fl_beep(); return 1; }
273  return undo();
274 }
275 
276 // Redo. (currently unimplemented.. toggles undo() instead)
278  if (readonly()) { fl_beep(); return 1; }
279  return kf_undo(); // currently we don't support multilevel undo
280 }
281 
282 // Do a copy operation
284  return copy(1);
285 }
286 
287 // Do a paste operation
289  if (readonly()) { fl_beep(); return 1; }
290  Fl::paste(*this, 1);
291  return 1;
292 }
293 
294 // Do a cut with copy
296  if (readonly()) { fl_beep(); return 1; }
297  copy(1);
298  return cut();
299 }
300 
301 // Handle a keystroke.
302 // Returns 1 if handled by us, 0 if not.
303 //
305 
306  char ascii = Fl::event_text()[0];
307 
308  int del;
309  if (Fl::compose(del)) {
310 
311  // Insert characters into numeric fields after checking for legality:
313  Fl::compose_reset(); // ignore any foreign letters...
314 
315  // initialize the list of legal characters inside a floating point number
316 #ifdef HAVE_LOCALECONV
317  if (!legal_fp_chars) {
318  size_t len = strlen(standard_fp_chars);
319  struct lconv *lc = localeconv();
320  if (lc) {
321  if (lc->decimal_point) len += strlen(lc->decimal_point);
322  if (lc->mon_decimal_point) len += strlen(lc->mon_decimal_point);
323  if (lc->positive_sign) len += strlen(lc->positive_sign);
324  if (lc->negative_sign) len += strlen(lc->negative_sign);
325  }
326  // the following line is not a true memory leak because the array is only
327  // allocated once if required, and automatically freed when the program quits
328  char *chars = (char*)malloc(len+1);
330  strcpy(chars, standard_fp_chars);
331  if (lc) {
332  if (lc->decimal_point) strcat(chars, lc->decimal_point);
333  if (lc->mon_decimal_point) strcat(chars, lc->mon_decimal_point);
334  if (lc->positive_sign) strcat(chars, lc->positive_sign);
335  if (lc->negative_sign) strcat(chars, lc->negative_sign);
336  }
337  }
338 #endif // HAVE_LOCALECONV
339 
340  // find the insert position
341  int ip = position()<mark() ? position() : mark();
342  // This is complex to allow "0xff12" hex to be typed:
343  if ( (!ip && (ascii == '+' || ascii == '-'))
344  || (ascii >= '0' && ascii <= '9')
345  || (ip==1 && index(0)=='0' && (ascii=='x' || ascii == 'X'))
346  || (ip>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X')
347  && ((ascii>='A'&& ascii<='F') || (ascii>='a'&& ascii<='f')))
348  || (input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii)))
349  {
350  if (readonly()) fl_beep();
351  else replace(position(), mark(), &ascii, 1);
352  }
353  return 1;
354  }
355 
356  if (del || Fl::event_length()) {
357  if (readonly()) fl_beep();
358  else replace(position(), del ? position()-del : mark(),
360  }
361 #ifdef __APPLE__
362  if (Fl::compose_state) {
363  this->mark( this->position() - Fl::compose_state );
364  }
365 #endif
366  return 1;
367  }
368 
369  unsigned int mods = Fl::event_state() & (FL_META|FL_CTRL|FL_ALT);
370  unsigned int shift = Fl::event_state() & FL_SHIFT;
371  unsigned int multiline = (input_type() == FL_MULTILINE_INPUT) ? 1 : 0;
372  //
373  // The following lists apps that support these keypresses.
374  // Prefixes: '!' indicates NOT supported, '?' indicates un-verified.
375  //
376  // HIG=Human Interface Guide,
377  // TE=TextEdit.app, SA=Safari.app, WOX=MS Word/OSX -- OSX 10.4.x
378  // NP=Notepad, WP=WordPad, WOW=MS Word/Windows -- WinXP
379  // GE=gedit, KE=kedit -- Ubuntu8.04
380  // OF=old FLTK behavior (<=1.1.10)
381  //
382  // Example: (NP,WP,!WO) means supported in notepad + wordpad, but NOT word.
383  //
384  switch (Fl::event_key()) {
385 
386  case FL_Insert:
387  // Note: Mac has no "Insert" key; it's the "Help" key.
388  // This keypress is apparently not possible on macs.
389  //
390  if (mods==0 && shift) return kf_paste(); // Shift-Insert (WP,NP,WOW,GE,KE,OF)
391  if (mods==0) return kf_insert_toggle(); // Insert (Standard)
392  if (mods==FL_CTRL) return kf_copy(); // Ctrl-Insert (WP,NP,WOW,GE,KE,OF)
393  return 0; // ignore other combos, pass to parent
394 
395  case FL_Delete: {
396 #ifdef __APPLE__
397  if (mods==0) return kf_delete_char_right(); // Delete (OSX-HIG,TE,SA,WOX)
398  if (mods==FL_CTRL) return kf_delete_char_right(); // Ctrl-Delete (??? TE,!SA,!WOX)
399  if (mods==FL_ALT) return kf_delete_word_right(); // Alt-Delete (OSX-HIG,TE,SA)
400  return 0; // ignore other combos, pass to parent
401 #else
402  int selected = (position() != mark()) ? 1 : 0;
403  if (mods==0 && shift && selected)
404  return kf_copy_cut(); // Shift-Delete with selection (WP,NP,WOW,GE,KE,OF)
405  if (mods==0 && shift && !selected)
406  return kf_delete_char_right(); // Shift-Delete no selection (WP,NP,WOW,GE,KE,!OF)
407  if (mods==0) return kf_delete_char_right(); // Delete (Standard)
408  if (mods==FL_CTRL) return kf_delete_word_right(); // Ctrl-Delete (WP,!NP,WOW,GE,KE,!OF)
409  return 0; // ignore other combos, pass to parent
410 #endif
411  }
412 
413  case FL_Left:
414 #ifdef __APPLE__
415  if (mods==0) return kf_move_char_left(); // Left (OSX-HIG)
416  if (mods==FL_ALT) return kf_move_word_left(); // Alt-Left (OSX-HIG)
417  if (mods==FL_META) return kf_move_sol(); // Meta-Left (OSX-HIG)
418  if (mods==FL_CTRL) return kf_move_sol(); // Ctrl-Left (TE/SA)
419  return 0; // ignore other combos, pass to parent
420 #else
421  if (mods==0) return kf_move_char_left(); // Left (WP,NP,WOW,GE,KE,OF)
422  if (mods==FL_CTRL) return kf_move_word_left(); // Ctrl-Left (WP,NP,WOW,GE,KE,!OF)
423  if (mods==FL_META) return kf_move_char_left(); // Meta-Left (WP,NP,?WOW,GE,KE)
424  return 0; // ignore other combos, pass to parent
425 #endif
426 
427  case FL_Right:
428 #ifdef __APPLE__
429  if (mods==0) return kf_move_char_right(); // Right (OSX-HIG)
430  if (mods==FL_ALT) return kf_move_word_right(); // Alt-Right (OSX-HIG)
431  if (mods==FL_META) return kf_move_eol(); // Meta-Right (OSX-HIG)
432  if (mods==FL_CTRL) return kf_move_eol(); // Ctrl-Right (TE/SA)
433  return 0; // ignore other combos, pass to parent
434 #else
435  if (mods==0) return kf_move_char_right(); // Right (WP,NP,WOW,GE,KE,OF)
436  if (mods==FL_CTRL) return kf_move_word_right(); // Ctrl-Right (WP,NP,WOW,GE,KE,!OF)
437  if (mods==FL_META) return kf_move_char_right(); // Meta-Right (WP,NP,?WOW,GE,KE,!OF)
438  return 0; // ignore other combos, pass to parent
439 #endif
440 
441  case FL_Up:
442 #ifdef __APPLE__
443  if (mods==0) return kf_lines_up(1); // Up (OSX-HIG)
444  if (mods==FL_CTRL) return kf_page_up(); // Ctrl-Up (TE !HIG)
445  if (mods==FL_ALT) return kf_move_up_and_sol(); // Alt-Up (OSX-HIG)
446  if (mods==FL_META) return kf_top(); // Meta-Up (OSX-HIG)
447  return 0; // ignore other combos, pass to parent
448 #else
449  if (mods==0) return kf_lines_up(1); // Up (WP,NP,WOW,GE,KE,OF)
450  if (mods==FL_CTRL) return kf_move_up_and_sol(); // Ctrl-Up (WP,!NP,WOW,GE,!KE,OF)
451  return 0; // ignore other combos, pass to parent
452 #endif
453 
454  case FL_Down:
455 #ifdef __APPLE__
456  if (mods==0) return kf_lines_down(1); // Dn (OSX-HIG)
457  if (mods==FL_CTRL) return kf_page_down(); // Ctrl-Dn (TE !HIG)
458  if (mods==FL_ALT) return kf_move_down_and_eol(); // Alt-Dn (OSX-HIG)
459  if (mods==FL_META) return kf_bottom(); // Meta-Dn (OSX-HIG)
460  return 0; // ignore other combos, pass to parent
461 #else
462  if (mods==0) return kf_lines_down(1); // Dn (WP,NP,WOW,GE,KE,OF)
463  if (mods==FL_CTRL) return kf_move_down_and_eol(); // Ctrl-Down (WP,!NP,WOW,GE,!KE,OF)
464  return 0; // ignore other combos, pass to parent
465 #endif
466 
467  case FL_Page_Up:
468  // Fl_Input has no scroll control, so instead we move the cursor by one page
469  // OSX-HIG recommends Alt increase one semantic unit, Meta next higher..
470 #ifdef __APPLE__
471  if (mods==0) return kf_page_up(); // PgUp (OSX-HIG)
472  if (mods==FL_ALT) return kf_page_up(); // Alt-PageUp (OSX-HIG)
473  if (mods==FL_META) return kf_top(); // Meta-PageUp (OSX-HIG,!TE)
474  return 0; // ignore other combos, pass to parent
475 #else
476  if (mods==0) return kf_page_up(); // PageUp (WP,NP,WOW,GE,KE)
477  if (mods==FL_CTRL) return kf_page_up(); // Ctrl-PageUp (!WP,!NP,!WOW,!GE,KE,OF)
478  if (mods==FL_ALT) return kf_page_up(); // Alt-PageUp (!WP,!NP,!WOW,!GE,KE,OF)
479  return 0; // ignore other combos, pass to parent
480 #endif
481 
482  case FL_Page_Down:
483 #ifdef __APPLE__
484  // Fl_Input has no scroll control, so instead we move the cursor by one page
485  // OSX-HIG recommends Alt increase one semantic unit, Meta next higher..
486  if (mods==0) return kf_page_down(); // PgDn (OSX-HIG)
487  if (mods==FL_ALT) return kf_page_down(); // Alt-PageDn (OSX-HIG)
488  if (mods==FL_META) return kf_bottom(); // Meta-PageDn (OSX-HIG,!TE)
489  return 0; // ignore other combos, pass to parent
490 #else
491  if (mods==0) return kf_page_down(); // PageDn (WP,NP,WOW,GE,KE)
492  if (mods==FL_CTRL) return kf_page_down(); // Ctrl-PageDn (!WP,!NP,!WOW,!GE,KE,OF)
493  if (mods==FL_ALT) return kf_page_down(); // Alt-PageDn (!WP,!NP,!WOW,!GE,KE,OF)
494  return 0; // ignore other combos, pass to parent
495 #endif
496 
497  case FL_Home:
498 #ifdef __APPLE__
499  if (mods==0) return kf_top(); // Home (OSX-HIG)
500  if (mods==FL_ALT) return kf_top(); // Alt-Home (???)
501  return 0; // ignore other combos, pass to parent
502 #else
503  if (mods==0) return kf_move_sol(); // Home (WP,NP,WOW,GE,KE,OF)
504  if (mods==FL_CTRL) return kf_top(); // Ctrl-Home (WP,NP,WOW,GE,KE,OF)
505  return 0; // ignore other combos, pass to parent
506 #endif
507 
508  case FL_End:
509 #ifdef __APPLE__
510  if (mods==0) return kf_bottom(); // End (OSX-HIG)
511  if (mods==FL_ALT) return kf_bottom(); // Alt-End (???)
512  return 0; // ignore other combos, pass to parent
513 #else
514  if (mods==0) return kf_move_eol(); // End (WP,NP,WOW,GE,KE,OF)
515  if (mods==FL_CTRL) return kf_bottom(); // Ctrl-End (WP,NP,WOW,GE,KE,OF)
516  return 0; // ignore other combos, pass to parent
517 #endif
518 
519  case FL_BackSpace:
520 #ifdef __APPLE__
521  if (mods==0) return kf_delete_char_left(); // Backspace (OSX-HIG)
522  if (mods==FL_CTRL) return kf_delete_char_left(); // Ctrl-Backspace (TE/SA)
523  if (mods==FL_ALT) return kf_delete_word_left(); // Alt-Backspace (OSX-HIG)
524  if (mods==FL_META) return kf_delete_sol(); // Meta-Backspace (OSX-HIG,!TE)
525  return 0; // ignore other combos, pass to parent
526 #else
527  if (mods==0) return kf_delete_char_left(); // Backspace (WP,NP,WOW,GE,KE,OF)
528  if (mods==FL_CTRL) return kf_delete_word_left(); // Ctrl-Backspace (WP,!NP,WOW,GE,KE,!OF)
529  return 0; // ignore other combos, pass to parent
530 #endif
531 
532  case FL_Enter:
533  case FL_KP_Enter:
534  if (when() & FL_WHEN_ENTER_KEY) {
535  position(size(), 0);
537  return 1;
538  } else if (multiline && !readonly()) {
539  return replace(position(), mark(), "\n", 1);
540  } return 0; // reserved for shortcuts
541 
542  case FL_Tab:
543  // Handle special case for multiline input with 'old tab behavior';
544  // tab handled as a normal insertable character.
545  //
546  if (mods==0 && !shift // Tab?
547  && !tab_nav() // old tab behavior enabled?
548  && multiline) { // multiline input?
549  break; // insert tab character
550  }
551  if (mods==0) return 0; // Tab, Shift-Tab? nav focus (Standard/OSX-HIG)
552  return 0; // ignore other combos, pass to parent
553 
554  case 'a':
555  if (mods==FL_COMMAND) return kf_select_all(); // Ctrl-A, Mac:Meta-A (Standard/OSX-HIG)
556  break; // handle other combos elsewhere
557  case 'c':
558  if (mods==FL_COMMAND) return kf_copy(); // Ctrl-C, Mac:Meta-C (Standard/OSX-HIG)
559  break; // handle other combos elsewhere
560  case 'v':
561  if (mods==FL_COMMAND) return kf_paste(); // Ctrl-V, Mac:Meta-V (Standard/OSX-HIG)
562  break; // handle other combos elsewhere
563  case 'x':
564  if (mods==FL_COMMAND) return kf_copy_cut(); // Ctrl-X, Mac:Meta-X (Standard/OSX-HIG)
565  break;
566  case 'z':
567  if (mods==FL_COMMAND && !shift) return kf_undo(); // Ctrl-Z, Mac:Meta-Z (Standard/OSX-HIG)
568  if (mods==FL_COMMAND && shift) return kf_redo(); // Shift-Ctrl-Z, Mac:Shift-Meta-Z (Standard/OSX-HIG)
569  break; // handle other combos elsewhere
570  }
571 
572  switch (ascii) {
573  case ctrl('H'):
574  return kf_delete_char_left(); // Ctrl-H (!WP,!NP,!WOW,!WOX,TE,SA,GE,KE,OF)
575  case ctrl('I'): // Ctrl-I (literal Tab) (!WP,NP,!WOW,!GE,KE,OF)
576  case ctrl('J'): // Ctrl-J (literal Line Feed/Enter) (Standard)
577  case ctrl('L'): // Ctrl-L (literal Form Feed) (Standard)
578  case ctrl('M'): // Ctrl-M (literal Cr) (Standard)
579  if (readonly()) { fl_beep(); return 1; }
580  // insert a few selected control characters literally:
582  return replace(position(), mark(), &ascii, 1);
583  break;
584  }
585 
586  return 0; // ignored
587 }
588 
589 int Fl_Input::handle(int event) {
590  static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos;
591  static Fl_Widget *dnd_save_focus = NULL;
592  switch (event) {
593 #ifdef __APPLE__
594  case FL_UNFOCUS:
595  if (Fl::compose_state) {
596  this->mark( this->position() );
597  Fl::reset_marked_text();
598  }
599  break;
600 #endif
601  case FL_FOCUS:
602  switch (Fl::event_key()) {
603  case FL_Right:
604  position(0);
605  break;
606  case FL_Left:
607  position(size());
608  break;
609  case FL_Down:
610  up_down_position(0);
611  break;
612  case FL_Up:
614  break;
615  case FL_Tab:
616  position(size(),0);
617  break;
618  default:
619  position(position(),mark());// turns off the saved up/down arrow position
620  break;
621  }
622  break;
623 
624  case FL_KEYBOARD:
625  // Handle special case for multiline input with 'old tab behavior'
626  // where tab is entered as a character: make sure user attempt to 'tab over'
627  // widget doesn't destroy the field, replacing it with a tab character.
628  //
629  if (Fl::event_key() == FL_Tab // Tab key?
630  && !Fl::event_state(FL_SHIFT) // no shift?
631  && !tab_nav() // with tab navigation disabled?
632  && input_type() == FL_MULTILINE_INPUT // with a multiline input?
633  && size() > 0 // non-empty field?
634  && ((mark()==0 && position()==size()) || (position()==0 && mark()==size()))) {// while entire field selected?
635  // Set cursor to the end of the selection...
636  if (mark() > position())
637  position(mark());
638  else
639  position(position());
640  return (1);
641  } else {
642  if (active_r() && window() && this == Fl::belowmouse())
644  return handle_key();
645  }
646  //NOTREACHED
647 
648  case FL_PUSH:
649  if (Fl::dnd_text_ops()) {
650  int oldpos = position(), oldmark = mark();
651  Fl_Boxtype b = box();
653  w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
654  newpos = position();
655  position( oldpos, oldmark );
657  ( (newpos >= mark() && newpos < position()) ||
658  (newpos >= position() && newpos < mark()) ) ) {
659  // user clicked in the selection, may be trying to drag
660  drag_start = newpos;
661  return 1;
662  }
663  drag_start = -1;
664  }
665 
666  if (Fl::focus() != this) {
667  Fl::focus(this);
668  handle(FL_FOCUS);
669  }
670  break;
671 
672  case FL_DRAG:
673  if (Fl::dnd_text_ops()) {
674  if (drag_start >= 0) {
675  if (Fl::event_is_click()) return 1; // debounce the mouse
676  // save the position because sometimes we don't get DND_ENTER:
677  dnd_save_position = position();
678  dnd_save_mark = mark();
679  dnd_save_focus = this;
680  // drag the data:
681  copy(0);
682 #ifdef __APPLE__
683  Fl_X::dnd(1);
684 #else
685  Fl::dnd();
686 #endif
687  return 1;
688  }
689  }
690  break;
691 
692  case FL_RELEASE:
693  if (Fl::event_button() == 2) {
694  Fl::event_is_click(0); // stop double click from picking a word
695  Fl::paste(*this, 0);
696  } else if (!Fl::event_is_click()) {
697  // copy drag-selected text to the clipboard.
698  copy(0);
699  } else if (Fl::event_is_click() && drag_start >= 0) {
700  // user clicked in the field and wants to reset the cursor position...
701  position(drag_start, drag_start);
702  drag_start = -1;
703  } else if (Fl::event_clicks()) {
704  // user double or triple clicked to select word or whole text
705  copy(0);
706  }
707 
708  // For output widgets, do the callback so the app knows the user
709  // did something with the mouse...
710  if (readonly()) do_callback();
711 
712  return 1;
713 
714  case FL_DND_ENTER:
715  Fl::belowmouse(this); // send the leave events first
716  if (dnd_save_focus != this) {
717  dnd_save_position = position();
718  dnd_save_mark = mark();
719  dnd_save_focus = Fl::focus();
720  Fl::focus(this);
721  handle(FL_FOCUS);
722  }
723  // fall through:
724  case FL_DND_DRAG:
725  //int p = mouse_position(X, Y, W, H);
726 #ifdef DND_OUT_XXXX
727  if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark ||
728  p>=dnd_save_mark && p<=dnd_save_position)) {
729  position(dnd_save_position, dnd_save_mark);
730  return 0;
731  }
732 #endif
733  {
734  Fl_Boxtype b = box();
736  w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0);
737  }
738  return 1;
739 
740  case FL_DND_LEAVE:
741  position(dnd_save_position, dnd_save_mark);
742 #ifdef DND_OUT_XXXX
743  if (!focused())
744 #endif
745  if (dnd_save_focus && dnd_save_focus != this) {
746  Fl::focus(dnd_save_focus);
748  }
749 #if !(defined(__APPLE__) || defined(WIN32))
751 #endif
752  dnd_save_focus = NULL;
753  return 1;
754 
755  case FL_DND_RELEASE:
756  if (dnd_save_focus == this) { // if the dragged text comes from the same widget
757  // remove the selected text
758  int old_position = position();
759  if (dnd_save_mark > dnd_save_position) {
760  int tmp = dnd_save_mark;
761  dnd_save_mark = dnd_save_position;
762  dnd_save_position = tmp;
763  }
764  replace(dnd_save_mark, dnd_save_position, NULL, 0);
765  if (old_position > dnd_save_position) position(old_position - (dnd_save_position - dnd_save_mark));
766  else position(old_position);
767  }
768  else if(dnd_save_focus) {
769  dnd_save_focus->handle(FL_UNFOCUS);
770  }
771  dnd_save_focus = NULL;
772  take_focus();
773  return 1;
774 
775  /* TODO: this will scroll the area, but stop if the cursor would become invisible.
776  That clipping happens in drawtext(). Do we change the clipping or should
777  we move the cursor (ouch)?
778  case FL_MOUSEWHEEL:
779  if (Fl::e_dy > 0) {
780  yscroll( yscroll() - Fl::e_dy*15 );
781  } else if (Fl::e_dy < 0) {
782  yscroll( yscroll() - Fl::e_dy*15 );
783  }
784  return 1;
785  */
786  }
787  Fl_Boxtype b = box();
788  return Fl_Input_::handletext(event,
789  x()+Fl::box_dx(b), y()+Fl::box_dy(b),
790  w()-Fl::box_dw(b), h()-Fl::box_dh(b));
791 }
792 
797 Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l)
798 : Fl_Input_(X, Y, W, H, l) {
799 }
800 
801 
802 Fl_Float_Input::Fl_Float_Input(int X,int Y,int W,int H,const char *l)
803 : Fl_Input(X,Y,W,H,l)
804 {
807 }
808 
809 
810 Fl_Int_Input::Fl_Int_Input(int X,int Y,int W,int H,const char *l)
811 : Fl_Input(X,Y,W,H,l) {
814 }
815 
816 
817 Fl_Multiline_Input::Fl_Multiline_Input(int X,int Y,int W,int H,const char *l)
818 : Fl_Input(X,Y,W,H,l) {
820 }
821 
822 
823 Fl_Output::Fl_Output(int X,int Y,int W,int H, const char *l)
824 : Fl_Input(X, Y, W, H, l) {
826 }
827 
828 
829 Fl_Multiline_Output::Fl_Multiline_Output(int X,int Y,int W,int H,const char *l)
830 : Fl_Output(X,Y,W,H,l) {
832 }
833 
834 
835 Fl_Secret_Input::Fl_Secret_Input(int X,int Y,int W,int H,const char *l)
836 : Fl_Input(X,Y,W,H,l) {
839 }
840 
841 int Fl_Secret_Input::handle(int event) {
842  int retval = Fl_Input::handle(event);
843 #ifdef __APPLE__
844  if (event == FL_KEYBOARD && Fl::compose_state) {
845  this->mark( this->position() ); // don't underline marked text
846  }
847 #endif
848  return retval;
849 }
850 
851 //
852 // End of "$Id$".
853 //
FL_Up
#define FL_Up
The up arrow key.
Definition: Enumerations.H:481
Fl_Input::kf_move_sol
int kf_move_sol()
Definition: Fl_Input.cxx:189
Fl_Widget::y
int y() const
Definition: Fl_Widget.H:289
FL_Enter
#define FL_Enter
The enter key.
Definition: Enumerations.H:471
FL_DAMAGE_ALL
Definition: Enumerations.H:1112
Fl.H
Fl_Input_::copy_cuts
int copy_cuts()
Definition: Fl_Input_.cxx:977
FL_DND_ENTER
Definition: Enumerations.H:401
FL_BackSpace
#define FL_BackSpace
The backspace key.
Definition: Enumerations.H:468
FL_META
#define FL_META
One of the meta/Windows keys is down.
Definition: Enumerations.H:563
Fl_Input::kf_move_up_and_sol
int kf_move_up_and_sol()
Definition: Fl_Input.cxx:237
Fl_Widget::draw_box
void draw_box() const
Definition: fl_boxtype.cxx:442
Fl_Input::kf_delete_word_right
int kf_delete_word_right()
Definition: Fl_Input.cxx:144
chars
static const Fl_Glut_StrokeChar * chars[]
Definition: freeglut_stroke_mono_roman.cxx:2828
FL_UNFOCUS
Definition: Enumerations.H:288
FL_DND_RELEASE
Definition: Enumerations.H:417
Fl_Input::kf_move_word_left
int kf_move_word_left()
Definition: Fl_Input.cxx:225
Fl_Input.H
Fl::box_dx
static int box_dx(Fl_Boxtype)
Definition: fl_boxtype.cxx:360
Fl_Boxtype
Fl_Boxtype
Definition: Enumerations.H:603
Fl_Secret_Input::Fl_Secret_Input
Fl_Secret_Input(int X, int Y, int W, int H, const char *l=0)
Definition: Fl_Input.cxx:835
Fl::event_state
static int event_state()
Definition: Fl.H:704
fl_ask.H
Fl_Input::kf_delete_word_left
int kf_delete_word_left()
Definition: Fl_Input.cxx:152
FL_NORMAL_OUTPUT
#define FL_NORMAL_OUTPUT
Definition: Fl_Input_.H:37
Fl::event_button
static int event_button()
Definition: Fl.H:678
Fl_Widget::window
Fl_Window * window() const
Definition: Fl_Window.cxx:118
Fl_Input::kf_clear_eol
int kf_clear_eol()
Definition: Fl_Input.cxx:199
FL_DRAG
Definition: Enumerations.H:268
FL_SHIFT
#define FL_SHIFT
One of the shift keys is down.
Definition: Enumerations.H:557
FL_Page_Down
#define FL_Page_Down
The page-down key.
Definition: Enumerations.H:485
Fl::event_is_click
static int event_is_click()
Definition: Fl.H:661
Fl::event_text
static const char * event_text()
Definition: Fl.H:792
FL_SECRET_INPUT
#define FL_SECRET_INPUT
Definition: Fl_Input_.H:34
Fl_Float_Input::Fl_Float_Input
Fl_Float_Input(int X, int Y, int W, int H, const char *l=0)
Definition: Fl_Input.cxx:802
Fl_Input::shift_up_down_position
int shift_up_down_position(int p)
Definition: Fl_Input.cxx:59
H
static int H
Definition: Fl_Tooltip.cxx:76
FL_KP_Enter
#define FL_KP_Enter
The enter key on the keypad, same as Fl_KP+'\r'.
Definition: Enumerations.H:493
Fl::paste
static void paste(Fl_Widget &receiver, int source, const char *type)
Definition: Fl_win32.cxx:704
Fl_Input::kf_move_down_and_eol
int kf_move_down_and_eol()
Definition: Fl_Input.cxx:245
Fl::compose_reset
static void compose_reset()
Definition: Fl_compose.cxx:141
Fl_Widget::x
int x() const
Definition: Fl_Widget.H:284
NULL
#define NULL
Definition: forms.H:34
Fl_Input_::index
Fl_Char index(int i) const
Definition: Fl_Input_.cxx:1334
Fl::compose
static int compose(int &del)
Definition: Fl_compose.cxx:79
Fl_Input_::size
int size() const
Definition: Fl_Input_.H:257
Fl_Int_Input::Fl_Int_Input
Fl_Int_Input(int X, int Y, int W, int H, const char *l=0)
Definition: Fl_Input.cxx:810
Fl_Input::kf_page_down
int kf_page_down()
Definition: Fl_Input.cxx:133
FL_CURSOR_MOVE
Definition: Enumerations.H:1056
Fl_Widget::when
Fl_When when() const
Definition: Fl_Widget.H:621
Fl_Widget::do_callback
void do_callback()
Definition: Fl_Widget.H:861
Fl::event_key
static int event_key()
Definition: Fl.H:723
Fl_Input_::input_type
int input_type() const
Definition: Fl_Input_.H:424
b
long b
Definition: jpegint.h:397
Fl::OPTION_ARROW_FOCUS
Definition: Fl.H:197
Fl_Input::kf_copy_cut
int kf_copy_cut()
Definition: Fl_Input.cxx:295
Fl_Input_::linesPerPage
int linesPerPage()
Definition: Fl_Input_.cxx:1315
Fl::dnd
static int dnd()
Definition: fl_dnd_win32.cxx:535
Fl_Float_Input.H
Fl_Input::kf_move_word_right
int kf_move_word_right()
Definition: Fl_Input.cxx:231
Fl::box_dh
static int box_dh(Fl_Boxtype)
Definition: fl_boxtype.cxx:397
Fl_Input_::line_end
int line_end(int i) const
Definition: Fl_Input_.cxx:477
FL_Page_Up
#define FL_Page_Up
The page-up key.
Definition: Enumerations.H:484
Fl_Input::kf_undo
int kf_undo()
Definition: Fl_Input.cxx:271
Fl_Input::Fl_Input
Fl_Input(int, int, int, int, const char *=0)
Definition: Fl_Input.cxx:797
FL_Down
#define FL_Down
The down arrow key.
Definition: Enumerations.H:483
Fl_Widget::w
int w() const
Definition: Fl_Widget.H:294
Fl_Input::kf_paste
int kf_paste()
Definition: Fl_Input.cxx:288
Fl::first_window
static Fl_Window * first_window()
Definition: Fl.cxx:751
FL_MULTILINE_INPUT
#define FL_MULTILINE_INPUT
Definition: Fl_Input_.H:33
Fl::box_dw
static int box_dw(Fl_Boxtype)
Definition: fl_boxtype.cxx:391
Fl::dnd_text_ops
static int dnd_text_ops()
Definition: Fl.H:1213
Fl::belowmouse
static Fl_Widget * belowmouse()
Definition: Fl.H:833
Fl_Window.H
Fl_Secret_Input::handle
int handle(int)
Definition: Fl_Input.cxx:841
Fl_Input::kf_move_char_right
int kf_move_char_right()
Definition: Fl_Input.cxx:219
FL_DND_LEAVE
Definition: Enumerations.H:411
Fl_Widget::color
Fl_Color color() const
Definition: Fl_Widget.H:378
FL_End
#define FL_End
The end key.
Definition: Enumerations.H:486
FL_DND_DRAG
Definition: Enumerations.H:407
p
static menustate * p
Definition: Fl_Menu.cxx:606
FL_Left
#define FL_Left
The left arrow key.
Definition: Enumerations.H:480
FL_Right
#define FL_Right
The right arrow key.
Definition: Enumerations.H:482
Fl::box_dy
static int box_dy(Fl_Boxtype)
Definition: fl_boxtype.cxx:385
ctrl
#define ctrl(x)
Definition: Fl_Input.cxx:77
FL_Tab
#define FL_Tab
The tab key.
Definition: Enumerations.H:469
FL_ALT
#define FL_ALT
One of the alt keys is down.
Definition: Enumerations.H:560
Fl_Input_::word_end
int word_end(int i) const
Definition: Fl_Input_.cxx:441
FL_Home
#define FL_Home
The home key.
Definition: Enumerations.H:479
fl_draw.H
utility header to pull drawing functions together
Fl::option
static bool option(Fl_Option opt)
FLTK library options management.
Definition: Fl.cxx:2182
Fl_Input::kf_delete_sol
int kf_delete_sol()
Definition: Fl_Input.cxx:160
Fl_Widget::active_r
int active_r() const
Definition: Fl_Widget.cxx:265
Fl_Input::handle_key
int handle_key()
Definition: Fl_Input.cxx:304
FL_COMMAND
#define FL_COMMAND
An alias for FL_CTRL on WIN32 and X11, or FL_META on MacOS X.
Definition: Enumerations.H:580
FL_FOCUS
Definition: Enumerations.H:283
fl_beep
void fl_beep(int type=FL_BEEP_DEFAULT)
Definition: fl_ask.cxx:283
Fl_Input_::handle_mouse
void handle_mouse(int, int, int, int, int keepmark=0)
Definition: Fl_Input_.cxx:542
Fl_Output::Fl_Output
Fl_Output(int X, int Y, int W, int H, const char *l=0)
Definition: Fl_Input.cxx:823
Fl_Multiline_Input::Fl_Multiline_Input
Fl_Multiline_Input(int X, int Y, int W, int H, const char *l=0)
Definition: Fl_Input.cxx:817
Fl_Input_::undo
int undo()
Definition: Fl_Input_.cxx:927
FL_FLOAT_INPUT
#define FL_FLOAT_INPUT
Definition: Fl_Input_.H:30
Fl_Input
Definition: Fl_Input.H:222
Fl_Multiline_Output.H
Fl_Input::kf_select_all
int kf_select_all()
Definition: Fl_Input.cxx:265
Fl_Input_::position
int position() const
Definition: Fl_Input_.H:283
FL_PUSH
Definition: Enumerations.H:236
Fl_Input_::handletext
int handletext(int e, int, int, int, int)
Definition: Fl_Input_.cxx:999
Fl_Widget::damage
uchar damage() const
Definition: Fl_Widget.H:917
Fl::event_length
static int event_length()
Definition: Fl.H:799
Fl_Widget
Definition: Fl_Widget.H:101
NORMAL_INPUT_MOVE
#define NORMAL_INPUT_MOVE
Definition: Fl_Input.cxx:75
Fl_Input::kf_move_char_left
int kf_move_char_left()
Definition: Fl_Input.cxx:211
Fl::focus
static Fl_Widget * focus()
Definition: Fl.H:840
Fl_Input_::up_down_position
int up_down_position(int, int keepmark=0)
Definition: Fl_Input_.cxx:692
Fl_Widget::box
Fl_Boxtype box() const
Definition: Fl_Widget.H:363
Fl_Multiline_Input.H
Fl_Input_::word_start
int word_start(int i) const
Definition: Fl_Input_.cxx:461
Fl_Widget::h
int h() const
Definition: Fl_Widget.H:299
FL_KEYBOARD
Definition: Enumerations.H:315
Fl_Int_Input.H
Fl_Input::kf_lines_down
int kf_lines_down(int repeat_num)
Definition: Fl_Input.cxx:112
Fl_Input::kf_page_up
int kf_page_up()
Definition: Fl_Input.cxx:128
Fl::event_clicks
static int event_clicks()
Definition: Fl.H:645
Fl_Widget::handle
virtual int handle(int event)
Definition: Fl_Widget.cxx:112
Fl_Widget::MAC_USE_ACCENTS_MENU
On the Mac OS platform, pressing and holding a key on the keyboard opens an accented-character menu w...
Definition: Fl_Widget.H:175
Fl_Input_::line_start
int line_start(int i) const
Definition: Fl_Input_.cxx:508
Fl_Window::cursor
void cursor(Fl_Cursor)
Definition: fl_cursor.cxx:111
Fl_Input::kf_copy
int kf_copy()
Definition: Fl_Input.cxx:283
FL_MULTILINE_OUTPUT
#define FL_MULTILINE_OUTPUT
Definition: Fl_Input_.H:38
FL_CURSOR_NONE
Definition: Enumerations.H:1072
Fl_Output.H
Fl_Widget::type
uchar type() const
Definition: Fl_Widget.H:274
malloc
voidp malloc()
Fl_Input_::drawtext
void drawtext(int, int, int, int)
Definition: Fl_Input_.cxx:217
Fl_Secret_Input.H
Y
static int Y
Definition: Fl_Tooltip.cxx:76
Fl_Input_::mark
int mark() const
Definition: Fl_Input_.H:287
flstring.h
Fl_Input::handle
int handle(int)
Definition: Fl_Input.cxx:589
Fl_Input::kf_bottom
int kf_bottom()
Definition: Fl_Input.cxx:259
Fl::compose_state
static int compose_state
Definition: Fl.H:166
Fl_Input::shift_position
int shift_position(int p)
Definition: Fl_Input.cxx:55
FL_Insert
#define FL_Insert
The insert key.
Definition: Enumerations.H:488
Fl_Input::kf_delete_eol
int kf_delete_eol()
Definition: Fl_Input.cxx:168
Fl_Input_
Definition: Fl_Input_.H:94
Fl_Input::kf_delete_char_right
int kf_delete_char_right()
Definition: Fl_Input.cxx:175
Fl_Input::kf_redo
int kf_redo()
Definition: Fl_Input.cxx:277
Fl_Output
Definition: Fl_Output.H:47
Fl_Input_::maybe_do_callback
void maybe_do_callback()
Definition: Fl_Input_.cxx:987
FL_RELEASE
Definition: Enumerations.H:244
Fl_Widget::take_focus
int take_focus()
Definition: Fl_Widget.cxx:162
Fl_Input_::copy
int copy(int clipboard)
Definition: Fl_Input_.cxx:724
FL_HIDDEN_INPUT
#define FL_HIDDEN_INPUT
Definition: Fl_Input_.H:32
Fl_Input::kf_delete_char_left
int kf_delete_char_left()
Definition: Fl_Input.cxx:181
FL_CTRL
#define FL_CTRL
One of the ctrl keys is down.
Definition: Enumerations.H:559
Fl_Input_::cut
int cut()
Definition: Fl_Input_.H:320
FL_Delete
#define FL_Delete
The delete key.
Definition: Enumerations.H:506
Fl_Input::kf_top
int kf_top()
Definition: Fl_Input.cxx:253
Fl_Input::kf_move_eol
int kf_move_eol()
Definition: Fl_Input.cxx:194
Fl_Widget::clear_flag
void clear_flag(unsigned int c)
Definition: Fl_Widget.H:151
Fl_Input::kf_lines_up
int kf_lines_up(int repeat_num)
Definition: Fl_Input.cxx:94
Fl_Input_::tab_nav
int tab_nav() const
Definition: Fl_Input_.H:490
legal_fp_chars
static const char * legal_fp_chars
Definition: Fl_Input.cxx:88
Fl_Input::draw
void draw()
Definition: Fl_Input.cxx:46
Fl_Input_::replace
int replace(int b, int e, const char *text, int ilen=0)
Definition: Fl_Input_.cxx:803
Fl_Input_::readonly
int readonly() const
Definition: Fl_Input_.H:433
Fl_Multiline_Output::Fl_Multiline_Output
Fl_Multiline_Output(int X, int Y, int W, int H, const char *l=0)
Definition: Fl_Input.cxx:829
Fl_Input::kf_insert_toggle
int kf_insert_toggle()
Definition: Fl_Input.cxx:138
FL_INT_INPUT
#define FL_INT_INPUT
Definition: Fl_Input_.H:31
FL_WHEN_ENTER_KEY
Do the callback when the user presses the ENTER key and the value changes.
Definition: Enumerations.H:445