The following patch seems to provide a smoother Cursor/Page up/down than we currently have.
As it is fairly intrusive (over 100 lines removed) I would not mind if someone else had a look. The "big change" is to let 'setCursorFromCoordinates' descent into insets. The necessary code was already present in the handler for LFUN_DOWN, but not used by e.g. LFUN_NEXT. So apart from removing code that I did not understand this is basically "putting things where they belong". Bonus: It even works with things like adjacent note insets (which it di not before) and -- my favourite -- the cursor is now shown on the correct position in front of a displayed formula. And it make yesterday's quick'n'dirty hack unnecessary. Andre' -- Those who desire to give up Freedom in order to gain Security, will not have, nor do they deserve, either one. (T. Jefferson)
Index: lyxtext.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v retrieving revision 1.129 diff -u -p -r1.129 lyxtext.h --- lyxtext.h 21 Oct 2002 16:21:53 -0000 1.129 +++ lyxtext.h 27 Nov 2002 12:43:43 -0000 @@ -315,10 +315,11 @@ public: LyXFont const & font) const; /// - void setCursorFromCoordinates(BufferView *, int x, int y) const; + void setCursorFromCoordinates(BufferView *, + int x, int y, bool selecting = false) const; /// void setCursorFromCoordinates(BufferView *, LyXCursor &, - int x, int y) const; + int x, int y, bool selecting = false) const; /// void cursorUp(BufferView *, bool selecting = false) const; /// Index: text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.266 diff -u -p -r1.266 text2.C --- text2.C 27 Nov 2002 10:30:18 -0000 1.266 +++ text2.C 27 Nov 2002 12:43:43 -0000 @@ -1959,11 +1959,12 @@ void LyXText::setCurrentFont(BufferView } -void LyXText::setCursorFromCoordinates(BufferView * bview, int x, int y) const +void LyXText::setCursorFromCoordinates + (BufferView * bview, int x, int y, bool selecting) const { LyXCursor old_cursor = cursor; - setCursorFromCoordinates(bview, cursor, x, y); + setCursorFromCoordinates(bview, cursor, x, y, selecting); setCurrentFont(bview); deleteEmptyParagraphMechanism(bview, old_cursor); } @@ -1994,31 +1995,38 @@ namespace { void LyXText::setCursorFromCoordinates(BufferView * bview, LyXCursor & cur, - int x, int y) const + const int x, const int y, bool selecting) const { - // Get the row first. + int xx = x; + int yy = y; - Row * row = getRowNearY(y); + // Get the row first. + Row * row = getRowNearY(yy); bool bound = false; - pos_type const column = getColumnNearX(bview, row, x, bound); + pos_type const column = getColumnNearX(bview, row, xx, bound); cur.par(row->par()); cur.pos(row->pos() + column); - cur.x(x); - cur.y(y + row->baseline()); + cur.x(xx); + cur.y(yy + row->baseline()); cur.row(row); + cur.iy(cur.y()); + cur.ix(cur.x()); + cur.irow(row); + cur.boundary(bound); - if (beforeFullRowInset(*row, cur)) { - pos_type last = rowLastPrintable(row); - float x = getCursorX(bview, row->next(), cur.pos(), last, bound); - cur.ix(int(x)); - cur.iy(y + row->height() + row->next()->baseline()); - cur.irow(row->next()); - } else { - cur.iy(cur.y()); - cur.ix(cur.x()); - cur.irow(row); + //lyxerr << "x: " << x << " cx: " << cursor.x() << " " + // << "y: " << y << " cy: " << cursor.y() << endl; + + if (!selecting) { + Inset * inset = getInset(); + if (inset && isEditableInset(inset)) { + //lyxerr << "x: " << x << " ix: " << inset->x() << " cx: " + // << cursor.x() << " xx: " << xx << " " + // << "y: " << y << " iy: " << inset->y() << " cy: " + // << cursor.y() << " yy: " << yy << endl; + inset->edit(bview, x - xx, y - yy, mouse_button::none); + } } - cur.boundary(bound); } @@ -2054,47 +2062,18 @@ void LyXText::cursorRight(BufferView * b void LyXText::cursorUp(BufferView * bview, bool selecting) const { -#if 1 int x = cursor.x_fix(); int y = cursor.y() - cursor.row()->baseline() - 1; - setCursorFromCoordinates(bview, x, y); - if (!selecting) { - int y1 = cursor.iy() - first_y; - int y2 = y1; - y -= first_y; - Inset * inset_hit = checkInsetHit(bview, x, y1); - if (inset_hit && isHighlyEditableInset(inset_hit)) { - inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none); - } - } -#else - setCursorFromCoordinates(bview, cursor.x_fix(), - cursor.y() - cursor.row()->baseline() - 1); -#endif + setCursorFromCoordinates(bview, x, y, selecting); } void LyXText::cursorDown(BufferView * bview, bool selecting) const { -#if 1 int x = cursor.x_fix(); int y = cursor.y() - cursor.row()->baseline() + cursor.row()->height() + 1; - setCursorFromCoordinates(bview, x, y); - if (!selecting && cursor.row() == cursor.irow()) { - int y1 = cursor.iy() - first_y; - int y2 = y1; - y -= first_y; - Inset * inset_hit = checkInsetHit(bview, x, y1); - if (inset_hit && isHighlyEditableInset(inset_hit)) { - inset_hit->edit(bview, x, y - (y2 - y1), mouse_button::none); - } - } -#else - setCursorFromCoordinates(bview, cursor.x_fix(), - cursor.y() - cursor.row()->baseline() - + cursor.row()->height() + 1); -#endif + setCursorFromCoordinates(bview, x, y, selecting); } Index: text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.27 diff -u -p -r1.27 text3.C --- text3.C 27 Nov 2002 10:30:22 -0000 1.27 +++ text3.C 27 Nov 2002 12:43:43 -0000 @@ -241,108 +241,18 @@ void LyXText::gotoInset(BufferView * bv, void LyXText::cursorPrevious(BufferView * bv) { - if (!cursor.row()->previous()) { - if (first_y > 0) { - int new_y = bv->text->first_y - bv->workHeight(); - bv->screen().draw(bv->text, bv, new_y < 0 ? 0 : new_y); - bv->updateScrollbar(); - } - return; - } - - int y = first_y; - Row * cursorrow = cursor.row(); - + int y = cursor.y() - bv->workHeight() / 2; setCursorFromCoordinates(bv, cursor.x_fix(), y); - finishUndo(); - - int new_y; - if (cursorrow == bv->text->cursor.row()) { - // we have a row which is higher than the workarea so we leave the - // cursor on the start of the row and move only the draw up as soon - // as we move the cursor or do something while inside the row (it may - // span several workarea-heights) we'll move to the top again, but this - // is better than just jump down and only display part of the row. - new_y = bv->text->first_y - bv->workHeight(); - } else { - if (inset_owner) { - new_y = bv->text->cursor.iy() - + bv->theLockingInset()->insetInInsetY() + y - + cursor.row()->height() - - bv->workHeight() + 1; - } else { - new_y = cursor.y() - - cursor.row()->baseline() - + cursor.row()->height() - - bv->workHeight() + 1; - } - } - bv->screen().draw(bv->text, bv, new_y < 0 ? 0 : new_y); - if (cursor.row()->previous()) { - LyXCursor cur; - setCursor(bv, cur, cursor.row()->previous()->par(), - cursor.row()->previous()->pos(), false); - if (cur.y() > first_y) { - cursorUp(bv, true); - } - } + bv->screen().draw(bv->text, bv, 0); bv->updateScrollbar(); } void LyXText::cursorNext(BufferView * bv) { - if (!cursor.row()->next()) { - int y = cursor.y() - cursor.row()->baseline() + - cursor.row()->height(); - if (y > int(first_y + bv->workHeight())) { - bv->screen().draw(bv->text, bv, - bv->text->first_y + bv->workHeight()); - bv->updateScrollbar(); - } - return; - } - - int y = first_y + bv->workHeight(); - if (inset_owner && !first_y) { - y -= (bv->text->cursor.iy() - - bv->text->first_y - + bv->theLockingInset()->insetInInsetY()); - } - - getRowNearY(y); - - Row * cursorrow = cursor.row(); + int y = cursor.y() + bv->workHeight() / 2; setCursorFromCoordinates(bv, cursor.x_fix(), y); - // + bv->workHeight()); - finishUndo(); - - int new_y; - if (cursorrow == bv->text->cursor.row()) { - // we have a row which is higher than the workarea so we leave the - // cursor on the start of the row and move only the draw down as soon - // as we move the cursor or do something while inside the row (it may - // span several workarea-heights) we'll move to the top again, but this - // is better than just jump down and only display part of the row. - new_y = bv->text->first_y + bv->workHeight(); - } else { - if (inset_owner) { - new_y = bv->text->cursor.iy() - + bv->theLockingInset()->insetInInsetY() - + y - cursor.row()->baseline(); - } else { - new_y = cursor.y() - cursor.row()->baseline(); - } - } - bv->screen().draw(bv->text, bv, new_y); - if (cursor.row()->next()) { - LyXCursor cur; - setCursor(bv, cur, cursor.row()->next()->par(), - cursor.row()->next()->pos(), false); - if (cur.y() < int(first_y + bv->workHeight())) { - cursorDown(bv, true); - } - } + bv->screen().draw(bv->text, bv, 0); bv->updateScrollbar(); }