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_(&paragraphs),
-		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();
 

Reply via email to