I've played a bit with coordinates this morning, and tried to bring LyX again to a working state (coord-wise). I think it can be a good starting point to choose a right coordinate scheme.
currently is: - LyXFunc::dispatch uses screen coords (ok) - BufferView::Pimpl::workAreaDispatch receives screen coords and translates inmediately to absolute coords, before dispatching to insets::dispatch or lyxtext::dispatch. (ok) - internal methods from LyXText use a mixture of absolute x,y coords, LyXText-relative x,y coords, and relative-y but absolute-x. (not so good. I'd try to declare private whatever doesn't takes absolute coords. I think storing relative info is ok as long as it is private.) - inset::dispatch and lyxtext::dispatch take absolute coords (ok) - the cached x,y position in insets is screen-relative (bad) Current detected issues (with the patch) - the cursor doesnt enter an inset by opening it, but jumps to the position it was. There's currently no LCursor::push in insetcollapsable::priv_dispatch. - There are some draw-related crashes somewhere: scroll down with the scrollbar in the UG, open an inset (the screen jumps back to the top), then try to visit the inset -> crash. InsetText::draw was requested but the LyXText doesn't have rows or something. Doesn't seem to happend if you go there with the cursor, so the screen doesn't jump back. Alfredo PS: I'd not apply the patch yet, I'll play a bit more today and/or tomorrow.
? PosIterator.C-save ? PosIterator.h-save ? bfri.C ? text3-save.C ? textcursor.C-save ? textcursor.h-save ? insets/insetcollapsable-save.C ? insets/insettext-save.C Index: text.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v retrieving revision 1.530 diff -u -p -u -r1.530 text.C --- text.C 3 Feb 2004 08:56:23 -0000 1.530 +++ text.C 5 Feb 2004 11:26:02 -0000 @@ -1414,9 +1414,12 @@ ParagraphList::iterator LyXText::getPar( } +// y is relative to this LyXText's top RowList::iterator LyXText::getRowNearY(int y, ParagraphList::iterator & pit) const { + BOOST_ASSERT(!paragraphs().empty()); + BOOST_ASSERT(!paragraphs().begin()->rows.empty()); #if 1 ParagraphList::iterator const pend = boost::prior(paragraphs().end()); Index: text2.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v retrieving revision 1.539 diff -u -p -u -r1.539 text2.C --- text2.C 4 Feb 2004 11:23:23 -0000 1.539 +++ text2.C 5 Feb 2004 11:26:04 -0000 @@ -1207,7 +1207,7 @@ void LyXText::setCurrentFont() } } - +// x is an absolute screen coord // returns the column near the specified x-coordinate of the row // x is set to the real beginning of this column pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, @@ -1327,7 +1327,8 @@ void LyXText::setCursorFromCoordinates(C ParagraphList::iterator pit; Row const & row = *getRowNearY(y, pit); bool bound = false; - pos_type const pos = row.pos() + getColumnNearX(pit, row, x, bound); + int xx = x + xo_; // getRowNearX get absolute x coords + pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound); cur.par() = parOffset(pit); cur.pos() = pos; cur.boundary() = bound; @@ -1337,10 +1338,11 @@ void LyXText::setCursorFromCoordinates(C // x,y are absolute screen coordinates void LyXText::edit(LCursor & cur, int x, int y) { - int xx = x; // is modified by getColumnNearX ParagraphList::iterator pit; - Row const & row = *getRowNearY(y, pit); + Row const & row = *getRowNearY(y - yo_, pit); bool bound = false; + + int xx = x; // is modified by getColumnNearX pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound); cur.par() = parOffset(pit); cur.pos() = pos; @@ -1349,11 +1351,12 @@ void LyXText::edit(LCursor & cur, int x, // try to descend into nested insets InsetBase * inset = checkInsetHit(x, y); if (inset) { - // This should be just before or just behind the cursor position - // set above. + // This should be just before or just behind the + // cursor position set above. BOOST_ASSERT((pos != 0 && inset == pit->getInset(pos - 1)) || inset == pit->getInset(pos)); - // Make sure the cursor points to the position before this inset. + // Make sure the cursor points to the position before + // this inset. if (inset == pit->getInset(pos - 1)) --cur.pos(); inset->edit(cur, x, y); Index: text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.216 diff -u -p -u -r1.216 text3.C --- text3.C 4 Feb 2004 11:23:24 -0000 1.216 +++ text3.C 5 Feb 2004 11:26:06 -0000 @@ -246,6 +246,7 @@ string const freefont2string() } +//takes absolute x,y coordinates InsetBase * LyXText::checkInsetHit(int x, int y) { ParagraphList::iterator pit; @@ -1228,7 +1229,8 @@ DispatchResult LyXText::dispatch(LCursor break; } - setCursorFromCoordinates(cur.current(), cmd.x, cmd.y); + setCursorFromCoordinates(cur.current(), cmd.x - xo_, + cmd.y - yo_); cur.resetAnchor(); finishUndo(); cur.x_target() = cursorX(cur.current()); Index: insets/insetcollapsable.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insetcollapsable.C,v retrieving revision 1.232 diff -u -p -u -r1.232 insetcollapsable.C --- insets/insetcollapsable.C 4 Feb 2004 09:14:27 -0000 1.232 +++ insets/insetcollapsable.C 5 Feb 2004 11:26:09 -0000 @@ -211,15 +211,17 @@ InsetCollapsable::lfunMouseRelease(LCurs edit(cur, true); return DispatchResult(true, true); - case Open: - if (hitButton(cmd)) { + case Open: { + FuncRequest cmd1 = cmd; + cmd1.y -= cur.bv().top_y(); + if (hitButton(cmd1)) { lyxerr << "InsetCollapsable::lfunMouseRelease 2" << endl; setStatus(Collapsed); return DispatchResult(false, FINISHED_RIGHT); } lyxerr << "InsetCollapsable::lfunMouseRelease 3" << endl; return inset.dispatch(cur, cmd); - + } case Inlined: return inset.dispatch(cur, cmd); } @@ -306,8 +308,8 @@ void InsetCollapsable::edit(LCursor & cu } else { if (y <= button_dim.y2) y = 0; - else - y += inset.ascent() - height_collapsed(); +// else +// y += inset.ascent() - height_collapsed(); inset.edit(cur, x, y); } @@ -323,14 +325,16 @@ InsetCollapsable::priv_dispatch(LCursor case LFUN_MOUSE_PRESS: if (status_ == Inlined) inset.dispatch(cur, cmd); - else if (status_ == Open && cmd.y > button_dim.y2) + else if (status_ == Open + && cmd.y - cur.bv().top_y() > button_dim.y2) inset.dispatch(cur, cmd); return DispatchResult(true, true); case LFUN_MOUSE_MOTION: if (status_ == Inlined) inset.dispatch(cur, cmd); - else if (status_ == Open && cmd.y > button_dim.y2) + else if (status_ == Open + && cmd.y - cur.bv().top_y() > button_dim.y2) inset.dispatch(cur, cmd); return DispatchResult(true, true); Index: insets/insettext.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v retrieving revision 1.573 diff -u -p -u -r1.573 insettext.C --- insets/insettext.C 4 Feb 2004 09:14:27 -0000 1.573 +++ insets/insettext.C 5 Feb 2004 11:26:09 -0000 @@ -191,6 +191,7 @@ void InsetText::metrics(MetricsInfo & mi void InsetText::draw(PainterInfo & pi, int x, int y) const { + BOOST_ASSERT(!text_.paragraphs().begin()->rows.empty()); // update our idea of where we are setPosCache(pi, x, y); @@ -275,9 +276,6 @@ void InsetText::sanitizeEmptyText(Buffer text_.setFont(font, false); } } - - -extern CursorBase theTempCursor; void InsetText::edit(LCursor & cur, bool left)