blob: 1638436a45231499fa10adf155bb18a26a2a0291 [file] [log] [blame]
DRC2ff39b82011-07-28 08:38:59 +00001//
2// "$Id: Fl_Input_.H 8068 2010-12-20 07:48:59Z greg.ercolano $"
3//
4// Input base class header file for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 1998-2010 by Bill Spitzak and others.
7//
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.
12//
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.
17//
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
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25// http://www.fltk.org/str.php
26//
27
28/* \file
29 Fl_Input_ widget . */
30
31#ifndef Fl_Input__H
32#define Fl_Input__H
33
34#ifndef Fl_Widget_H
35#include "Fl_Widget.H"
36#endif
37
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)
51
52/**
53 This class provides a low-overhead text input field.
54
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
60 to the input field.
61
62 This can act like any of the subclasses of Fl_Input, by
63 setting type() to one of the following values:
64
65 \code
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)
78 \endcode
79
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
83 in the text buffer.
84
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.
88
89 \see Fl_Text_Display, Fl_Text_Editor for more powerful text handling widgets
90
91 \internal
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.
98
99 None of these issues should be disastrous. Nevertheless, we should
100 discuss how FLTK should handle false UTF-8 sequences and pointers.
101*/
102class FL_EXPORT Fl_Input_ : public Fl_Widget {
103
104 /** \internal Storage for the text field. */
105 const char* value_;
106
107 /** \internal Buffer memory for expanded text. \see expand() */
108 char* buffer;
109
110 /** \internal Size of text in bytes in the \p value_ field. */
111 int size_;
112
113 /** \internal \todo Please document me! */
114 int bufsize;
115
116 /** \internal Position of the cursor in the document. */
117 int position_;
118
119 /** \internal Position of the other end of the selected text. If \p position_ equals
120 \p mark_, no text is selected */
121 int mark_;
122
123 /** \internal Behavior of Tab key in multiline input widget.
124 If enabled (default) Tab causes focus nav, otherwise Tab is inserted
125 as a character. */
126 int tab_nav_;
127
128 /** \internal Offset to text origin within widget bounds */
129 int xscroll_, yscroll_;
130
131 /** \internal Minimal update pointer. Display requires redraw from here to the end
132 of the buffer. */
133 int mu_p;
134
135 /** \internal Maximum size of buffer. \todo Is this really needed? */
136 int maximum_size_;
137
138 /** \internal Shortcut key that will fetch focus for this widget. */
139 int shortcut_;
140
141 /** \internal This is set if no text but only the cursor needs updating. */
142 uchar erase_cursor_only;
143
144 /** \internal The font used for the entire text. */
145 Fl_Font textfont_;
146
147 /** \internal Height of the font used for the entire text. */
148 Fl_Fontsize textsize_;
149
150 /** \internal color of the entire text */
151 Fl_Color textcolor_;
152
153 /** \internal color of the text cursor */
154 Fl_Color cursor_color_;
155
156 /** \internal Horizontal cursor position in pixels while moving up or down. */
157 static double up_down_pos;
158
159 /** \internal Flag to remember last cursor move. */
160 static int was_up_down;
161
162 /* Convert a given text segment into the text that will be rendered on screen. */
163 const char* expand(const char*, char*) const;
164
165 /* Calculates the width in pixels of part of a text buffer. */
166 double expandpos(const char*, const char*, const char*, int*) const;
167
168 /* Mark a range of characters for update. */
169 void minimal_update(int, int);
170
171 /* Mark a range of characters for update. */
172 void minimal_update(int p);
173
174 /* Copy the value from a possibly static entry into the internal buffer. */
175 void put_in_buffer(int newsize);
176
177 /* Set the current font and font size. */
178 void setfont() const;
179
180protected:
181
182 /* Find the start of a word. */
183 int word_start(int i) const;
184
185 /* Find the end of a word. */
186 int word_end(int i) const;
187
188 /* Find the start of a line. */
189 int line_start(int i) const;
190
191 /* Find the end of a line. */
192 int line_end(int i) const;
193
194 /* Draw the text in the passed bounding box. */
195 void drawtext(int, int, int, int);
196
197 /* Move the cursor to the column given by up_down_pos. */
198 int up_down_position(int, int keepmark=0);
199
200 /* Handle mouse clicks and mouse moves. */
201 void handle_mouse(int, int, int, int, int keepmark=0);
202
203 /* Handle all kinds of text field related events. */
204 int handletext(int e, int, int, int, int);
205
206 /* Check the when() field and do a callback if indicated. */
207 void maybe_do_callback();
208
209 /** \internal Horizontal offset of text to left edge of widget. */
210 int xscroll() const {return xscroll_;}
211
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);}
215
216 /* Return the number of lines displayed on a single page. */
217 int linesPerPage();
218
219public:
220
221 /* Change the size of the widget. */
222 void resize(int, int, int, int);
223
224 /* Constructor */
225 Fl_Input_(int, int, int, int, const char* = 0);
226
227 /* Destructor */
228 ~Fl_Input_();
229
230 /* Changes the widget text. */
231 int value(const char*);
232
233 /* Changes the widget text. */
234 int value(const char*, int);
235
236 /* Changes the widget text. */
237 int static_value(const char*);
238
239 /* Changes the widget text. */
240 int static_value(const char*, int);
241
242 /**
243 Returns the text displayed in the widget.
244
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
247 handled.
248
249 \return pointer to an internal buffer - do not free() this
250 \see Fl_Input_::value(const char*)
251 */
252 const char* value() const {return value_;}
253
254 /* Returns the character at index \p i. */
255 Fl_Char index(int i) const;
256
257 /**
258 Returns the number of bytes in value().
259
260 This may be greater than <tt>strlen(value())</tt> if there are
261 \c nul characters in the text.
262
263 \return number of bytes in the text
264 */
265 int size() const {return size_;}
266
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); }
271
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_;}
275
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;}
279
280 /** Gets the position of the text cursor.
281 \return the cursor position as an index
282 \see position(int, int)
283 */
284 int position() const {return position_;}
285
286 /** Gets the current selection mark.
287 \return index into the text */
288 int mark() const {return mark_;}
289
290 /* Sets the index for the cursor and mark. */
291 int position(int p, int m);
292
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)
298 */
299 int position(int p) {return position(p, p);}
300
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);}
307
308 /* Deletes text from b to e and inserts the new string text. */
309 int replace(int, int, const char*, int=0);
310
311 /**
312 Deletes the current selection.
313
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
317 this call.
318
319 \return 0 if no data was copied
320 */
321 int cut() {return replace(position(), mark(), 0);}
322
323 /**
324 Deletes the next \p n bytes rounded to characters before or after the cursor.
325
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
329 this call.
330
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
334 */
335 int cut(int n) {return replace(position(), position()+n, 0);}
336
337 /**
338 Deletes all characters between index \p a and \p b.
339
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
343 this call.
344
345 \param a, b range of bytes rounded to full characters and clamped to the buffer
346 \return 0 if no data was copied
347 */
348 int cut(int a, int b) {return replace(a, b, 0);}
349
350 /**
351 Inserts text at the cursor position.
352
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.
356
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
360 */
361 int insert(const char* t, int l=0){return replace(position_, mark_, t, l);}
362
363 /* Put the current selection into the clipboard. */
364 int copy(int clipboard);
365
366 /* Undo previous changes to the text buffer. */
367 int undo();
368
369 /* Copy the yank buffer to the clipboard. */
370 int copy_cuts();
371
372 /** Return the shortcut key associated with this widget.
373 \return shortcut keystroke
374 \see Fl_Button::shortcut() */
375 int shortcut() const {return shortcut_;}
376
377 /**
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()
382 */
383 void shortcut(int s) {shortcut_ = s;}
384
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_;}
388
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;}
393
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_;}
397
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;}
402
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_;}
407
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
411 \see textcolor() */
412 void textcolor(Fl_Color n) {textcolor_ = n;}
413
414 /** Gets the color of the cursor.
415 \return the current cursor color */
416 Fl_Color cursor_color() const {return cursor_color_;}
417
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;}
422
423 /** Gets the input field type.
424 \return the current input type */
425 int input_type() const {return type() & FL_INPUT_TYPE; }
426
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())); }
431
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; }
435
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)); }
440
441 /**
442 Gets the word wrapping state of the input field.
443 Word wrap is only functional with multi-line input fields.
444 */
445 int wrap() const { return type() & FL_INPUT_WRAP; }
446
447 /**
448 Sets the word wrapping state of the input field.
449 Word wrap is only functional with multi-line input fields.
450 */
451 void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP));
452 else type((uchar)(type() & ~FL_INPUT_WRAP)); }
453
454 /**
455 Sets whether the Tab key does focus navigation,
456 or inserts tab characters into Fl_Multiline_Input.
457
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
461 or copy/paste.
462
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.
466
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.
471
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).
474 */
475 void tab_nav(int val) {
476 tab_nav_ = val;
477 }
478
479 /**
480 Gets whether the Tab key causes focus navigation in multiline input fields or not.
481
482 If enabled (default), hitting Tab causes focus navigation to the next widget.
483
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.
486 \see tab_nav(int)
487 */
488 int tab_nav() const {
489 return tab_nav_;
490 }
491};
492
493#endif
494
495//
496// End of "$Id: Fl_Input_.H 8068 2010-12-20 07:48:59Z greg.ercolano $".
497//