2
// "$Id: Fl_Input_.H 8068 2010-12-20 07:48:59Z greg.ercolano $"
4
// Input base class header file for the Fast Light Tool Kit (FLTK).
6
// Copyright 1998-2010 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
35
#include "Fl_Widget.H"
38
#define FL_NORMAL_INPUT 0
39
#define FL_FLOAT_INPUT 1
40
#define FL_INT_INPUT 2
41
#define FL_HIDDEN_INPUT 3
42
#define FL_MULTILINE_INPUT 4
43
#define FL_SECRET_INPUT 5
44
#define FL_INPUT_TYPE 7
45
#define FL_INPUT_READONLY 8
46
#define FL_NORMAL_OUTPUT (FL_NORMAL_INPUT | FL_INPUT_READONLY)
47
#define FL_MULTILINE_OUTPUT (FL_MULTILINE_INPUT | FL_INPUT_READONLY)
48
#define FL_INPUT_WRAP 16
49
#define FL_MULTILINE_INPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_WRAP)
50
#define FL_MULTILINE_OUTPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_READONLY | FL_INPUT_WRAP)
53
This class provides a low-overhead text input field.
55
This is a virtual base class below Fl_Input. It has all
56
the same interfaces, but lacks the handle() and
57
draw() method. You may want to subclass it if you are
58
one of those people who likes to change how the editing keys
59
work. It may also be useful for adding scrollbars
62
This can act like any of the subclasses of Fl_Input, by
63
setting type() to one of the following values:
66
#define FL_NORMAL_INPUT 0
67
#define FL_FLOAT_INPUT 1
68
#define FL_INT_INPUT 2
69
#define FL_MULTILINE_INPUT 4
70
#define FL_SECRET_INPUT 5
71
#define FL_INPUT_TYPE 7
72
#define FL_INPUT_READONLY 8
73
#define FL_NORMAL_OUTPUT (FL_NORMAL_INPUT | FL_INPUT_READONLY)
74
#define FL_MULTILINE_OUTPUT (FL_MULTILINE_INPUT | FL_INPUT_READONLY)
75
#define FL_INPUT_WRAP 16
76
#define FL_MULTILINE_INPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_WRAP)
77
#define FL_MULTILINE_OUTPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_READONLY | FL_INPUT_WRAP)
80
All variables that represent an index into a text buffer are byte-oriented,
81
not character oriented. Since UTF-8 characters can be up to six bytes long,
82
simply incrementing such an index will not reliably advance to the next character
85
Indices and pointers into the text buffer should always point at a 7 bit ASCII
86
character or the beginning of a UTF-8 character sequence. Behavior for false
87
UTF-8 sequences and pointers into the middle of a sequence are undefined.
89
\see Fl_Text_Display, Fl_Text_Editor for more powerful text handling widgets
92
When porting this widget from ASCII to UTF-8, previously legal pointers into
93
the text of this widget can become illegal by pointing into the middle of
94
a UTF-8 sequence. This is not a big problem for Fl_Input_ because all code
95
in this module is quite tolerant. It could be problematic though when deriving
96
from this class because no feedback for illegal pointers is given. Additionally,
97
a careless "copy" call can put partial UTF-8 sequences into the clipboard.
99
None of these issues should be disastrous. Nevertheless, we should
100
discuss how FLTK should handle false UTF-8 sequences and pointers.
102
class FL_EXPORT Fl_Input_ : public Fl_Widget {
104
/** \internal Storage for the text field. */
107
/** \internal Buffer memory for expanded text. \see expand() */
110
/** \internal Size of text in bytes in the \p value_ field. */
113
/** \internal \todo Please document me! */
116
/** \internal Position of the cursor in the document. */
119
/** \internal Position of the other end of the selected text. If \p position_ equals
120
\p mark_, no text is selected */
123
/** \internal Behavior of Tab key in multiline input widget.
124
If enabled (default) Tab causes focus nav, otherwise Tab is inserted
128
/** \internal Offset to text origin within widget bounds */
129
int xscroll_, yscroll_;
131
/** \internal Minimal update pointer. Display requires redraw from here to the end
135
/** \internal Maximum size of buffer. \todo Is this really needed? */
138
/** \internal Shortcut key that will fetch focus for this widget. */
141
/** \internal This is set if no text but only the cursor needs updating. */
142
uchar erase_cursor_only;
144
/** \internal The font used for the entire text. */
147
/** \internal Height of the font used for the entire text. */
148
Fl_Fontsize textsize_;
150
/** \internal color of the entire text */
153
/** \internal color of the text cursor */
154
Fl_Color cursor_color_;
156
/** \internal Horizontal cursor position in pixels while moving up or down. */
157
static double up_down_pos;
159
/** \internal Flag to remember last cursor move. */
160
static int was_up_down;
162
/* Convert a given text segment into the text that will be rendered on screen. */
163
const char* expand(const char*, char*) const;
165
/* Calculates the width in pixels of part of a text buffer. */
166
double expandpos(const char*, const char*, const char*, int*) const;
168
/* Mark a range of characters for update. */
169
void minimal_update(int, int);
171
/* Mark a range of characters for update. */
172
void minimal_update(int p);
174
/* Copy the value from a possibly static entry into the internal buffer. */
175
void put_in_buffer(int newsize);
177
/* Set the current font and font size. */
178
void setfont() const;
182
/* Find the start of a word. */
183
int word_start(int i) const;
185
/* Find the end of a word. */
186
int word_end(int i) const;
188
/* Find the start of a line. */
189
int line_start(int i) const;
191
/* Find the end of a line. */
192
int line_end(int i) const;
194
/* Draw the text in the passed bounding box. */
195
void drawtext(int, int, int, int);
197
/* Move the cursor to the column given by up_down_pos. */
198
int up_down_position(int, int keepmark=0);
200
/* Handle mouse clicks and mouse moves. */
201
void handle_mouse(int, int, int, int, int keepmark=0);
203
/* Handle all kinds of text field related events. */
204
int handletext(int e, int, int, int, int);
206
/* Check the when() field and do a callback if indicated. */
207
void maybe_do_callback();
209
/** \internal Horizontal offset of text to left edge of widget. */
210
int xscroll() const {return xscroll_;}
212
/** \internal Vertical offset of text to top edge of widget. */
213
int yscroll() const {return yscroll_;}
214
void yscroll(int y) { yscroll_ = y; damage(FL_DAMAGE_EXPOSE);}
216
/* Return the number of lines displayed on a single page. */
221
/* Change the size of the widget. */
222
void resize(int, int, int, int);
225
Fl_Input_(int, int, int, int, const char* = 0);
230
/* Changes the widget text. */
231
int value(const char*);
233
/* Changes the widget text. */
234
int value(const char*, int);
236
/* Changes the widget text. */
237
int static_value(const char*);
239
/* Changes the widget text. */
240
int static_value(const char*, int);
243
Returns the text displayed in the widget.
245
This function returns the current value, which is a pointer
246
to the internal buffer and is valid only until the next event is
249
\return pointer to an internal buffer - do not free() this
250
\see Fl_Input_::value(const char*)
252
const char* value() const {return value_;}
254
/* Returns the character at index \p i. */
255
Fl_Char index(int i) const;
258
Returns the number of bytes in value().
260
This may be greater than <tt>strlen(value())</tt> if there are
261
\c nul characters in the text.
263
\return number of bytes in the text
265
int size() const {return size_;}
267
/** Sets the width and height of this widget.
268
\param [in] W, H new width and height
269
\see Fl_Widget::size(int, int) */
270
void size(int W, int H) { Fl_Widget::size(W, H); }
272
/** Gets the maximum length of the input field.
273
\todo It is not clear if this function is actually required */
274
int maximum_size() const {return maximum_size_;}
276
/** Sets the maximum length of the input field.
277
\todo It is not clear if this function is actually required */
278
void maximum_size(int m) {maximum_size_ = m;}
280
/** Gets the position of the text cursor.
281
\return the cursor position as an index
282
\see position(int, int)
284
int position() const {return position_;}
286
/** Gets the current selection mark.
287
\return index into the text */
288
int mark() const {return mark_;}
290
/* Sets the index for the cursor and mark. */
291
int position(int p, int m);
293
/** Set the cursor position and mark.
294
position(n) is the same as <tt>position(n, n)</tt>.
295
\param p new index for cursor and mark
296
\return 0 if no positions changed
297
\see position(int, int), position(), mark(int)
299
int position(int p) {return position(p, p);}
301
/** Sets the current selection mark.
302
mark(n) is the same as <tt>position(position(),n)</tt>.
303
\param m new index of the mark
304
\return 0 if the mark did not change
305
\see position(), position(int, int) */
306
int mark(int m) {return position(position(), m);}
308
/* Deletes text from b to e and inserts the new string text. */
309
int replace(int, int, const char*, int=0);
312
Deletes the current selection.
314
This function deletes the currently selected text
315
\e without storing it in the clipboard. To use the clipboard,
316
you may call copy() first or copy_cuts() after
319
\return 0 if no data was copied
321
int cut() {return replace(position(), mark(), 0);}
324
Deletes the next \p n bytes rounded to characters before or after the cursor.
326
This function deletes the currently selected text
327
\e without storing it in the clipboard. To use the clipboard,
328
you may call copy() first or copy_cuts() after
331
\param n number of bytes rounded to full characters and clamped to the buffer.
332
A negative number will cut characters to the left of the cursor.
333
\return 0 if no data was copied
335
int cut(int n) {return replace(position(), position()+n, 0);}
338
Deletes all characters between index \p a and \p b.
340
This function deletes the currently selected text
341
\e without storing it in the clipboard. To use the clipboard,
342
you may call copy() first or copy_cuts() after
345
\param a, b range of bytes rounded to full characters and clamped to the buffer
346
\return 0 if no data was copied
348
int cut(int a, int b) {return replace(a, b, 0);}
351
Inserts text at the cursor position.
353
This function inserts the string in \p t at the cursor
354
position() and moves the new position and mark to
355
the end of the inserted text.
357
\param [in] t text that will be inserted
358
\param [in] l length of text, or 0 if the string is terminated by \c nul.
359
\return 0 if no text was inserted
361
int insert(const char* t, int l=0){return replace(position_, mark_, t, l);}
363
/* Put the current selection into the clipboard. */
364
int copy(int clipboard);
366
/* Undo previous changes to the text buffer. */
369
/* Copy the yank buffer to the clipboard. */
372
/** Return the shortcut key associated with this widget.
373
\return shortcut keystroke
374
\see Fl_Button::shortcut() */
375
int shortcut() const {return shortcut_;}
378
Sets the shortcut key associated with this widget.
379
Pressing the shortcut key gives text editing focus to this widget.
380
\param [in] s new shortcut keystroke
381
\see Fl_Button::shortcut()
383
void shortcut(int s) {shortcut_ = s;}
385
/** Gets the font of the text in the input field.
386
\return the current Fl_Font index */
387
Fl_Font textfont() const {return textfont_;}
389
/** Sets the font of the text in the input field.
390
The text font defaults to \c FL_HELVETICA.
391
\param [in] s the new text font */
392
void textfont(Fl_Font s) {textfont_ = s;}
394
/** Gets the size of the text in the input field.
395
\return the text height in pixels */
396
Fl_Fontsize textsize() const {return textsize_;}
398
/** Sets the size of the text in the input field.
399
The text height defaults to \c FL_NORMAL_SIZE.
400
\param [in] s the new font height in pixel units */
401
void textsize(Fl_Fontsize s) {textsize_ = s;}
403
/** Gets the color of the text in the input field.
404
\return the text color
405
\see textcolor(Fl_Color) */
406
Fl_Color textcolor() const {return textcolor_;}
408
/** Sets the color of the text in the input field.
409
The text color defaults to \c FL_FOREGROUND_COLOR.
410
\param [in] n new text color
412
void textcolor(Fl_Color n) {textcolor_ = n;}
414
/** Gets the color of the cursor.
415
\return the current cursor color */
416
Fl_Color cursor_color() const {return cursor_color_;}
418
/** Sets the color of the cursor.
419
The default color for the cursor is \c FL_BLACK.
420
\param [in] n the new cursor color */
421
void cursor_color(Fl_Color n) {cursor_color_ = n;}
423
/** Gets the input field type.
424
\return the current input type */
425
int input_type() const {return type() & FL_INPUT_TYPE; }
427
/** Sets the input field type.
428
A redraw() is required to reformat the input field.
429
\param [in] t new input type */
430
void input_type(int t) { type((uchar)(t | readonly())); }
432
/** Gets the read-only state of the input field.
433
\return non-zero if this widget is read-only */
434
int readonly() const { return type() & FL_INPUT_READONLY; }
436
/** Sets the read-only state of the input field.
437
\param [in] b if \p b is 0, the text in this widget can be edited by the user */
438
void readonly(int b) { if (b) type((uchar)(type() | FL_INPUT_READONLY));
439
else type((uchar)(type() & ~FL_INPUT_READONLY)); }
442
Gets the word wrapping state of the input field.
443
Word wrap is only functional with multi-line input fields.
445
int wrap() const { return type() & FL_INPUT_WRAP; }
448
Sets the word wrapping state of the input field.
449
Word wrap is only functional with multi-line input fields.
451
void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP));
452
else type((uchar)(type() & ~FL_INPUT_WRAP)); }
455
Sets whether the Tab key does focus navigation,
456
or inserts tab characters into Fl_Multiline_Input.
458
By default this flag is enabled to provide the 'normal' behavior
459
most users expect; Tab navigates focus to the next widget.
460
To inserting an actual Tab character, users can use Ctrl-I
463
Disabling this flag gives the old FLTK behavior where Tab
464
inserts a tab character into the text field, in which case
465
only the mouse can be used to navigate to the next field.
467
History: This flag was provided for backwards support of FLTK's old 1.1.x
468
behavior where Tab inserts a tab character instead of navigating
469
focus to the next widget. This behavior was unique to Fl_Multiline_Input.
470
With the advent of Fl_Text_Editor, this old behavior has been deprecated.
472
\param [in] val If \p val is 1, Tab advances focus (default).<BR>
473
If \p val is 0, Tab inserts a tab character (old FLTK behavior).
475
void tab_nav(int val) {
480
Gets whether the Tab key causes focus navigation in multiline input fields or not.
482
If enabled (default), hitting Tab causes focus navigation to the next widget.
484
If disabled, hitting Tab inserts a tab character into the text field.
485
\returns 1 if Tab advances focus (default), 0 if Tab inserts tab characters.
488
int tab_nav() const {
496
// End of "$Id: Fl_Input_.H 8068 2010-12-20 07:48:59Z greg.ercolano $".