I'd like some of you to take a look at this and try it out. I am not about its size, and it is not as clean as I would have liked.
But it seems to work fairly great. (on xforms) I have not tested on qt.
Index: src/BufferView.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v retrieving revision 1.114 diff -u -p -r1.114 BufferView.C --- src/BufferView.C 5 Jan 2003 22:38:41 -0000 1.114 +++ src/BufferView.C 19 Jan 2003 16:23:12 -0000 @@ -124,6 +124,12 @@ bool BufferView::fitCursor() } +bool BufferView::fitCursorJust() +{ + return pimpl_->fitCursorJust(); +} + + void BufferView::update() { pimpl_->update(); Index: src/BufferView.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.h,v retrieving revision 1.113 diff -u -p -r1.113 BufferView.h --- src/BufferView.h 5 Jan 2003 22:38:41 -0000 1.113 +++ src/BufferView.h 19 Jan 2003 16:23:12 -0000 @@ -84,6 +84,9 @@ public: /// fit the user cursor within the visible view bool fitCursor(); + /// scroll as little as possible to fit the cursor within the + /// visible view. + bool fitCursorJust(); /// perform pending painting updates void update(); // update for a particular lyxtext Index: src/BufferView_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v retrieving revision 1.321 diff -u -p -r1.321 BufferView_pimpl.C --- src/BufferView_pimpl.C 27 Nov 2002 10:30:03 -0000 1.321 +++ src/BufferView_pimpl.C 19 Jan 2003 16:23:13 -0000 @@ -238,6 +238,23 @@ bool BufferView::Pimpl::fitCursor() } +bool BufferView::Pimpl::fitCursorJust() +{ + bool ret; + + if (bv_->theLockingInset()) { + bv_->theLockingInset()->fitInsetCursor(bv_); + ret = true; + } else { + ret = screen().fitCursorJust(bv_->text, bv_); + } + + bv_->owner()->getDialogs().updateParagraph(); + if (ret) + updateScrollbar(); + return ret; +} + void BufferView::Pimpl::redoCurrentBuffer() { lyxerr[Debug::INFO] << "BufferView::redoCurrentBuffer" << endl; Index: src/BufferView_pimpl.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.h,v retrieving revision 1.81 diff -u -p -r1.81 BufferView_pimpl.h --- src/BufferView_pimpl.h 21 Oct 2002 00:15:48 -0000 1.81 +++ src/BufferView_pimpl.h 19 Jan 2003 16:23:14 -0000 @@ -41,6 +41,7 @@ struct BufferView::Pimpl : public boost: void buffer(Buffer *); /// Return true if the cursor was fitted. bool fitCursor(); + bool fitCursorJust(); /// void redoCurrentBuffer(); /// Index: src/text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.29 diff -u -p -r1.29 text3.C --- src/text3.C 17 Jan 2003 09:57:50 -0000 1.29 +++ src/text3.C 19 Jan 2003 16:23:15 -0000 @@ -380,7 +380,7 @@ void doInsertInset(LyXText * lt, FuncReq { Inset * inset = createInset(cmd); BufferView * bv = cmd.view(); - + if (inset) { bool gotsel = false; if (lt->selection.set()) { @@ -1315,23 +1315,13 @@ Inset::RESULT LyXText::dispatch(FuncRequ bv->screen().hideCursor(); - Row * cursorrow = bv->text->cursor.row(); - bv->text->setCursorFromCoordinates(bv, cmd.x, cmd.y + bv->text->first_y); - #if 0 - // sorry for this but I have a strange error that the y value jumps at - // a certain point. This seems like an error in my xforms library or - // in some other local environment, but I would like to leave this here - // for the moment until I can remove this (Jug 20020418) - if (y_before < bv->text->cursor.y()) - lyxerr << y_before << ':' - << bv->text->cursor.y() << endl; - #endif - // This is to allow jumping over large insets - if (cursorrow == bv->text->cursor.row()) { - if (cmd.y >= int(bv->workHeight())) - bv->text->cursorDown(bv, false); - else if (cmd.y < 0) - bv->text->cursorUp(bv, false); + if (cmd.y >= int(bv->workHeight())) { + bv->text->cursorDown(bv, false); + } else if (cmd.y < 0) { + bv->text->cursorUp(bv, false); + } else { + + bv->text->setCursorFromCoordinates(bv, cmd.x, cmd.y + bv->text->first_y); } // Maybe an empty line was deleted @@ -1339,7 +1329,7 @@ Inset::RESULT LyXText::dispatch(FuncRequ bv->update(bv->text, BufferView::UPDATE); bv->text->setSelection(bv); bv->screen().toggleToggle(bv->text, bv); - bv->fitCursor(); + bv->fitCursorJust(); bv->showCursor(); break; } Index: src/frontends/screen.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/screen.C,v retrieving revision 1.25 diff -u -p -r1.25 screen.C --- src/frontends/screen.C 12 Jan 2003 19:35:40 -0000 1.25 +++ src/frontends/screen.C 19 Jan 2003 16:23:15 -0000 @@ -226,6 +226,30 @@ unsigned int LyXScreen::topCursorVisible } +unsigned int LyXScreen::topCursorVisibleJust(LyXCursor const & cursor, int top_y) +{ + int const vheight = workarea().workHeight(); + int newtop = top_y; + + Row * row = cursor.row(); + + // Is this a hack? Yes, probably... (Lgb) + if (!row) + return max(newtop, 0); + + if (cursor.y() - row->baseline() + row->height() - top_y >= vheight) { + newtop = cursor.y() + + row->height() + - row->baseline() - vheight; + } else if (static_cast<int>((cursor.y()) - row->baseline()) < + top_y && top_y > 0) { + newtop = cursor.y() - row->baseline(); + } + + return max(newtop, 0);; +} + + bool LyXScreen::fitCursor(LyXText * text, BufferView * bv) { // Is a change necessary? @@ -238,6 +262,18 @@ bool LyXScreen::fitCursor(LyXText * text return result; } + +bool LyXScreen::fitCursorJust(LyXText * text, BufferView * bv) +{ + // Is a change necessary? + int const newtop = topCursorVisibleJust(text->cursor, text->first_y); + bool const result = (newtop != text->first_y); + if (result) { + draw(text, bv, newtop); + } + + return result; +} void LyXScreen::update(LyXText * text, BufferView * bv, int yo, int xo) Index: src/frontends/screen.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/screen.h,v retrieving revision 1.10 diff -u -p -r1.10 screen.h --- src/frontends/screen.h 1 Dec 2002 22:59:18 -0000 1.10 +++ src/frontends/screen.h 19 Jan 2003 16:23:15 -0000 @@ -105,6 +105,7 @@ public: * within the LyXText is "nicely" visible. */ virtual unsigned int topCursorVisible(LyXCursor const & c, int top_y); + virtual unsigned int topCursorVisibleJust(LyXCursor const & c, int top_y); /** * fitCursor - fit the cursor onto the work area @@ -115,6 +116,7 @@ public: * Scrolls the screen so that the cursor is visible */ virtual bool fitCursor(LyXText *, BufferView *); + virtual bool fitCursorJust(LyXText *, BufferView *); /// show the cursor if it's not, and vice versa virtual void cursorToggle(BufferView *) const; Index: src/frontends/xforms/XWorkArea.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/XWorkArea.C,v retrieving revision 1.31 diff -u -p -r1.31 XWorkArea.C --- src/frontends/xforms/XWorkArea.C 16 Dec 2002 11:38:21 -0000 1.31 +++ src/frontends/xforms/XWorkArea.C 19 Jan 2003 16:23:15 -0000 @@ -265,7 +265,7 @@ void XWorkArea::scroll_cb() waitForX(false); } - + int XWorkArea::work_area_handler(FL_OBJECT * ob, int event, FL_Coord, FL_Coord, int key, void * xev) @@ -309,18 +309,22 @@ int XWorkArea::work_area_handler(FL_OBJE int const drag_x = ev->xmotion.x; int const drag_y = ev->xmotion.y; - int const area_y = ob->y; - int const area_h = ob->h; + int const area_y_top = ob->y + 10; + int const area_h = ob->h - 10; + int const area_y_bot = area_y_top + area_h; + + bool const above = (drag_y < area_y_top); + bool const below = (drag_y > area_y_bot); // Check if the mouse is above or below the workarea - if (drag_y <= area_y || drag_y >= area_y + area_h) { + if (above || below) { // The mouse button is depressed and we are outside the // workarea. That means we are simultaneously selecting // text and scrolling the view. // Use a Timeout to react to a drag events only every // 200ms. All intervening events are discarded, // allowing the user to control position easily. - static int const discard_interval = 200; + static int const discard_interval = 100; static Timeout timeout(discard_interval); if (timeout.running()) @@ -339,7 +343,7 @@ int XWorkArea::work_area_handler(FL_OBJE fl_get_scrollbar_value(area->scrollbar); if (drag_x != x_old || drag_y != y_old || - scrollbar_value != scrollbar_value_old) { + scrollbar_value != scrollbar_value_old ) { x_old = drag_x; y_old = drag_y; scrollbar_value_old = scrollbar_value; @@ -359,9 +363,13 @@ int XWorkArea::work_area_handler(FL_OBJE // rather than ev->xbutton.button. // Angus 15 Oct 2002. + + int const new_pos_x = drag_x - ob->x; + int const new_pos_y = drag_y - area_y_top; + FuncRequest cmd(LFUN_MOUSE_MOTION, - ev->xbutton.x - ob->x, - ev->xbutton.y - ob->y, + new_pos_x, + new_pos_y, x_button_state(key)); area->dispatch(cmd); }
-- Lgb