blob: c9b91f1f1fac8559ff656bbca52a87f35f370f50 [file] [log] [blame]
DRC2ff39b82011-07-28 08:38:59 +00001//
2// "$Id: Fl_Text_Display.H 8306 2011-01-24 17:04:22Z matt $"
3//
4// Header file for Fl_Text_Display class.
5//
6// Copyright 2001-2010 by Bill Spitzak and others.
7// Original code Copyright Mark Edel. Permission to distribute under
8// the LGPL for the FLTK library granted by Mark Edel.
9//
10// This library is free software; you can redistribute it and/or
11// modify it under the terms of the GNU Library General Public
12// License as published by the Free Software Foundation; either
13// version 2 of the License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Library General Public License for more details.
19//
20// You should have received a copy of the GNU Library General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23// USA.
24//
25// Please report all bugs and problems on the following page:
26//
27// http://www.fltk.org/str.php
28//
29
30/* \file
31 Fl_Text_Display widget . */
32
33#ifndef FL_TEXT_DISPLAY_H
34#define FL_TEXT_DISPLAY_H
35
36#include "fl_draw.H"
37#include "Fl_Group.H"
38#include "Fl_Widget.H"
39#include "Fl_Scrollbar.H"
40#include "Fl_Text_Buffer.H"
41
42/**
43 \brief Rich text display widget.
44
45 This is the FLTK text display widget. It allows the user to view multiple lines
46 of text and supports highlighting and scrolling. The buffer that is displayed
47 in the widget is managed by the Fl_Text_Buffer class. A single Text Buffer
48 can be displayed by multiple Text Displays.
49 */
50class FL_EXPORT Fl_Text_Display: public Fl_Group {
51
52public:
53
54 /**
55 text display cursor shapes enumeration
56 */
57 enum {
58 NORMAL_CURSOR, /**< I-beam */
59 CARET_CURSOR, /**< caret under the text */
60 DIM_CURSOR, /**< dim I-beam */
61 BLOCK_CURSOR, /**< unfille box under the current character */
62 HEAVY_CURSOR /**< thick I-beam */
63 };
64
65 /**
66 the character position is the left edge of a character, whereas
67 the cursor is thought to be between the centers of two consecutive
68 characters.
69 */
70 enum {
71 CURSOR_POS,
72 CHARACTER_POS
73 };
74
75 /**
76 drag types - they match Fl::event_clicks() so that single clicking to
77 start a collection selects by character, double clicking selects by
78 word and triple clicking selects by line.
79 */
80 enum {
81 DRAG_NONE = -2,
82 DRAG_START_DND = -1,
83 DRAG_CHAR = 0,
84 DRAG_WORD = 1,
85 DRAG_LINE = 2
86 };
87
88 /**
89 wrap types - used in wrap_mode()
90 */
91 enum {
92 WRAP_NONE, /**< don't wrap text at all */
93 WRAP_AT_COLUMN, /**< wrap text at the given text column */
94 WRAP_AT_PIXEL, /**< wrap text at a pixel position */
95 WRAP_AT_BOUNDS /**< wrap text so that it fits into the widget width */
96 };
97
98 friend void fl_text_drag_me(int pos, Fl_Text_Display* d);
99
100 typedef void (*Unfinished_Style_Cb)(int, void *);
101
102 /**
103 This structure associates the color, font, andsize of a string to draw
104 with an attribute mask matching attr
105 */
106 struct Style_Table_Entry {
107 Fl_Color color;
108 Fl_Font font;
109 Fl_Fontsize size;
110 unsigned attr;
111 };
112
113 Fl_Text_Display(int X, int Y, int W, int H, const char *l = 0);
114 ~Fl_Text_Display();
115
116 virtual int handle(int e);
117
118 void buffer(Fl_Text_Buffer* buf);
119
120 /**
121 Sets the current text buffer associated with the text widget.
122 Multiple text widgets can be associated with the same text buffer.
123 \param buf new text buffer
124 */
125 void buffer(Fl_Text_Buffer& buf) { buffer(&buf); }
126
127 /**
128 Gets the current text buffer associated with the text widget.
129 Multiple text widgets can be associated with the same text buffer.
130 \return current text buffer
131 */
132 Fl_Text_Buffer* buffer() const { return mBuffer; }
133
134 void redisplay_range(int start, int end);
135 void scroll(int topLineNum, int horizOffset);
136 void insert(const char* text);
137 void overstrike(const char* text);
138 void insert_position(int newPos);
139
140 /**
141 Gets the position of the text insertion cursor for text display.
142 \return insert position index into text buffer
143 */
144 int insert_position() const { return mCursorPos; }
145 int position_to_xy(int pos, int* x, int* y) const;
146
147 int in_selection(int x, int y) const;
148 void show_insert_position();
149
150 int move_right();
151 int move_left();
152 int move_up();
153 int move_down();
154 int count_lines(int start, int end, bool start_pos_is_line_start) const;
155 int line_start(int pos) const;
156 int line_end(int startPos, bool startPosIsLineStart) const;
157 int skip_lines(int startPos, int nLines, bool startPosIsLineStart);
158 int rewind_lines(int startPos, int nLines);
159 void next_word(void);
160 void previous_word(void);
161
162 void show_cursor(int b = 1);
163
164 /**
165 Hides the text cursor.
166 */
167 void hide_cursor() { show_cursor(0); }
168
169 void cursor_style(int style);
170
171 /**
172 Gets the text cursor color.
173 \return cursor color
174 */
175 Fl_Color cursor_color() const {return mCursor_color;}
176
177 /**
178 Sets the text cursor color.
179 \param n new cursor color
180 */
181 void cursor_color(Fl_Color n) {mCursor_color = n;}
182
183 /**
184 Gets the width/height of the scrollbars.
185 /return width of scrollbars
186 */
187 int scrollbar_width() const { return scrollbar_width_; }
188
189 /**
190 Sets the width/height of the scrollbars.
191 \param W width of scrollbars
192 */
193 void scrollbar_width(int W) { scrollbar_width_ = W; }
194
195 /**
196 Gets the scrollbar alignment type.
197 \return scrollbar alignment
198 */
199 Fl_Align scrollbar_align() const { return scrollbar_align_; }
200
201 /**
202 Sets the scrollbar alignment type.
203 \param a new scrollbar alignment
204 */
205 void scrollbar_align(Fl_Align a) { scrollbar_align_ = a; }
206
207 /**
208 Moves the insert position to the beginning of the current word.
209 \param pos start calculation at this index
210 \return beginning of the words
211 */
212 int word_start(int pos) const { return buffer()->word_start(pos); }
213
214 /**
215 Moves the insert position to the end of the current word.
216 \param pos start calculation at this index
217 \return index of first character after the end of the word
218 */
219 int word_end(int pos) const { return buffer()->word_end(pos); }
220
221
222 void highlight_data(Fl_Text_Buffer *styleBuffer,
223 const Style_Table_Entry *styleTable,
224 int nStyles, char unfinishedStyle,
225 Unfinished_Style_Cb unfinishedHighlightCB,
226 void *cbArg);
227
228 int position_style(int lineStartPos, int lineLen, int lineIndex) const;
229
230 /**
231 \todo FIXME : get set methods pointing on shortcut_
232 have no effects as shortcut_ is unused in this class and derived!
233 \return the current shortcut key
234 */
235 int shortcut() const {return shortcut_;}
236
237 /**
238 \todo FIXME : get set methods pointing on shortcut_
239 have no effects as shortcut_ is unused in this class and derived!
240 \param s the new shortcut key
241 */
242 void shortcut(int s) {shortcut_ = s;}
243
244 /**
245 Gets the default font used when drawing text in the widget.
246 \return current text font face unless overridden by a style
247 */
248 Fl_Font textfont() const {return textfont_;}
249
250 /**
251 Sets the default font used when drawing text in the widget.
252 \param s default text font face
253 */
254 void textfont(Fl_Font s) {textfont_ = s; mColumnScale = 0;}
255
256 /**
257 Gets the default size of text in the widget.
258 \return current text height unless overridden by a style
259 */
260 Fl_Fontsize textsize() const {return textsize_;}
261
262 /**
263 Sets the default size of text in the widget.
264 \param s new text size
265 */
266 void textsize(Fl_Fontsize s) {textsize_ = s; mColumnScale = 0;}
267
268 /**
269 Gets the default color of text in the widget.
270 \return text color unless overridden by a style
271 */
272 Fl_Color textcolor() const {return textcolor_;}
273
274 /**
275 Sets the default color of text in the widget.
276 \param n new text color
277 */
278 void textcolor(Fl_Color n) {textcolor_ = n;}
279
280 int wrapped_column(int row, int column) const;
281 int wrapped_row(int row) const;
282 void wrap_mode(int wrap, int wrap_margin);
283
284 virtual void resize(int X, int Y, int W, int H);
285
286 /**
287 Convert an x pixel position into a column number.
288 \param x number of pixels from the left margin
289 \return an approximate column number based on the main font
290 */
291 double x_to_col(double x) const;
292
293 /**
294 Convert a column number into an x pixel position.
295 \param col an approximate column number based on the main font
296 \return number of pixels from the left margin to the left of an
297 average sized character
298 */
299 double col_to_x(double col) const;
300
301protected:
302 // Most (all?) of this stuff should only be called from resize() or
303 // draw().
304 // Anything with "vline" indicates thats it deals with currently
305 // visible lines.
306
307 virtual void draw();
308 void draw_text(int X, int Y, int W, int H);
309 void draw_range(int start, int end);
310 void draw_cursor(int, int);
311
312 void draw_string(int style, int x, int y, int toX, const char *string,
313 int nChars) const;
314
315 void draw_vline(int visLineNum, int leftClip, int rightClip,
316 int leftCharIndex, int rightCharIndex);
317
318 int find_x(const char *s, int len, int style, int x) const;
319
320 enum {
321 DRAW_LINE,
322 FIND_INDEX,
323 FIND_INDEX_FROM_ZERO,
324 GET_WIDTH
325 };
326
327 int handle_vline(int mode,
328 int lineStart, int lineLen, int leftChar, int rightChar,
329 int topClip, int bottomClip,
330 int leftClip, int rightClip) const;
331
332 void draw_line_numbers(bool clearAll);
333
334 void clear_rect(int style, int x, int y, int width, int height) const;
335 void display_insert();
336
337 void offset_line_starts(int newTopLineNum);
338
339 void calc_line_starts(int startLine, int endLine);
340
341 void update_line_starts(int pos, int charsInserted, int charsDeleted,
342 int linesInserted, int linesDeleted, int *scrolled);
343
344 void calc_last_char();
345
346 int position_to_line( int pos, int* lineNum ) const;
347 double string_width(const char* string, int length, int style) const;
348
349 static void scroll_timer_cb(void*);
350
351 static void buffer_predelete_cb(int pos, int nDeleted, void* cbArg);
352 static void buffer_modified_cb(int pos, int nInserted, int nDeleted,
353 int nRestyled, const char* deletedText,
354 void* cbArg);
355
356 static void h_scrollbar_cb(Fl_Scrollbar* w, Fl_Text_Display* d);
357 static void v_scrollbar_cb( Fl_Scrollbar* w, Fl_Text_Display* d);
358 void update_v_scrollbar();
359 void update_h_scrollbar();
360 int measure_vline(int visLineNum) const;
361 int longest_vline() const;
362 int empty_vlines() const;
363 int vline_length(int visLineNum) const;
364 int xy_to_position(int x, int y, int PosType = CHARACTER_POS) const;
365
366 void xy_to_rowcol(int x, int y, int* row, int* column,
367 int PosType = CHARACTER_POS) const;
368 void maintain_absolute_top_line_number(int state);
369 int get_absolute_top_line_number() const;
370 void absolute_top_line_number(int oldFirstChar);
371 int maintaining_absolute_top_line_number() const;
372 void reset_absolute_top_line_number();
373 int position_to_linecol(int pos, int* lineNum, int* column) const;
374 int scroll_(int topLineNum, int horizOffset);
375
376 void extend_range_for_styles(int* start, int* end);
377
378 void find_wrap_range(const char *deletedText, int pos, int nInserted,
379 int nDeleted, int *modRangeStart, int *modRangeEnd,
380 int *linesInserted, int *linesDeleted);
381 void measure_deleted_lines(int pos, int nDeleted);
382 void wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, int maxPos,
383 int maxLines, bool startPosIsLineStart,
384 int styleBufOffset, int *retPos, int *retLines,
385 int *retLineStart, int *retLineEnd,
386 bool countLastLineMissingNewLine = true) const;
387 void find_line_end(int pos, bool start_pos_is_line_start, int *lineEnd,
388 int *nextLineStart) const;
389 double measure_proportional_character(const char *s, int colNum, int pos) const;
390 int wrap_uses_character(int lineEndPos) const;
391
392 int damage_range1_start, damage_range1_end;
393 int damage_range2_start, damage_range2_end;
394 int mCursorPos;
395 int mCursorOn;
396 int mCursorOldY; /* Y pos. of cursor for blanking */
397 int mCursorToHint; /* Tells the buffer modified callback
398 where to move the cursor, to reduce
399 the number of redraw calls */
400 int mCursorStyle; /* One of enum cursorStyles above */
401 int mCursorPreferredXPos; /* Pixel position for vert. cursor movement */
402 int mNVisibleLines; /* # of visible (displayed) lines */
403 int mNBufferLines; /* # of newlines in the buffer */
404 Fl_Text_Buffer* mBuffer; /* Contains text to be displayed */
405 Fl_Text_Buffer* mStyleBuffer; /* Optional parallel buffer containing
406 color and font information */
407 int mFirstChar, mLastChar; /* Buffer positions of first and last
408 displayed character (lastChar points
409 either to a newline or one character
410 beyond the end of the buffer) */
411 int mContinuousWrap; /* Wrap long lines when displaying */
412 int mWrapMarginPix; /* Margin in # of pixels for
413 wrapping in continuousWrap mode */
414 int* mLineStarts;
415 int mTopLineNum; /* Line number of top displayed line
416 of file (first line of file is 1) */
417 int mAbsTopLineNum; /* In continuous wrap mode, the line
418 number of the top line if the text
419 were not wrapped (note that this is
420 only maintained as needed). */
421 int mNeedAbsTopLineNum; /* Externally settable flag to continue
422 maintaining absTopLineNum even if
423 it isn't needed for line # display */
424 int mHorizOffset; /* Horizontal scroll pos. in pixels */
425 int mTopLineNumHint; /* Line number of top displayed line
426 of file (first line of file is 1) */
427 int mHorizOffsetHint; /* Horizontal scroll pos. in pixels */
428 int mNStyles; /* Number of entries in styleTable */
429 const Style_Table_Entry *mStyleTable; /* Table of fonts and colors for
430 coloring/syntax-highlighting */
431 char mUnfinishedStyle; /* Style buffer entry which triggers
432 on-the-fly reparsing of region */
433 Unfinished_Style_Cb mUnfinishedHighlightCB; /* Callback to parse "unfinished" */
434 /* regions */
435 void* mHighlightCBArg; /* Arg to unfinishedHighlightCB */
436
437 int mMaxsize;
438
439 int mSuppressResync; /* Suppress resynchronization of line
440 starts during buffer updates */
441 int mNLinesDeleted; /* Number of lines deleted during
442 buffer modification (only used
443 when resynchronization is suppressed) */
444 int mModifyingTabDistance; /* Whether tab distance is being
445 modified */
446
447 mutable double mColumnScale; /* Width in pixels of an average character. This
448 value is calculated as needed (lazy eval); it
449 needs to be mutable so that it can be calculated
450 within a method marked as "const" */
451
452 Fl_Color mCursor_color;
453
454 Fl_Scrollbar* mHScrollBar;
455 Fl_Scrollbar* mVScrollBar;
456 int scrollbar_width_;
457 Fl_Align scrollbar_align_;
458 int dragPos, dragType, dragging;
459 int display_insert_position_hint;
460 struct { int x, y, w, h; } text_area;
461
462 int shortcut_;
463
464 Fl_Font textfont_;
465 Fl_Fontsize textsize_;
466 Fl_Color textcolor_;
467
468 // The following are not presently used from the original NEdit code,
469 // but are being put here so that future versions of Fl_Text_Display
470 // can implement line numbers without breaking binary compatibility.
471
472 /* Line number margin and width */
473 int mLineNumLeft, mLineNumWidth;
474};
475
476#endif
477
478//
479// End of "$Id: Fl_Text_Display.H 8306 2011-01-24 17:04:22Z matt $".
480//