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();
 }
 

Reply via email to