summaryrefslogtreecommitdiffstats
path: root/fltk/fltk/TextDisplay.h
blob: 88771000f3bc1f7ee184e63e98aee5c6a3a15594 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
//
// "$Id: TextDisplay.h 5432 2006-09-16 02:03:04Z spitzak $"
//
// Header file for TextDisplay class.
//
// Copyright 2001-2006 by Bill Spitzak and others.
// Original code Copyright Mark Edel.  Permission to distribute under
// the LGPL for the FLTK library granted by Mark Edel.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems on the following page:
//
//     http://www.fltk.org/str.php
//

#ifndef _fltk_TextDisplay_h_
#define _fltk_TextDisplay_h_

#include "draw.h"
#include "Group.h"
#include "Widget.h"
#include "Scrollbar.h"
#include "TextBuffer.h"
#include "Font.h"

namespace fltk {

typedef void (*UnfinishedStyleCb)(int, void *);

/** TextDisplay */
class FL_API TextDisplay: public Group {
public:
  enum {
    NORMAL_CURSOR, CARET_CURSOR, DIM_CURSOR,
    BLOCK_CURSOR, HEAVY_CURSOR
  };

  enum {
    CURSOR_POS, CHARACTER_POS
  };

  // drag types- they match fltk::event_clicks() so that single clicking to
  // start a collection selects by character, double clicking selects by
  // word and triple clicking selects by line.
  enum {
    DRAG_CHAR = 0, DRAG_WORD = 1, DRAG_LINE = 2
  };

  enum {
    ATTR_NONE = 0,
    ATTR_UNDERLINE = 1,
    ATTR_HIDDEN = 2
  };

  struct StyleTableEntry {
    Color	color;
    Font        *font;
    float       size;
    unsigned	attr;
  };

  TextDisplay(int X, int Y, int W, int H, const char *l = 0);
  ~TextDisplay();

  // Emulation of Input widget:
  int size() const { return buffer_->length(); }
  const char* text() const { return buffer_->text(); }
  void text( const char* v) { buffer_->text(v); }
  void static_text( const char* v) { buffer_->text(v); }
  char at(int i) const { return buffer_->character(i); }

  virtual int handle(int e);
  virtual void draw();
  virtual void layout();

  /** Associate 'buf' with display */
  void buffer(TextBuffer* buf);
  /** Associate 'buf' with display */
  void buffer(TextBuffer& buf) { buffer(&buf); }

  /** Return attached buffer */
  TextBuffer* buffer() { return buffer_; }
  /** Return attached buffer */
  const TextBuffer* buffer() const { return buffer_; }

  /** Append text to the end of the buffer */
  void append(const char *text) { insert_position(buffer()->length()); insert(text); }
  /** Insert text to current cursor position */
  void insert(const char *text);
  /** Overstrike text from current cursor position */
  void overstrike(const char *text);

  /** Set new cursor position */
  void insert_position(int newPos);
  /** Return current cursor position */
  int insert_position() const { return cursor_pos_; }
  /** Make cursor position visible in screen */
  void show_insert_position();

  /** Show cursor */
  void show_cursor(bool b = true);
  /** Hide cursor */
  void hide_cursor() { show_cursor(false); }
  /** Return cursor visibility state */
  bool cursor_on() const { return cursor_on_; }
  /** Set cursor style */
  void cursor_style(int style);

  /** Return cursor color */
  Color cursor_color() const { return cursor_color_;}
  /** Set cursor color */
  void cursor_color(Color n) { cursor_color_ = n; }

  /** Return begining of the word where 'pos' is located */
  int word_start(int pos) { return buffer()->word_start(pos); }
  /** Return end of the word where 'pos' is located */
  int word_end(int pos) { return buffer()->word_end(pos); }
  /** Go to next word */
  void next_word(void);
  /** Go to previous word */
  void previous_word(void);

  /** Set wrapping mode. wrap_margin is width to wrap at, zero means use w() */
  void wrap_mode(bool wrap, int wrap_margin=0);

  /** Set line number area width */
  void linenumber_width(int width);
  /** Return line number area width */
  int linenumber_width() const { return linenumwidth_; }

