This patch introduces document absolute coordinates in LyXText, and use them to solve the target_x problem (almost all operation are still done as before, but now we can possibly simplify/correct code using the absolute coordinates, in small steps).
I've also tried to fix cursorNext/Previous, and did a lot of butchering there, i.e. ended by rewriting the thing in its simplest form. [I won't apply this patch unless it gets some review (in particular I need help to know if some of the code removed was needed for some reason)] The current situation of coordinates is not much changed: - LyXText knows it own absolute coords - Events are sent to LyXText in LyXText coordinates - Paragraphs have LyXText xy coordinates - rows have Paragraph xy coordinates - Inset cache their screen coordinates (so they have absolute x coord and almost the absolute coordinates inset.y() + bv->top_y()) - insets handles events in own coordinates, and inset::edit(bv, x, y) in screen coordinates. (corrections/aditions welcomed) What this patch is supposed to cure: - target_x handling - cursorUp/Down entering/exiting insets (LFUN_FINISHED_UP/DOWN where not handled correctly) - pageUp/Down (take the userguide, press page down: scrolling gets stuck at some point) There's still the eternal problem with with full-row insets: if you have a line like this blah blah blah BUTTON ---------------------- - - - - - - |here is some text ----------------------- - - - - - and you place the cursor at the end of the blah row, it goes automatically to the next row, before BUTTON (i.e., we don't distinguish between the two positions). So say you are with the cursor in the last 't' of 'text', then you go up and the cursor goes to before the B of BUTTON with x_target set appropriately to the x coordinate of the 't'. If you try to go further up, the algorithm tries to place the cursor at the end of the last blah, and so goes again to the same position, i.e. we are stuck. Solution: we have to distinguish between the two positions, IMO. Alfredo
Index: lyxtext.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v retrieving revision 1.255 diff -u -p -u -r1.255 lyxtext.h --- lyxtext.h 17 Nov 2003 14:28:17 -0000 1.255 +++ lyxtext.h 18 Nov 2003 22:39:15 -0000 @@ -461,13 +461,14 @@ public: /// bool checkAndActivateInset(bool front); + struct Pos { + int x; + int y; + }; + Pos pos_; private: - /** Cursor related data. - Later this variable has to be removed. There should be now internal - cursor in a text */ - /// - ///TextCursor cursor_; + /// prohibit this as long as there are back pointers... LyXText(LyXText const &); Index: text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.503 diff -u -p -u -r1.503 text2.C --- text2.C 18 Nov 2003 11:39:29 -0000 1.503 +++ text2.C 18 Nov 2003 22:39:19 -0000 @@ -74,8 +74,11 @@ LyXText::LyXText(BufferView * bv, InsetT ParagraphList & paragraphs) : height(0), width(0), inset_owner(inset), bv_owner(bv), in_inset_(ininset), paragraphs_(¶graphs), - cache_pos_(-1) -{} + cache_pos_(-1) +{ + pos_.x = 0; + pos_.y = 0; +} void LyXText::init(BufferView * bview) @@ -1404,7 +1407,7 @@ void LyXText::setCursorIntern(paroffset_ pos_type pos, bool setfont, bool boundary) { setCursor(cursor, par, pos, boundary); - bv()->x_target(cursor.x()); + bv()->x_target(cursor.x() + pos_.x); if (setfont) setCurrentFont(); } @@ -1710,24 +1713,17 @@ void LyXText::cursorUp(bool selecting) { ParagraphList::iterator cpit = cursorPar(); Row const & crow = *cpit->getRow(cursor.pos()); -#if 1 - int x = bv()->x_target(); + int x = bv()->x_target() - pos_.x; int y = cursor.y() - crow.baseline() - 1; setCursorFromCoordinates(x, y); if (!selecting) { int topy = bv()->top_y(); - int y1 = cursor.y() - topy; - y -= topy; + int y1 = cursor.y() - pos_.y - topy; + y -= topy + pos_.y; InsetOld * inset_hit = checkInsetHit(x, y1); if (inset_hit && isHighlyEditableInset(inset_hit)) inset_hit->edit(bv(), x, y); } -#else - lyxerr << "cursorUp: y " << cursor.y() << " bl: " << - crow.baseline() << endl; - setCursorFromCoordinates(bv()->x_target(), - cursor.y() - crow.baseline() - 1); -#endif } @@ -1735,22 +1731,17 @@ void LyXText::cursorDown(bool selecting) { ParagraphList::iterator cpit = cursorPar(); Row const & crow = *cpit->getRow(cursor.pos()); -#if 1 - int x = bv()->x_target(); + int x = bv()->x_target() - pos_.x; int y = cursor.y() - crow.baseline() + crow.height() + 1; setCursorFromCoordinates(x, y); if (!selecting) { int topy = bv()->top_y(); - int y1 = cursor.y() - topy; - y -= topy; + int y1 = cursor.y() - pos_.y - topy; + y -= topy + pos_.y; InsetOld * inset_hit = checkInsetHit(x, y1); if (inset_hit && isHighlyEditableInset(inset_hit)) inset_hit->edit(bv(), x, y); } -#else - setCursorFromCoordinates(bv()->x_target(), - cursor.y() - crow.baseline() + crow.height() + 1); -#endif } Index: text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.183 diff -u -p -u -r1.183 text3.C --- text3.C 18 Nov 2003 11:39:30 -0000 1.183 +++ text3.C 18 Nov 2003 22:39:21 -0000 @@ -362,43 +362,21 @@ void LyXText::gotoInset(InsetOld::Code c void LyXText::cursorPrevious() { - int y = bv()->top_y(); + int y = bv()->top_y() - pos_.y; ParagraphList::iterator cpit = cursorPar(); RowList::iterator crit = cpit->getRow(cursor.pos()); - if (isFirstRow(cpit, *crit)) { - if (y > 0) - bv()->updateScrollbar(); - return; - } - - setCursorFromCoordinates(bv()->x_target(), y); - finishUndo(); + setCursorFromCoordinates(bv()->x_target() - pos_.x, y); - if (crit == bv()->text->cursorRow()) { + if (crit == cursorRow()) { // we have a row which is taller than the workarea. The // simplest solution is to move to the previous row instead. cursorUp(true); - return; - } - - int new_y = + crit->height() - bv()->workHeight() + 1; - - if (inset_owner) { - new_y += bv()->text->cursor.y() - + bv()->cursor().innerInset()->insetInInsetY() - + y; - } else { - new_y += cursor.y() - crit->baseline(); } - previousRow(cpit, crit); - LyXCursor cur; - setCursor(cur, parOffset(cpit), crit->pos(), false); - if (cur.y() > bv()->top_y()) - cursorUp(true); bv()->updateScrollbar(); + finishUndo(); } @@ -409,56 +387,18 @@ void LyXText::cursorNext() ParagraphList::iterator cpit = cursorPar(); RowList::iterator crit = cpit->getRow(cursor.pos()); - if (isLastRow(cpit, *crit)) { - int y = cursor.y() - crit->baseline() + crit->height(); - if (y > topy + bv()->workHeight()) - bv()->updateScrollbar(); - return; - } - - int y = topy + bv()->workHeight(); - if (inset_owner && !topy) { - y += - bv()->text->cursor.y() - + bv()->top_y() - - bv()->cursor().innerInset()->insetInInsetY(); - } - - ParagraphList::iterator dummypit; - Row const & row = *getRowNearY(y, dummypit); - y = dummypit->y + row.y_offset(); + int y = topy + bv()->workHeight() - pos_.y; - setCursorFromCoordinates(bv()->x_target(), y); - // + bv->workHeight()); - finishUndo(); + setCursorFromCoordinates(bv()->x_target() - pos_.x, y); - int new_y; - if (crit == bv()->text->cursorRow()) { + if (crit == cursorRow()) { // we have a row which is taller than the workarea. The // simplest solution is to move to the next row instead. cursorDown(true); - return; - // This is what we used to do, so we wouldn't skip right past - // tall rows, but it's not working right now. -#if 0 - new_y = bv->top_y() + bv->workHeight(); -#endif - } - - if (inset_owner) { - new_y = bv()->text->cursor.y() - + bv()->cursor().innerInset()->insetInInsetY() - + y - crit->baseline(); - } else { - new_y = cursor.y() - crit->baseline(); } - - - nextRow(cpit, crit); - LyXCursor cur; - setCursor(cur, parOffset(cpit), crit->pos(), false); - if (cur.y() < bv()->top_y() + bv()->workHeight()) - cursorDown(true); + bv()->updateScrollbar(); + finishUndo(); } @@ -1355,7 +1295,7 @@ DispatchResult LyXText::dispatch(FuncReq setCursorFromCoordinates(cmd.x, cmd.y); selection.cursor = cursor; finishUndo(); - bv->x_target(cursor.x()); + bv->x_target(cursor.x() + pos_.x); if (bv->fitCursor()) selection_possible = false; @@ -1596,11 +1536,12 @@ DispatchResult LyXText::dispatch(FuncReq case LFUN_FINISHED_UP: lyxerr << "swallow LFUN_FINISHED_UP" << endl; + cursorUp(true); break; case LFUN_FINISHED_DOWN: lyxerr << "swallow LFUN_FINISHED_DOWN" << endl; - cursorRight(true); + cursorDown(true); break; default: Index: insets/insetcollapsable.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v retrieving revision 1.209 diff -u -p -u -r1.209 insetcollapsable.C --- insets/insetcollapsable.C 17 Nov 2003 20:28:10 -0000 1.209 +++ insets/insetcollapsable.C 18 Nov 2003 22:39:24 -0000 @@ -283,6 +283,7 @@ void InsetCollapsable::edit(BufferView * else inset.edit(bv, x, ascent() + y - height_collapsed() + inset.ascent()); } + bv->cursor().push(this); } Index: insets/insettext.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v retrieving revision 1.546 diff -u -p -u -r1.546 insettext.C --- insets/insettext.C 17 Nov 2003 20:28:10 -0000 1.546 +++ insets/insettext.C 18 Nov 2003 22:39:28 -0000 @@ -257,6 +257,9 @@ void InsetText::draw(PainterInfo & pi, i x += TEXT_TO_INSET_OFFSET; + text_.pos_.x = x; + text_.pos_.y = y + bv->top_y(); + paintTextInset(*bv, text_, x, y); if (drawFrame_ == ALWAYS || drawFrame_ == LOCKED) @@ -340,10 +343,8 @@ void InsetText::edit(BufferView * bv, in lyxerr << "InsetText::edit xy" << endl; old_par = -1; sanitizeEmptyText(bv); - text_.setCursorFromCoordinates(x, y + dim_.asc); - text_.cursor.x(text_.cursor.x()); - bv->x_target(text_.cursor.x()); - + text_.setCursorFromCoordinates(x - text_.pos_.x, y + bv->top_y() + - text_.pos_.y); text_.clearSelection(); finishUndo();