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
This commit is contained in:
parent
7410f80a84
commit
af39242da6
2
CHANGES
2
CHANGES
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user