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