  /** Set new highlight data */
  void highlight_data(TextBuffer *styleBuffer,
		      StyleTableEntry *styleTable,
		      int nStyles, char unfinishedStyle,
		      UnfinishedStyleCb unfinishedHighlightCB,
		      void *cbArg);

  /** Move cursor right */
  bool move_right();
  /** Move cursor left */
  bool move_left();
  /** Move cursor down */
  bool move_up();
  /** Move cursor down */
  bool move_down();

  /** Redisplay text */
  void redisplay_range(int start, int end);

  /** Scroll to new position */
  void scroll(int topLineNum, int horizOffset);

  /** Returns true if position is inside selection */
  bool in_selection(int x, int y);

  /** Returns begining of the line where 'pos' is located */
  int line_start(int pos);

  /** Returns end of the line where 'pos' is located */
  int line_end(int pos, bool start_pos_is_line_start = false);

  /** Return number of visible lines */
  int visible_lines() const { return visiblelines_cnt_; }

  /** Return current visible topline */
  int top_line() const { return topline_num_; }

  /** Return current horizontal offset */
  int hor_offset() const { return horiz_offset_; }

  /** Find start of the next character, starting from 'pos'
   * If 'pos' points to start of character already, it is returned.
   * This is mainly used with UTF-8 strings
   */
  int find_next_char(int pos);

  /** Find start of the previous character, starting from 'pos'
   * If 'pos' points to start of character already, it is returned.
   * This is mainly used with UTF-8 strings
   */
  int find_prev_char(int pos);

  int xy_to_position(int X, int Y, int PosType = CHARACTER_POS);

  void xy_to_rowcol(int X, int Y, int *row, int *column, int PosType = CHARACTER_POS);

  bool position_to_xy(int pos, int *X, int *Y);

  int total_lines() {return count_lines(0, buffer_->length(), true);}

protected:
  void draw_text(int X, int Y, int W, int H);
  void draw_range(int start, int end);
  void draw_cursor(int, int);

  void draw_string(int style, int x, int y, int toX, const char *string,
		   int nChars);

  void draw_vline(int visLineNum, int leftClip, int rightClip,
		  int leftCharIndex, int rightCharIndex);

  void draw_line_numbers(bool clearAll);

  void clear_rect(int style, int x, int y, int width, int height);
  void display_insert();

  int count_lines(int start, int end, bool start_pos_is_line_start);
  int skip_lines(int startPos, int nLines, bool startPosIsLineStart);
  int rewind_lines(int startPos, int nLines);
  int position_style(int lineStartPos, int lineLen, int lineIndex, int dispIndex);

  int wrapped_column(int row, int column);
  int wrapped_row(int row);

  void offset_line_starts(int newTopLineNum);

  void calc_line_starts(int startLine, int endLine);

  void update_line_starts(int pos, int charsInserted, int charsDeleted,
			  int linesInserted, int linesDeleted, bool *scrolled);

  void calc_last_char();

  bool position_to_line(int pos, int* lineNum);
  int string_width(const char* string, int length, int style);

  static void buffer_predelete_cb(int pos, int nDeleted, void* cbArg);
  static void buffer_modified_cb(int pos, int nInserted, int nDeleted,
				 int nRestyled, const char* deletedText,
				 void* cbArg);

  static void h_scrollbar_cb(Scrollbar* w, TextDisplay* d);
  static void v_scrollbar_cb( Scrollbar* w, TextDisplay* d);
  void update_v_scrollbar();
  void update_h_scrollbar(int longestvline = 0);

  void blank_cursor_protrusions();
  int measure_vline(int visLineNum);
  int longest_vline();
  int empty_vlines();
  int vline_length(int visLineNum);

  void maintain_absolute_top_line_number(bool state);
  int get_absolute_top_line_number();
  void absolute_top_line_number(int oldFirstChar);
  int maintaining_absolute_top_line_number();
  void reset_absolute_top_line_number();
  bool position_to_linecol(int pos, int *lineNum, int *column);
  void scroll_(int topLineNum, int horizOffset);

