2 // "$Id: Fl_Input.cxx 8726 2011-05-23 18:32:47Z AlbrechtS $"
4 // Input widget for the Fast Light Tool Kit (FLTK).
6 // Copyright 1998-2011 by Bill Spitzak and others.
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 // This is the "user interface", it decodes user actions into what to
29 // do to the text. See also Fl_Input_.cxx, where the text is actually
30 // manipulated (and some ui, in particular the mouse, is done...).
31 // In theory you can replace this code with another subclass to change
37 #include <FL/Fl_Window.H>
38 #include <FL/Fl_Input.H>
39 #include <FL/fl_draw.H>
40 #include <FL/fl_ask.H>
43 #if defined(FL_DLL) // really needed for c'tors for MS VC++ only
44 #include <FL/Fl_Float_Input.H>
45 #include <FL/Fl_Int_Input.H>
46 #include <FL/Fl_Multiline_Input.H>
47 #include <FL/Fl_Output.H>
48 #include <FL/Fl_Multiline_Output.H>
49 #include <FL/Fl_Secret_Input.H>
57 void Fl_Input::draw() {
58 if (input_type() == FL_HIDDEN_INPUT
) return;
60 if (damage() & FL_DAMAGE_ALL
) draw_box(b
, color());
61 Fl_Input_::drawtext(x()+Fl::box_dx(b
), y()+Fl::box_dy(b
),
62 w()-Fl::box_dw(b
), h()-Fl::box_dh(b
));
65 // kludge so shift causes selection to extend:
66 int Fl_Input::shift_position(int p
) {
67 return position(p
, Fl::event_state(FL_SHIFT
) ? mark() : p
);
70 int Fl_Input::shift_up_down_position(int p
) {
71 return up_down_position(p
, Fl::event_state(FL_SHIFT
));
74 // Old text from FLTK 1.1 for reference:
75 // If you define NORMAL_INPUT_MOVE as zero you will get the peculiar fltk
76 // behavior where moving off the end of an input field will move the
77 // cursor into the next field:
78 // define it as 1 to prevent cursor movement from going to next field:
80 // Note: this has been replaced by Fl::option(Fl::OPTION_ARROW_FOCUS)
81 // in FLTK 1.3. This option has "inverted" values:
82 // 1 = Arrow keys move focus (previously 0)
83 // 0 = Arrow keys don't move focus (previously 1)
84 // Hence we define ...
86 #define NORMAL_INPUT_MOVE (Fl::option(Fl::OPTION_ARROW_FOCUS) ? 0 : 1)
88 #define ctrl(x) ((x)^0x40)
90 // List of characters that are legal in a floating point input field.
91 // This text string is created at run-time to take the current locale
92 // into account (for example, continental Europe uses a comma instead
93 // of a decimal point). For back compatibility reasons, we always
94 // allow the decimal point.
95 #ifdef HAVE_LOCALECONV
96 static const char *standard_fp_chars
= ".eE+-";
97 static const char *legal_fp_chars
= 0L;
99 static const char *legal_fp_chars
= ".eE+-";
102 // Move cursor up specified #lines
103 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
105 int Fl_Input::kf_lines_up(int repeat_num
) {
107 if (!line_start(i
)) {
108 //UNNEEDED if (input_type()==FL_MULTILINE_INPUT && !Fl::option(Fl::OPTION_ARROW_FOCUS)) return 1;
109 return NORMAL_INPUT_MOVE
;
111 while(repeat_num
--) {
116 shift_up_down_position(line_start(i
));
120 // Move cursor down specified #lines
121 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
123 int Fl_Input::kf_lines_down(int repeat_num
) {
125 if (line_end(i
) >= size()) {
126 //UNNEEDED if (input_type()==FL_MULTILINE_INPUT && !Fl::option(Fl::OPTION_ARROW_FOCUS)) return 1;
127 return NORMAL_INPUT_MOVE
;
129 while (repeat_num
--) {
131 if (i
>= size()) break;
134 shift_up_down_position(i
);
139 int Fl_Input::kf_page_up() {
140 return kf_lines_up(linesPerPage());
144 int Fl_Input::kf_page_down() {
145 return kf_lines_down(linesPerPage());
148 // Toggle insert mode
149 int Fl_Input::kf_insert_toggle() {
150 if (readonly()) { fl_beep(); return 1; }
151 return 1; // \todo: needs insert mode
155 int Fl_Input::kf_delete_word_right() {
156 if (readonly()) { fl_beep(); return 1; }
157 if (mark() != position()) return cut();
158 cut(position(), word_end(position()));
163 int Fl_Input::kf_delete_word_left() {
164 if (readonly()) { fl_beep(); return 1; }
165 if (mark() != position()) return cut();
166 cut(word_start(position()), position());
170 // Delete to start of line
171 int Fl_Input::kf_delete_sol() {
172 if (readonly()) { fl_beep(); return 1; }
173 if (mark() != position()) return cut();
174 cut(line_start(position()), position());
178 // Delete to end of line
179 int Fl_Input::kf_delete_eol() {
180 if (readonly()) { fl_beep(); return 1; }
181 if (mark() != position()) return cut();
182 cut(position(), line_end(position()));
186 int Fl_Input::kf_delete_char_right() {
187 if (readonly()) { fl_beep(); return 1; }
188 if (mark() != position()) return cut();
192 int Fl_Input::kf_delete_char_left() {
193 if (readonly()) { fl_beep(); return 1; }
194 if (mark() != position()) cut();
199 // Move cursor to start of line
200 int Fl_Input::kf_move_sol() {
201 return shift_position(line_start(position())) + NORMAL_INPUT_MOVE
;
204 // Move cursor to end of line
205 int Fl_Input::kf_move_eol() {
206 return shift_position(line_end(position())) + NORMAL_INPUT_MOVE
;
209 // Clear to end of line
210 int Fl_Input::kf_clear_eol() {
211 if (readonly()) { fl_beep(); return 1; }
212 if (position()>=size()) return 0;
213 int i
= line_end(position());
214 if (i
== position() && i
< size()) i
++;
219 // Move cursor one character to the left
220 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
222 int Fl_Input::kf_move_char_left() {
223 int i
= shift_position(position()-1) + NORMAL_INPUT_MOVE
;
224 return Fl::option(Fl::OPTION_ARROW_FOCUS
) ? i
: 1;
227 // Move cursor one character to the right
228 // If OPTION_ARROW_FOCUS is disabled, return 1 to prevent focus navigation.
230 int Fl_Input::kf_move_char_right() {
231 int i
= shift_position(position()+1) + NORMAL_INPUT_MOVE
;
232 return Fl::option(Fl::OPTION_ARROW_FOCUS
) ? i
: 1;
235 // Move cursor word-left
236 int Fl_Input::kf_move_word_left() {
237 shift_position(word_start(position()));
241 // Move cursor word-right
242 int Fl_Input::kf_move_word_right() {
243 shift_position(word_end(position()));
247 // Move cursor up one line and to the start of line (paragraph up)
248 int Fl_Input::kf_move_up_and_sol() {
249 if (line_start(position())==position() && position()>0)
250 return shift_position(line_start(position()-1)) + NORMAL_INPUT_MOVE
;
252 return shift_position(line_start(position())) + NORMAL_INPUT_MOVE
;
255 // Move cursor down one line and to the end of line (paragraph down)
256 int Fl_Input::kf_move_down_and_eol() {
257 if (line_end(position())==position() && position()<size())
258 return shift_position(line_end(position()+1)) + NORMAL_INPUT_MOVE
;
260 return shift_position(line_end(position())) + NORMAL_INPUT_MOVE
;
263 // Move to top of document
264 int Fl_Input::kf_top() {
269 // Move to bottom of document
270 int Fl_Input::kf_bottom() {
271 shift_position(size());
275 // Select all text in the widget
276 int Fl_Input::kf_select_all() {
282 int Fl_Input::kf_undo() {
283 if (readonly()) { fl_beep(); return 1; }
287 // Redo. (currently unimplemented.. toggles undo() instead)
288 int Fl_Input::kf_redo() {
289 if (readonly()) { fl_beep(); return 1; }
290 return kf_undo(); // currently we don't support multilevel undo
293 // Do a copy operation
294 int Fl_Input::kf_copy() {
298 // Do a paste operation
299 int Fl_Input::kf_paste() {
300 if (readonly()) { fl_beep(); return 1; }
305 // Do a cut with copy
306 int Fl_Input::kf_copy_cut() {
307 if (readonly()) { fl_beep(); return 1; }
312 // Handle a keystroke.
313 // Returns 1 if handled by us, 0 if not.
315 int Fl_Input::handle_key() {
317 char ascii
= Fl::event_text()[0];
320 if (Fl::compose(del
)) {
322 // Insert characters into numeric fields after checking for legality:
323 if (input_type() == FL_FLOAT_INPUT
|| input_type() == FL_INT_INPUT
) {
324 Fl::compose_reset(); // ignore any foreign letters...
326 // initialize the list of legal characters inside a floating point number
327 #ifdef HAVE_LOCALECONV
328 if (!legal_fp_chars
) {
329 int len
= strlen(standard_fp_chars
);
330 struct lconv
*lc
= localeconv();
332 if (lc
->decimal_point
) len
+= strlen(lc
->decimal_point
);
333 if (lc
->mon_decimal_point
) len
+= strlen(lc
->mon_decimal_point
);
334 if (lc
->positive_sign
) len
+= strlen(lc
->positive_sign
);
335 if (lc
->negative_sign
) len
+= strlen(lc
->negative_sign
);
337 // the following line is not a true memory leak because the array is only
338 // allocated once if required, and automatically freed when the program quits
339 char *chars
= (char*)malloc(len
+1);
340 legal_fp_chars
= chars
;
341 strcpy(chars
, standard_fp_chars
);
343 if (lc
->decimal_point
) strcat(chars
, lc
->decimal_point
);
344 if (lc
->mon_decimal_point
) strcat(chars
, lc
->mon_decimal_point
);
345 if (lc
->positive_sign
) strcat(chars
, lc
->positive_sign
);
346 if (lc
->negative_sign
) strcat(chars
, lc
->negative_sign
);
349 #endif // HAVE_LOCALECONV
351 // find the insert position
352 int ip
= position()<mark() ? position() : mark();
353 // This is complex to allow "0xff12" hex to be typed:
354 if ( (!ip
&& (ascii
== '+' || ascii
== '-'))
355 || (ascii
>= '0' && ascii
<= '9')
356 || (ip
==1 && index(0)=='0' && (ascii
=='x' || ascii
== 'X'))
357 || (ip
>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X')
358 && ((ascii
>='A'&& ascii
<='F') || (ascii
>='a'&& ascii
<='f')))
359 || (input_type()==FL_FLOAT_INPUT
&& ascii
&& strchr(legal_fp_chars
, ascii
)))
361 if (readonly()) fl_beep();
362 else replace(position(), mark(), &ascii
, 1);
367 if (del
|| Fl::event_length()) {
368 if (readonly()) fl_beep();
369 else replace(position(), del
? position()-del
: mark(),
370 Fl::event_text(), Fl::event_length());
375 unsigned int mods
= Fl::event_state() & (FL_META
|FL_CTRL
|FL_ALT
);
376 unsigned int shift
= Fl::event_state() & FL_SHIFT
;
377 unsigned int multiline
= (input_type() == FL_MULTILINE_INPUT
) ? 1 : 0;
379 // The following lists apps that support these keypresses.
380 // Prefixes: '!' indicates NOT supported, '?' indicates un-verified.
382 // HIG=Human Interface Guide,
383 // TE=TextEdit.app, SA=Safari.app, WOX=MS Word/OSX -- OSX 10.4.x
384 // NP=Notepad, WP=WordPad, WOW=MS Word/Windows -- WinXP
385 // GE=gedit, KE=kedit -- Ubuntu8.04
386 // OF=old FLTK behavior (<=1.1.10)
388 // Example: (NP,WP,!WO) means supported in notepad + wordpad, but NOT word.
390 switch (Fl::event_key()) {
393 // Note: Mac has no "Insert" key; it's the "Help" key.
394 // This keypress is apparently not possible on macs.
396 if (mods
==0 && shift
) return kf_paste(); // Shift-Insert (WP,NP,WOW,GE,KE,OF)
397 if (mods
==0) return kf_insert_toggle(); // Insert (Standard)
398 if (mods
==FL_CTRL
) return kf_copy(); // Ctrl-Insert (WP,NP,WOW,GE,KE,OF)
399 return 0; // ignore other combos, pass to parent
403 if (mods
==0) return kf_delete_char_right(); // Delete (OSX-HIG,TE,SA,WOX)
404 if (mods
==FL_CTRL
) return kf_delete_char_right(); // Ctrl-Delete (??? TE,!SA,!WOX)
405 if (mods
==FL_ALT
) return kf_delete_word_right(); // Alt-Delete (OSX-HIG,TE,SA)
406 return 0; // ignore other combos, pass to parent
408 int selected
= (position() != mark()) ? 1 : 0;
409 if (mods
==0 && shift
&& selected
)
410 return kf_copy_cut(); // Shift-Delete with selection (WP,NP,WOW,GE,KE,OF)
411 if (mods
==0 && shift
&& !selected
)
412 return kf_delete_char_right(); // Shift-Delete no selection (WP,NP,WOW,GE,KE,!OF)
413 if (mods
==0) return kf_delete_char_right(); // Delete (Standard)
414 if (mods
==FL_CTRL
) return kf_delete_word_right(); // Ctrl-Delete (WP,!NP,WOW,GE,KE,!OF)
415 return 0; // ignore other combos, pass to parent
421 if (mods
==0) return kf_move_char_left(); // Left (OSX-HIG)
422 if (mods
==FL_ALT
) return kf_move_word_left(); // Alt-Left (OSX-HIG)
423 if (mods
==FL_META
) return kf_move_sol(); // Meta-Left (OSX-HIG)
424 if (mods
==FL_CTRL
) return kf_move_sol(); // Ctrl-Left (TE/SA)
425 return 0; // ignore other combos, pass to parent
427 if (mods
==0) return kf_move_char_left(); // Left (WP,NP,WOW,GE,KE,OF)
428 if (mods
==FL_CTRL
) return kf_move_word_left(); // Ctrl-Left (WP,NP,WOW,GE,KE,!OF)
429 if (mods
==FL_META
) return kf_move_char_left(); // Meta-Left (WP,NP,?WOW,GE,KE)
430 return 0; // ignore other combos, pass to parent
435 if (mods
==0) return kf_move_char_right(); // Right (OSX-HIG)
436 if (mods
==FL_ALT
) return kf_move_word_right(); // Alt-Right (OSX-HIG)
437 if (mods
==FL_META
) return kf_move_eol(); // Meta-Right (OSX-HIG)
438 if (mods
==FL_CTRL
) return kf_move_eol(); // Ctrl-Right (TE/SA)
439 return 0; // ignore other combos, pass to parent
441 if (mods
==0) return kf_move_char_right(); // Right (WP,NP,WOW,GE,KE,OF)
442 if (mods
==FL_CTRL
) return kf_move_word_right(); // Ctrl-Right (WP,NP,WOW,GE,KE,!OF)
443 if (mods
==FL_META
) return kf_move_char_right(); // Meta-Right (WP,NP,?WOW,GE,KE,!OF)
444 return 0; // ignore other combos, pass to parent
449 if (mods
==0) return kf_lines_up(1); // Up (OSX-HIG)
450 if (mods
==FL_CTRL
) return kf_page_up(); // Ctrl-Up (TE !HIG)
451 if (mods
==FL_ALT
) return kf_move_up_and_sol(); // Alt-Up (OSX-HIG)
452 if (mods
==FL_META
) return kf_top(); // Meta-Up (OSX-HIG)
453 return 0; // ignore other combos, pass to parent
455 if (mods
==0) return kf_lines_up(1); // Up (WP,NP,WOW,GE,KE,OF)
456 if (mods
==FL_CTRL
) return kf_move_up_and_sol(); // Ctrl-Up (WP,!NP,WOW,GE,!KE,OF)
457 return 0; // ignore other combos, pass to parent
462 if (mods
==0) return kf_lines_down(1); // Dn (OSX-HIG)
463 if (mods
==FL_CTRL
) return kf_page_down(); // Ctrl-Dn (TE !HIG)
464 if (mods
==FL_ALT
) return kf_move_down_and_eol(); // Alt-Dn (OSX-HIG)
465 if (mods
==FL_META
) return kf_bottom(); // Meta-Dn (OSX-HIG)
466 return 0; // ignore other combos, pass to parent
468 if (mods
==0) return kf_lines_down(1); // Dn (WP,NP,WOW,GE,KE,OF)
469 if (mods
==FL_CTRL
) return kf_move_down_and_eol(); // Ctrl-Down (WP,!NP,WOW,GE,!KE,OF)
470 return 0; // ignore other combos, pass to parent
474 // Fl_Input has no scroll control, so instead we move the cursor by one page
475 // OSX-HIG recommends Alt increase one semantic unit, Meta next higher..
477 if (mods
==0) return kf_page_up(); // PgUp (OSX-HIG)
478 if (mods
==FL_ALT
) return kf_page_up(); // Alt-PageUp (OSX-HIG)
479 if (mods
==FL_META
) return kf_top(); // Meta-PageUp (OSX-HIG,!TE)
480 return 0; // ignore other combos, pass to parent
482 if (mods
==0) return kf_page_up(); // PageUp (WP,NP,WOW,GE,KE)
483 if (mods
==FL_CTRL
) return kf_page_up(); // Ctrl-PageUp (!WP,!NP,!WOW,!GE,KE,OF)
484 if (mods
==FL_ALT
) return kf_page_up(); // Alt-PageUp (!WP,!NP,!WOW,!GE,KE,OF)
485 return 0; // ignore other combos, pass to parent
490 // Fl_Input has no scroll control, so instead we move the cursor by one page
491 // OSX-HIG recommends Alt increase one semantic unit, Meta next higher..
492 if (mods
==0) return kf_page_down(); // PgDn (OSX-HIG)
493 if (mods
==FL_ALT
) return kf_page_down(); // Alt-PageDn (OSX-HIG)
494 if (mods
==FL_META
) return kf_bottom(); // Meta-PageDn (OSX-HIG,!TE)
495 return 0; // ignore other combos, pass to parent
497 if (mods
==0) return kf_page_down(); // PageDn (WP,NP,WOW,GE,KE)
498 if (mods
==FL_CTRL
) return kf_page_down(); // Ctrl-PageDn (!WP,!NP,!WOW,!GE,KE,OF)
499 if (mods
==FL_ALT
) return kf_page_down(); // Alt-PageDn (!WP,!NP,!WOW,!GE,KE,OF)
500 return 0; // ignore other combos, pass to parent
505 if (mods
==0) return kf_top(); // Home (OSX-HIG)
506 if (mods
==FL_ALT
) return kf_top(); // Alt-Home (???)
507 return 0; // ignore other combos, pass to parent
509 if (mods
==0) return kf_move_sol(); // Home (WP,NP,WOW,GE,KE,OF)
510 if (mods
==FL_CTRL
) return kf_top(); // Ctrl-Home (WP,NP,WOW,GE,KE,OF)
511 return 0; // ignore other combos, pass to parent
516 if (mods
==0) return kf_bottom(); // End (OSX-HIG)
517 if (mods
==FL_ALT
) return kf_bottom(); // Alt-End (???)
518 return 0; // ignore other combos, pass to parent
520 if (mods
==0) return kf_move_eol(); // End (WP,NP,WOW,GE,KE,OF)
521 if (mods
==FL_CTRL
) return kf_bottom(); // Ctrl-End (WP,NP,WOW,GE,KE,OF)
522 return 0; // ignore other combos, pass to parent
527 if (mods
==0) return kf_delete_char_left(); // Backspace (OSX-HIG)
528 if (mods
==FL_CTRL
) return kf_delete_char_left(); // Ctrl-Backspace (TE/SA)
529 if (mods
==FL_ALT
) return kf_delete_word_left(); // Alt-Backspace (OSX-HIG)
530 if (mods
==FL_META
) return kf_delete_sol(); // Meta-Backspace (OSX-HIG,!TE)
531 return 0; // ignore other combos, pass to parent
533 if (mods
==0) return kf_delete_char_left(); // Backspace (WP,NP,WOW,GE,KE,OF)
534 if (mods
==FL_CTRL
) return kf_delete_word_left(); // Ctrl-Backspace (WP,!NP,WOW,GE,KE,!OF)
535 return 0; // ignore other combos, pass to parent
540 if (when() & FL_WHEN_ENTER_KEY
) {
544 } else if (multiline
&& !readonly()) {
545 return replace(position(), mark(), "\n", 1);
546 } return 0; // reserved for shortcuts
549 // Handle special case for multiline input with 'old tab behavior';
550 // tab handled as a normal insertable character.
552 if (mods
==0 && !shift
// Tab?
553 && !tab_nav() // old tab behavior enabled?
554 && multiline
) { // multiline input?
555 break; // insert tab character
557 if (mods
==0) return 0; // Tab, Shift-Tab? nav focus (Standard/OSX-HIG)
558 return 0; // ignore other combos, pass to parent
561 if (mods
==FL_COMMAND
) return kf_select_all(); // Ctrl-A, Mac:Meta-A (Standard/OSX-HIG)
562 break; // handle other combos elsewhere
564 if (mods
==FL_COMMAND
) return kf_copy(); // Ctrl-C, Mac:Meta-C (Standard/OSX-HIG)
565 break; // handle other combos elsewhere
567 if (mods
==FL_COMMAND
) return kf_paste(); // Ctrl-V, Mac:Meta-V (Standard/OSX-HIG)
568 break; // handle other combos elsewhere
570 if (mods
==FL_COMMAND
) return kf_copy_cut(); // Ctrl-X, Mac:Meta-X (Standard/OSX-HIG)
573 if (mods
==FL_COMMAND
&& !shift
) return kf_undo(); // Ctrl-Z, Mac:Meta-Z (Standard/OSX-HIG)
574 if (mods
==FL_COMMAND
&& shift
) return kf_redo(); // Shift-Ctrl-Z, Mac:Shift-Meta-Z (Standard/OSX-HIG)
575 break; // handle other combos elsewhere
580 return kf_delete_char_left(); // Ctrl-H (!WP,!NP,!WOW,!WOX,TE,SA,GE,KE,OF)
581 case ctrl('I'): // Ctrl-I (literal Tab) (!WP,NP,!WOW,!GE,KE,OF)
582 case ctrl('J'): // Ctrl-J (literal Line Feed/Enter) (Standard)
583 case ctrl('L'): // Ctrl-L (literal Form Feed) (Standard)
584 case ctrl('M'): // Ctrl-M (literal Cr) (Standard)
585 if (readonly()) { fl_beep(); return 1; }
586 // insert a few selected control characters literally:
587 if (input_type() != FL_FLOAT_INPUT
&& input_type() != FL_INT_INPUT
)
588 return replace(position(), mark(), &ascii
, 1);
595 int Fl_Input::handle(int event
) {
596 static int dnd_save_position
, dnd_save_mark
, drag_start
= -1, newpos
;
597 static Fl_Widget
*dnd_save_focus
;
600 switch (Fl::event_key()) {
611 up_down_position(line_start(size()));
617 position(position(),mark());// turns off the saved up/down arrow position
623 // Handle special case for multiline input with 'old tab behavior'
624 // where tab is entered as a character: make sure user attempt to 'tab over'
625 // widget doesn't destroy the field, replacing it with a tab character.
627 if (Fl::event_key() == FL_Tab
// Tab key?
628 && !Fl::event_state(FL_SHIFT
) // no shift?
629 && !tab_nav() // with tab navigation disabled?
630 && input_type() == FL_MULTILINE_INPUT
// with a multiline input?
631 && (mark()==0 && position()==size())) { // while entire field selected?
632 // Set cursor to the end of the selection...
633 if (mark() > position())
636 position(position());
639 if (active_r() && window() && this == Fl::belowmouse())
640 window()->cursor(FL_CURSOR_NONE
);
646 if (Fl::dnd_text_ops()) {
647 int oldpos
= position(), oldmark
= mark();
648 Fl_Boxtype b
= box();
649 Fl_Input_::handle_mouse(x()+Fl::box_dx(b
), y()+Fl::box_dy(b
),
650 w()-Fl::box_dw(b
), h()-Fl::box_dh(b
), 0);
652 position( oldpos
, oldmark
);
653 if (Fl::focus()==this && !Fl::event_state(FL_SHIFT
) && input_type()!=FL_SECRET_INPUT
&&
654 ( (newpos
>= mark() && newpos
< position()) ||
655 (newpos
>= position() && newpos
< mark()) ) ) {
656 // user clicked in the selection, may be trying to drag
663 if (Fl::focus() != this) {
670 if (Fl::dnd_text_ops()) {
671 if (drag_start
>= 0) {
672 if (Fl::event_is_click()) return 1; // debounce the mouse
673 // save the position because sometimes we don't get DND_ENTER:
674 dnd_save_position
= position();
675 dnd_save_mark
= mark();
684 if (Fl::event_button() == 2) {
685 Fl::event_is_click(0); // stop double click from picking a word
687 } else if (!Fl::event_is_click()) {
688 // copy drag-selected text to the clipboard.
690 } else if (Fl::event_is_click() && drag_start
>= 0) {
691 // user clicked in the field and wants to reset the cursor position...
692 position(drag_start
, drag_start
);
694 } else if (Fl::event_clicks()) {
695 // user double or triple clicked to select word or whole text
699 // For output widgets, do the callback so the app knows the user
700 // did something with the mouse...
701 if (readonly()) do_callback();
706 Fl::belowmouse(this); // send the leave events first
707 dnd_save_position
= position();
708 dnd_save_mark
= mark();
709 dnd_save_focus
= Fl::focus();
710 if (dnd_save_focus
!= this) {
716 //int p = mouse_position(X, Y, W, H);
718 if (Fl::focus()==this && (p
>=dnd_save_position
&& p
<=dnd_save_mark
||
719 p
>=dnd_save_mark
&& p
<=dnd_save_position
)) {
720 position(dnd_save_position
, dnd_save_mark
);
725 Fl_Boxtype b
= box();
726 Fl_Input_::handle_mouse(x()+Fl::box_dx(b
), y()+Fl::box_dy(b
),
727 w()-Fl::box_dw(b
), h()-Fl::box_dh(b
), 0);
732 position(dnd_save_position
, dnd_save_mark
);
736 if (dnd_save_focus
!= this) {
737 Fl::focus(dnd_save_focus
);
740 #if !(defined(__APPLE__) || defined(WIN32))
741 Fl::first_window()->cursor(FL_CURSOR_MOVE
);
749 /* TODO: this will scroll the area, but stop if the cursor would become invisible.
750 That clipping happens in drawtext(). Do we change the clipping or should
751 we move the cursor (ouch)?
754 yscroll( yscroll() - Fl::e_dy*15 );
755 } else if (Fl::e_dy < 0) {
756 yscroll( yscroll() - Fl::e_dy*15 );
761 Fl_Boxtype b
= box();
762 return Fl_Input_::handletext(event
,
763 x()+Fl::box_dx(b
), y()+Fl::box_dy(b
),
764 w()-Fl::box_dw(b
), h()-Fl::box_dh(b
));
768 Creates a new Fl_Input widget using the given position, size,
769 and label string. The default boxtype is FL_DOWN_BOX.
771 Fl_Input::Fl_Input(int X
, int Y
, int W
, int H
, const char *l
)
772 : Fl_Input_(X
, Y
, W
, H
, l
) {
776 The following constructors must not be in the header file(s) if we
777 build a shared object (DLL). Instead they are defined here to force
778 the constructor (and default destructor as well) to be defined in
779 the DLL and exported (STR #2632).
781 Note: if you change any of them, do the same changes in the specific
782 header file as well. This redundant definition was chosen to enable
783 inline constructors in the header files (for static linking) as well
784 as those here for dynamic linking (Windows DLL).
788 Fl_Float_Input::Fl_Float_Input(int X
,int Y
,int W
,int H
,const char *l
)
789 : Fl_Input(X
,Y
,W
,H
,l
) {
790 type(FL_FLOAT_INPUT
);
793 Fl_Int_Input::Fl_Int_Input(int X
,int Y
,int W
,int H
,const char *l
)
794 : Fl_Input(X
,Y
,W
,H
,l
) {
798 Fl_Multiline_Input::Fl_Multiline_Input(int X
,int Y
,int W
,int H
,const char *l
)
799 : Fl_Input(X
,Y
,W
,H
,l
) {
800 type(FL_MULTILINE_INPUT
);
803 Fl_Output::Fl_Output(int X
,int Y
,int W
,int H
, const char *l
)
804 : Fl_Input(X
, Y
, W
, H
, l
) {
805 type(FL_NORMAL_OUTPUT
);
808 Fl_Multiline_Output::Fl_Multiline_Output(int X
,int Y
,int W
,int H
,const char *l
)
809 : Fl_Output(X
,Y
,W
,H
,l
) {
810 type(FL_MULTILINE_OUTPUT
);
813 Fl_Secret_Input::Fl_Secret_Input(int X
,int Y
,int W
,int H
,const char *l
)
814 : Fl_Input(X
,Y
,W
,H
,l
) {
815 type(FL_SECRET_INPUT
);
821 // End of "$Id: Fl_Input.cxx 8726 2011-05-23 18:32:47Z AlbrechtS $".