diff options
| author | Greg Ercolano <erco@seriss.com> | 2014-05-21 06:56:59 +0000 |
|---|---|---|
| committer | Greg Ercolano <erco@seriss.com> | 2014-05-21 06:56:59 +0000 |
| commit | 46521bf437f712234904a4295cb75ba15d168b5f (patch) | |
| tree | a89d0c692e005f4bc6c688374ab4333efa79d0ec /src/Fl_Text_Display.cxx | |
| parent | cb0f80cde7ced7ba1d98c8d1e3c713331ab5b5bf (diff) | |
Implements STR #2621: Add line numbers to Fl_Text_Display.
Applied LZA's patch and included some mods to address TODO items and ABI issues.
Also update CREDITS with LZA and a few other notably absent names.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10152 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Text_Display.cxx')
| -rw-r--r-- | src/Fl_Text_Display.cxx | 323 |
1 files changed, 260 insertions, 63 deletions
diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx index 0b5d75c3f..564611ad2 100644 --- a/src/Fl_Text_Display.cxx +++ b/src/Fl_Text_Display.cxx @@ -17,7 +17,7 @@ // // TODO: rendering of the "optional hyphen" -// TODO: make line numbering work again +// TODO: font background color control via style buffer #include <stdio.h> #include <stdlib.h> @@ -152,6 +152,14 @@ Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l) mContinuousWrap = 0; mWrapMarginPix = 0; mSuppressResync = mNLinesDeleted = mModifyingTabDistance = 0; +#if FLTK_ABI_VERSION >= 10303 + linenumber_font_ = FL_HELVETICA; + linenumber_size_ = FL_NORMAL_SIZE; + linenumber_fgcolor_ = FL_INACTIVE_COLOR; + linenumber_bgcolor_ = 53; // ~90% gray + linenumber_align_ = FL_ALIGN_RIGHT; + linenumber_format_ = "%d"; +#endif } @@ -175,6 +183,171 @@ Fl_Text_Display::~Fl_Text_Display() { } +/** + Set width of screen area for line numbers. + Use to also enable/disable line numbers. + A value of 0 disables line numbering, values >0 enables them. + \param width The new width of the area for line numbers to appear, in pixels. + 0 disables line numbers (default) +*/ +void Fl_Text_Display::linenumber_width(int width) { + if (width < 0) return; + mLineNumWidth = width; + resize(x(), y(), w(), h()); // triggers code to recalculate line#s +} + +/** + Return the screen area width provided for line numbers. +*/ +int Fl_Text_Display::linenumber_width() const { + return mLineNumWidth; +} + +/** + Set the font used for line numbers (if enabled). + \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher) +*/ +void Fl_Text_Display::linenumber_font(Fl_Font val) { +#if FLTK_ABI_VERSION >= 10303 + linenumber_font_ = val; +#else + // do nothing +#endif +} + +/** + Return the font used for line numbers (if enabled). +*/ +Fl_Font Fl_Text_Display::linenumber_font() const { +#if FLTK_ABI_VERSION >= 10303 + return linenumber_font_; +#else + return FL_HELVETICA; +#endif +} + +/** + Set the font size used for line numbers (if enabled). + \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher) +*/ +void Fl_Text_Display::linenumber_size(Fl_Fontsize val) { +#if FLTK_ABI_VERSION >= 10303 + linenumber_size_ = val; +#else + // do nothing +#endif +} + +/** + Return the font size used for line numbers (if enabled). +*/ +Fl_Fontsize Fl_Text_Display::linenumber_size() const { +#if FLTK_ABI_VERSION >= 10303 + return linenumber_size_; +#else + return FL_NORMAL_SIZE; +#endif +} + +/** + Set the foreground color used for line numbers (if enabled). + \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher) +*/ +void Fl_Text_Display::linenumber_fgcolor(Fl_Color val) { +#if FLTK_ABI_VERSION >= 10303 + linenumber_fgcolor_ = val; +#else + // do nothing +#endif +} + +/** + Return the foreground color used for line numbers (if enabled). +*/ +Fl_Color Fl_Text_Display::linenumber_fgcolor() const { +#if FLTK_ABI_VERSION >= 10303 + return linenumber_fgcolor_; +#else + return FL_INACTIVE_COLOR; +#endif +} + +/** + Set the background color used for line numbers (if enabled). + \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher) +*/ +void Fl_Text_Display::linenumber_bgcolor(Fl_Color val) { +#if FLTK_ABI_VERSION >= 10303 + linenumber_bgcolor_ = val; +#else + // do nothing +#endif +} + +/** + Returns the background color used for line numbers (if enabled). +*/ +Fl_Color Fl_Text_Display::linenumber_bgcolor() const { +#if FLTK_ABI_VERSION >= 10303 + return linenumber_bgcolor_; +#else + return 53; // hard coded ~90% gray +#endif +} + +/** + Set alignment for line numbers (if enabled). + Valid values are FL_ALIGN_LEFT, FL_ALIGN_CENTER or FL_ALIGN_RIGHT. + \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher) +*/ +void Fl_Text_Display::linenumber_align(Fl_Align val) { +#if FLTK_ABI_VERSION >= 10303 + linenumber_align_ = val; +#else + // do nothing +#endif +} + +/** + Returns the alignment used for line numbers (if enabled). +*/ +Fl_Align Fl_Text_Display::linenumber_align() const { +#if FLTK_ABI_VERSION >= 10303 + return linenumber_align_; +#else + return FL_ALIGN_RIGHT; +#endif +} + +/** + Sets the printf() style format string used for line numbers. + Default is "%d" for normal unpadded decimal integers. Example values: + + - "%d" -- For normal line numbers without padding (Default) + - "%03d" -- For 000 padding + - "%x" -- For hexadecimal line numbers + - "%o" -- For octal line numbers + + \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher) +*/ +void Fl_Text_Display::linenumber_format(const char* val) { +#if FLTK_ABI_VERSION >= 10303 + linenumber_format_ = val; +#else + // do nothing +#endif +} + +/** + Returns the line number printf() format string. +*/ +const char* Fl_Text_Display::linenumber_format() const { +#if FLTK_ABI_VERSION >= 10303 + return linenumber_format_; +#else + return "%d"; +#endif +} /** Attach a text buffer to display, replacing the current buffer (if any) @@ -406,6 +579,12 @@ void Fl_Text_Display::resize(int X, int Y, int W, int H) { } } + // add linenum width to the text area - LZA / STR#2621 + if (mLineNumWidth > 0) { + text_area.x += mLineNumWidth; + text_area.w -= mLineNumWidth; + } + // user request to change viewport if (mTopLineNumHint != mTopLineNum || mHorizOffsetHint != mHorizOffset) scroll_(mTopLineNumHint, mHorizOffsetHint); @@ -465,10 +644,6 @@ void Fl_Text_Display::draw_text( int left, int top, int width, int height ) { for ( line = firstLine; line <= lastLine; line++ ) draw_vline( line, left, left + width, 0, INT_MAX ); - /* draw the line numbers if exposed area includes them */ - if (mLineNumWidth != 0 && left <= mLineNumLeft + mLineNumWidth) - draw_line_numbers(false); - fl_pop_clip(); } @@ -700,7 +875,7 @@ void Fl_Text_Display::wrap_mode(int wrap, int wrapMargin) { mNBufferLines = 0; mFirstChar = 0; mTopLineNum = 1; - mAbsTopLineNum = 0; + mAbsTopLineNum = 1; // changed from 0 to 1 -- LZA / STR#2621 } resize(x(), y(), w(), h()); @@ -1514,8 +1689,10 @@ void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted, // CET - FIXME if ( origCursorPos >= startDispPos && // ( origCursorPos <= endDispPos || endDispPos == buf->length() ) ) } - - if (linesInserted > 1) textD->draw_line_numbers(false); + if (linesInserted > 1) { + // textD->draw_line_numbers(false); // can't do this b/c not called from virtual draw(); + textD->damage(::FL_DAMAGE_EXPOSE); + } } else { endDispPos = buf->next_char(textD->mLastChar); // CET - FIXME if ( origCursorPos >= pos ) @@ -1524,7 +1701,11 @@ void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted, have changed. If only one line is altered, line numbers cannot be affected (the insertion or removal of a line break always results in at least two lines being redrawn). */ - textD->draw_line_numbers(false); + + // Call draw_line_numbers() here to ensure line# is drawn + // when hitting enter for new line -- LZA / STR #2621 + //textD->draw_line_numbers(true); // no, can't call this here, not in draw() context -- ERCO / STR#2621 + //textD->damage(::FL_DAMAGE_EXPOSE); } IS_UTF8_ALIGNED2(buf, startDispPos) IS_UTF8_ALIGNED2(buf, endDispPos) @@ -1543,6 +1724,7 @@ void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted, } +/* Line Numbering Methods */ /** \brief Line numbering stuff, currently unused. @@ -2645,63 +2827,74 @@ void Fl_Text_Display::h_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) { /** \brief Refresh the line number area. - - If clearAll is False, writes only over the character cell areas. Setting - clearAll to True will clear out any stray marks outside of the character cell - area, which might have been left from before a resize or font change. - - This function is not used. + \param clearAll -- (currently unused) If False, only draws the line number text, + does not clear the area behind it. If True, clears the area + and redraws the text. Use False to avoid a 'flash' for + single buffered windows. */ + +// This draw_line_numbers() method based on patch from +// http://www.mail-archive.com/fltk-dev@easysw.com/msg06376.html +// altered to support line numbers right alignment. -LZA / STR #2621 +// void Fl_Text_Display::draw_line_numbers(bool /*clearAll*/) { -#if 0 - int y, line, visLine, nCols, lineStart; - char lineNumString[12]; - int lineHeight = mMaxsize ? mMaxsize : textsize_; - int charWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width; - - /* Don't draw if mLineNumWidth == 0 (line numbers are hidden), or widget is - not yet realized */ - if (mLineNumWidth == 0 || visible_r()) + int Y, line, visLine, lineStart; + char lineNumString[16]; + int lineHeight = mMaxsize; + + // Don't draw if lineNumWidth == 0 (line numbers are hidden), + // or widget is not yet realized + if (mLineNumWidth <= 0 || !visible_r()) return; - /* GC is allocated on demand, since not everyone will use line numbering */ - if (textD->lineNumGC == NULL) { - XGCValues values; - values.foreground = textD->lineNumFGPixel; - values.background = textD->bgPixel; - values.font = textD->fontStruct->fid; - textD->lineNumGC = XtGetGC(textD->w, - GCFont| GCForeground | GCBackground, &values); - } - - /* Erase the previous contents of the line number area, if requested */ - if (clearAll) - XClearArea(XtDisplay(textD->w), XtWindow(textD->w), textD->lineNumLeft, - textD->top, textD->lineNumWidth, textD->height, False); - - /* Draw the line numbers, aligned to the text */ - nCols = min(11, textD->lineNumWidth / charWidth); - y = textD->top; - line = getAbsTopLineNum(textD); - for (visLine=0; visLine < textD->nVisibleLines; visLine++) { - lineStart = textD->lineStarts[visLine]; - if (lineStart != -1 && (lineStart==0 || - BufGetCharacter(textD->buffer, lineStart-1)=='\n')) { - sprintf(lineNumString, "%*d", nCols, line); - XDrawImageString(XtDisplay(textD->w), XtWindow(textD->w), - textD->lineNumGC, textD->lineNumLeft, y + textD->ascent, - lineNumString, strlen(lineNumString)); - line++; - } else { - XClearArea(XtDisplay(textD->w), XtWindow(textD->w), - textD->lineNumLeft, y, textD->lineNumWidth, - textD->ascent + textD->descent, False); - if (visLine == 0) - line++; + // Make sure we reset clipping range for line number's GC; + // it may be shared (e.g. if line numbers and text have same color) + // and therefore clipping ranges may be invalid. + int xoff = Fl::box_dx(box()); + int hscroll_h = mHScrollBar->visible() ? mHScrollBar->h() : 0; + fl_push_clip(x() + xoff, + y() + Fl::box_dy(box()), + mLineNumWidth - xoff, + h() - Fl::box_dh(box()) - hscroll_h); + { + // Set background color for line number area -- LZA / STR# 2621 + // Erase background + fl_color(linenumber_bgcolor()); + fl_rectf(x(), y(), mLineNumWidth, h()); + + // Draw separator line + //fl_color(180,180,180); + //fl_line(x()+mLineNumWidth-1, y(), x()+mLineNumWidth-1, y()+h()); + + // Draw line number text + fl_font(linenumber_font(), linenumber_size()); + + Y = y(); + line = get_absolute_top_line_number(); + + int last_y = y(); + + // set font color for line numbers + fl_color(linenumber_fgcolor()); + for (visLine=0; visLine < mNVisibleLines; visLine++) { + lineStart = mLineStarts[visLine]; + if (lineStart != -1 && (lineStart==0 || buffer()->char_at(lineStart-1)=='\n')) { + sprintf(lineNumString, linenumber_format(), line); + int xx = x() + xoff + 3, + yy = Y + 3, + ww = mLineNumWidth - xoff - (3*2), + hh = lineHeight; + fl_draw(lineNumString, xx, yy, ww, hh, linenumber_align(), 0, 0); + //DEBUG fl_rect(xx, yy, ww, hh); + last_y = Y; + line++; + } else { + if (visLine == 0) line++; + } + Y += lineHeight; } - y += lineHeight; - } -#endif + } + fl_pop_clip(); } static int max( int i1, int i2 ) { @@ -3416,8 +3609,7 @@ void Fl_Text_Display::draw(void) { fl_rectf(mVScrollBar->x(), mHScrollBar->y(), mVScrollBar->w(), mHScrollBar->h(), FL_GRAY); - - // blank the previous cursor protrusions + //draw_line_numbers(true); // commented out STR# 2621 / LZA } else if (damage() & (FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)) { // printf("blanking previous cursor extrusions at Y: %d\n", mCursorOldY); @@ -3494,6 +3686,11 @@ void Fl_Text_Display::draw(void) { //printf("drew cursor at pos: %d (%d,%d)\n", mCursorPos, X, Y); fl_pop_clip(); } + + // Important to do this at end of this method, otherwise line numbers + // will not scroll with the text edit area + draw_line_numbers(true); + fl_pop_clip(); } |