  void extend_range_for_styles(int* start, int* end);

  void find_wrap_range(const char *deletedText, int pos, int nInserted,
			 int nDeleted, int *modRangeStart, int *modRangeEnd,
			 int *linesInserted, int *linesDeleted);
  void measure_deleted_lines(int pos, int nDeleted);
  void wrapped_line_counter(TextBuffer *buf, int startPos, int maxPos,
			     int maxLines, bool startPosIsLineStart,
			     int styleBufOffset, int *retPos, int *retLines,
			     int *retLineStart, int *retLineEnd,
			     bool countLastLineMissingNewLine = true);
  void find_line_end(int pos, bool start_pos_is_line_start, int *lineEnd,
		       int *nextLineStart);
  int measure_proportional_character(TextBuffer *buf, int bufpos, int colNum, int pos);
  int wrap_uses_character(int lineEndPos);
  int range_touches_selection(TextSelection *sel, int rangeStart, int rangeEnd);
  void text_drag_me(int pos);

  int damage_range1_start, damage_range1_end;
  int damage_range2_start, damage_range2_end;

  int cursor_pos_;
  bool cursor_on_;
  int cursor_oldx_;           /* X pos. of cursor for blanking */
  int cursor_oldy_;           /* Y pos. of cursor for blanking */
  int cursor_hint_;           /* Tells the buffer modified callback
				 where to move the cursor, to reduce
				 the number of redraw calls */
  int cursor_style_;          /* One of enum cursorStyles above */
  int cursor_preferred_col_;  /* Column for vert. cursor movement */
  int visiblelines_cnt_;      /* # of visible (displayed) lines */
  int bufferlines_cnt_;       /* # of newlines in the buffer */
  TextBuffer *buffer_;        /* Contains text to be displayed */
  TextBuffer *stylebuffer_;   /* Optional parallel buffer containing
				 color and font information */
  int firstchar_, lastchar_;  /* Buffer positions of first and last
				 displayed character (lastChar points
				 either to a newline or one character
				 beyond the end of the buffer) */
  bool own_buffer;	      /* True if buffer_ created by constructor */
  bool continuous_wrap_;      /* Wrap long lines when displaying */
  int wrapmargin_;            /* Margin in # of char positions for
				 wrapping in continuousWrap mode */
  int *linestarts_;
  int topline_num_;           /* Line number of top displayed line
				 of file (first line of file is 1) */
  int abs_topline_num_;       /* In continuous wrap mode, the line
				 number of the top line if the text
				 were not wrapped (note that this is
				 only maintained as needed). */
  bool need_abs_topline_num_; /* Externally settable flag to continue
				 maintaining absTopLineNum even if
				 it isn't needed for line # display */
  int horiz_offset_;          /* Horizontal scroll pos. in pixels */
  int numstyles_;             /* Number of entries in styleTable */
  const StyleTableEntry *styletable_; /* Table of fonts and colors for
					 coloring/syntax-highlighting */
  char unfinished_style_;     /* Style buffer entry which triggers
				 on-the-fly reparsing of region */
  UnfinishedStyleCb unfinished_highlight_cb_; /* Callback to parse "unfinished" */
					      /* regions */
  void *highlight_cbarg_;     /* Arg to unfinishedHighlightCB */
  int fixed_fontwidth_;       /* Font width if all current fonts are
				 fixed and match in width, else -1 */
  bool suppressresync_;       /* Suppress resynchronization of line
				 starts during buffer updates */
  int nlinesdeleted_;         /* Number of lines deleted during
				 buffer modification (only used
				 when resynchronization is suppressed) */

  int stdfontwidth_;
  int ascent_;
  int descent_;
  int maxsize_;

  Color cursor_color_;

  Scrollbar *hscrollbar;
  Scrollbar *vscrollbar;

  Rectangle text_area;

  int dragpos_, dragtype_, dragging_;
  int linenumleft_, linenumwidth_; /* Line number margin and width */
};

} /* namespace fltk */

#endif

//
// End of "$Id: TextDisplay.h 5432 2006-09-16 02:03:04Z spitzak $".
//