diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2005-08-10 23:11:51 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2005-08-10 23:11:51 +0000 |
| commit | af39242da6b5aa97ecbe4d197b1698906b347689 (patch) | |
| tree | 7eb9988aec5fd55d73653d25e2980e7e5ea42642 | |
| parent | 7410f80a844d0a4fdd4bc423bc792d3acb28a152 (diff) | |
Fl_Text_Display now auto-scrolls in all directions (STR #915). This is implemented using a timer event. The scroll speed is proportional to the distance of the cursor to the text area
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4502 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | FL/Fl_Text_Display.H | 2 | ||||
| -rw-r--r-- | src/Fl_Text_Display.cxx | 90 |
3 files changed, 86 insertions, 8 deletions
@@ -3,6 +3,8 @@ CHANGES IN FLTK 1.1.7 - Documentation fixes (STR #571, STR #648, STR #692, STR #730, STR #744, STR #745, STR #931, STR #942, STR #960, STR #969) + - Fl_Text_Display now auto-scrolls in all + directions (STR #915) - Borderless windows will not show in the taskbar anymore on X11 (STR #933) - Fixed event_text() field on FL_DND_* event on diff --git a/FL/Fl_Text_Display.H b/FL/Fl_Text_Display.H index 84e937b60..7e94ef001 100644 --- a/FL/Fl_Text_Display.H +++ b/FL/Fl_Text_Display.H @@ -166,6 +166,8 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group { int position_to_line( int pos, int* lineNum ); int string_width(const char* string, int length, int style); + static void scroll_timer_cb(void*); + 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, diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx index 2b9e56fd6..a4b020f26 100644 --- a/src/Fl_Text_Display.cxx +++ b/src/Fl_Text_Display.cxx @@ -66,6 +66,13 @@ static int max( int i1, int i2 ); static int min( int i1, int i2 ); static int countlines( const char *string ); +/* The variables below are used in a timer event to allow smooth + scrolling of the text area when the pointer has left the area. */ +static int scroll_direction = 0; +static int scroll_amount = 0; +static int scroll_y = 0; +static int scroll_x = 0; + // CET - FIXME #define TMPFONTWIDTH 6 @@ -147,6 +154,10 @@ Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l) ** freed, nor are the style buffer or style table. */ Fl_Text_Display::~Fl_Text_Display() { + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } if (mBuffer) { mBuffer->remove_modify_callback(buffer_modified_cb, this); mBuffer->remove_predelete_callback(buffer_predelete_cb, this); @@ -3031,6 +3042,37 @@ void fl_text_drag_me(int pos, Fl_Text_Display* d) { } } +// This timer event scrolls the text view proportionally to +// how far the mouse pointer has left the text area. This +// allows for smooth scrolling without "wiggeling" the mouse. +void Fl_Text_Display::scroll_timer_cb(void *user_data) { + Fl_Text_Display *w = (Fl_Text_Display*)user_data; + int pos; + switch (scroll_direction) { + case 1: // mouse is to the right, scroll left + w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount); + pos = w->xy_to_position(w->text_area.x + w->text_area.w, scroll_y, CURSOR_POS); + break; + case 2: // mouse is to the left, scroll right + w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount); + pos = w->xy_to_position(w->text_area.x, scroll_y, CURSOR_POS); + break; + case 3: // mouse is above, scroll down + w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset); + pos = w->xy_to_position(scroll_x, w->text_area.y, CURSOR_POS); + break; + case 4: // mouse is below, scroll up + w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset); + pos = w->xy_to_position(scroll_x, w->text_area.y + w->text_area.h, CURSOR_POS); + break; + default: + return; + } + fl_text_drag_me(pos, w); + Fl::repeat_timeout(.1, scroll_timer_cb, user_data); +} + + int Fl_Text_Display::handle(int event) { if (!buffer()) return 0; // This isn't very elegant! @@ -3089,21 +3131,53 @@ int Fl_Text_Display::handle(int event) { case FL_DRAG: { if (dragType < 0) return 1; int X = Fl::event_x(), Y = Fl::event_y(), pos; + // if we leave the text_area, we start a timer event + // that will take care of scrolling and selecting if (Y < text_area.y) { - move_up(); - scroll(mTopLineNum - 1, mHorizOffset); - pos = insert_position(); + scroll_x = X; + scroll_amount = (Y - text_area.y) / 5 - 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 3; } else if (Y >= text_area.y+text_area.h) { - move_down(); - scroll(mTopLineNum + 1, mHorizOffset); - pos = insert_position(); - } else pos = xy_to_position(X, Y, CURSOR_POS); - fl_text_drag_me(pos, this); + scroll_x = X; + scroll_amount = (Y - text_area.y - text_area.h) / 5 + 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 4; + } else if (X < text_area.x) { + scroll_y = Y; + scroll_amount = (X - text_area.x) / 2 - 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 2; + } else if (X >= text_area.x+text_area.w) { + scroll_y = Y; + scroll_amount = (X - text_area.x - text_area.w) / 2 + 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 1; + } else { + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } + pos = xy_to_position(X, Y, CURSOR_POS); + fl_text_drag_me(pos, this); + } return 1; } case FL_RELEASE: { dragging = 0; + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } // convert from WORD or LINE selection to CHAR if (insert_position() >= dragPos) |
