// // "$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 $". //