From 02ebc072b039aa001d0e18293eca596b41b4338c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Sat, 14 Aug 2004 14:03:42 +0000 Subject: [PATCH] remove per-inset position cahce, use new external map instead. this allows us to bomb early on uninitialized cache values. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8923 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView_pimpl.C | 11 +++++++++-- src/ChangeLog | 10 ++++++++++ src/Makefile.am | 2 ++ src/frontends/xforms/XWorkArea.C | 5 +++++ src/insets/ChangeLog | 6 ++++++ src/insets/inset.C | 10 ++++------ src/insets/inset.h | 8 -------- src/insets/insetbase.C | 16 +++++++++++++++- src/insets/insetbase.h | 4 ++-- src/insets/insettabular.C | 13 +++++++------ src/insets/updatableinset.C | 3 +++ src/lyxfunc.C | 11 ++++++++++- src/mathed/math_data.C | 30 ++++++++++++++++++++++-------- src/mathed/math_data.h | 12 ++++-------- src/mathed/math_decorationinset.C | 6 +++++- src/mathed/math_diminset.C | 5 ++--- src/mathed/math_diminset.h | 8 -------- src/mathed/math_factory.C | 2 +- src/mathed/math_nestinset.C | 5 ++++- src/mathed/math_parser.C | 3 ++- src/mathed/math_splitinset.C | 2 ++ src/rowpainter.C | 2 ++ src/text.C | 1 + src/text3.C | 13 +++++++++---- 24 files changed, 127 insertions(+), 61 deletions(-) diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 1fdc75a779..d80723d200 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -23,6 +23,7 @@ #include "buffer_funcs.h" #include "bufferlist.h" #include "bufferparams.h" +#include "coordcache.h" #include "cursor.h" #include "debug.h" #include "dispatchresult.h" @@ -602,7 +603,13 @@ void BufferView::Pimpl::update() // and the scrollbar updateScrollbar(); } + + // remove old position cache + theCoords.clear(); + + // The real, big redraw. screen().redraw(*bv_); + bv_->owner()->view_state_changed(); } @@ -835,8 +842,8 @@ void BufferView::Pimpl::trackChanges() bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0) { - //lyxerr << "BufferView::Pimpl::workAreaDispatch: request: " - // << cmd << std::endl; + lyxerr << "BufferView::Pimpl::workAreaDispatch: request: " + << cmd0 << std::endl; // this is only called for mouse related events including // LFUN_FILE_OPEN generated by drag-and-drop. FuncRequest cmd = cmd0; diff --git a/src/ChangeLog b/src/ChangeLog index 80c5d889b4..29a0121abf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2004-08-14 André Pönitz + + * coordcache.[Ch]: + * Makefile.am: new files to accomodate an 'external' (x,y)-position + cache for all insets in (at least partially) visible (top-level) + paragraphs. + + * BufferView_pimpl.C: reset external coord cache before every update. + This means the coord cache only contains valid entries. + 2004-08-14 Lars Gullik Bjonnes bug 1096 diff --git a/src/Makefile.am b/src/Makefile.am index 6eaad4b0c3..7a9aa96eec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -134,6 +134,8 @@ lyx_SOURCES = \ converter.h \ counters.C \ counters.h \ + coordcache.C \ + coordcache.h \ cursor.C \ cursor.h \ cursor_slice.C \ diff --git a/src/frontends/xforms/XWorkArea.C b/src/frontends/xforms/XWorkArea.C index 949e3ea897..bf2e367925 100644 --- a/src/frontends/xforms/XWorkArea.C +++ b/src/frontends/xforms/XWorkArea.C @@ -293,6 +293,9 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event, FL_Coord, FL_Coord, int key, void * xev) { + if (event != 11) + lyxerr[Debug::WORKAREA] << "Workarea event: EVENT: " << event << endl; + XEvent * ev = static_cast(xev); XWorkArea * area = static_cast(ob->u_vdata); @@ -385,6 +388,8 @@ int XWorkArea::work_area_handler(FL_OBJECT * ob, int event, break; case FL_DRAG: { + lyxerr[Debug::WORKAREA] << "Workarea event: DRAG 0" << endl; + if (!ev || !area->scrollbar) break; diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index 6916fdfec2..33d652f1b6 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,9 @@ + +2004-08-14 André Pönitz + + * inset.[Ch]: + * insetbase.[Ch]: remove the 'internale' xo, yo position cache + 2004-08-13 Jean-Marc Lasgouttes * insetoptarg.C (latexOptional): if the optional argument contains diff --git a/src/insets/inset.C b/src/insets/inset.C index 37b73dd634..0f8bbc739e 100644 --- a/src/insets/inset.C +++ b/src/insets/inset.C @@ -22,21 +22,20 @@ #include "lyxtext.h" #include "LColor.h" #include "metricsinfo.h" +#include "coordcache.h" using std::string; InsetOld::InsetOld() - : InsetBase(), - xo_(0), yo_(0), scx(0), + : scx(0), //background_color_(LColor::inherit) background_color_(LColor::background) {} InsetOld::InsetOld(InsetOld const & in) - : InsetBase(), - xo_(0), yo_(0), scx(0), name_(in.name_), + : InsetBase(in), scx(0), name_(in.name_), background_color_(in.background_color_) {} @@ -86,6 +85,5 @@ int InsetOld::scroll(bool) const void InsetOld::setPosCache(PainterInfo const & pi, int x, int y) const { //lyxerr << "InsetOld:: position cache to " << x << " " << y << std::endl; - xo_ = x; - yo_ = y + pi.base.bv->top_y(); + theCoords.insets_.add(this, x, y + pi.base.bv->top_y()); } diff --git a/src/insets/inset.h b/src/insets/inset.h index fe3d22ac39..ece7a34e29 100644 --- a/src/insets/inset.h +++ b/src/insets/inset.h @@ -52,20 +52,12 @@ public: LColor_color backgroundColor() const; /// set x/y drawing position cache void setPosCache(PainterInfo const &, int, int) const; - /// - int xo() const { return xo_; } - /// - int yo() const { return yo_; } /// returns the actual scroll-value virtual int scroll(bool recursive = true) const; /// bool forceDefaultParagraphs(InsetBase const * inset) const; protected: - /// - mutable int xo_; - /// - mutable int yo_; /// mutable int scx; /// diff --git a/src/insets/insetbase.C b/src/insets/insetbase.C index abfeeb8ca7..f40b4d52a7 100644 --- a/src/insets/insetbase.C +++ b/src/insets/insetbase.C @@ -13,6 +13,7 @@ #include "insetbase.h" #include "buffer.h" +#include "coordcache.h" #include "BufferView.h" #include "LColor.h" #include "cursor.h" @@ -287,6 +288,18 @@ bool InsetBase::editing(BufferView * bv) const } +int InsetBase::xo() const +{ + return theCoords.insets_.x(this); +} + + +int InsetBase::yo() const +{ + return theCoords.insets_.y(this); +} + + bool InsetBase::covers(int x, int y) const { //lyxerr << "InsetBase::covers, x: " << x << " y: " << y @@ -294,7 +307,8 @@ bool InsetBase::covers(int x, int y) const // << " x1: " << xo() << " x2: " << xo() + width() // << " y1: " << yo() - ascent() << " y2: " << yo() + descent() // << std::endl; - return x >= xo() + return theCoords.insets_.has(this) + && x >= xo() && x <= xo() + width() && y >= yo() - ascent() && y <= yo() + descent(); diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index 1287b5a74a..0109473402 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -98,9 +98,9 @@ public: /// add space for markers void metricsMarkers2(Dimension & dim, int framesize = 1) const; /// last drawn position for 'important' insets - virtual int xo() const { return 0; } + int xo() const; /// last drawn position for 'important' insets - virtual int yo() const { return 0; } + int yo() const; /// set x/y drawing position cache if available virtual void setPosCache(PainterInfo const &, int, int) const {} /// do we cover screen position x/y? diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 08693477ef..140e1cf279 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -387,8 +387,9 @@ void InsetTabular::edit(LCursor & cur, bool left) cell = tabular.getNumberOfCells() - 1; } cur.selection() = false; - resetPos(cur); - cur.bv().fitCursor(); + // this accesses the position cache before it is initialized + //resetPos(cur); + //cur.bv().fitCursor(); cur.push(*this); cur.idx() = cell; } @@ -400,7 +401,7 @@ InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y) const cur.selection() = false; cur.push(const_cast(*this)); return setPos(cur, x, y); - //int xx = cursorx_ - xo_ + tabular.getBeginningOfTextInCell(actcell); + //int xx = cursorx_ - xo() + tabular.getBeginningOfTextInCell(actcell); } @@ -987,7 +988,7 @@ int InsetTabular::getCellXPos(int cell) const for (; c < cell; ++c) lx += tabular.getWidthOfColumn(c); - return lx - tabular.getWidthOfColumn(cell) + xo_; + return lx - tabular.getWidthOfColumn(cell) + xo(); } @@ -1012,8 +1013,8 @@ void InsetTabular::resetPos(LCursor & cur) const scroll(bv, - tabular.getWidthOfColumn(actcell) - 20); } else if (cursorx_ - offset < 20) { scroll(bv, 20 - cursorx_ + offset); - } else if (scroll() && xo_ > 20 && - xo_ + tabular.getWidthOfTabular() > bv.workWidth() - 20) { + } else if (scroll() && xo() > 20 && + xo() + tabular.getWidthOfTabular() > bv.workWidth() - 20) { scroll(bv, old_x - cursorx_); } diff --git a/src/insets/updatableinset.C b/src/insets/updatableinset.C index 1e9aea7d14..4ba16bc046 100644 --- a/src/insets/updatableinset.C +++ b/src/insets/updatableinset.C @@ -16,6 +16,7 @@ #include "updatableinset.h" #include "BufferView.h" +#include "coordcache.h" #include "cursor.h" #include "debug.h" #include "dispatchresult.h" @@ -46,6 +47,7 @@ void UpdatableInset::scroll(BufferView & bv, float s) const } int const workW = bv.workWidth(); + int xo_ = theCoords.insets_.x(this); int const tmp_xo_ = xo_ - scx; if (tmp_xo_ > 0 && tmp_xo_ + width() < workW) @@ -65,6 +67,7 @@ void UpdatableInset::scroll(BufferView & bv, float s) const void UpdatableInset::scroll(BufferView & bv, int offset) const { + int const xo_ = theCoords.insets_.x(this); if (offset > 0) { if (!scx && xo_ >= 20) return; diff --git a/src/lyxfunc.C b/src/lyxfunc.C index f4fac34f66..2103bdb197 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -1433,7 +1433,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose) } if (view()->available()) { - if (view()->fitCursor() || update) + // Redraw screen unless explicitly told otherwise. + // This also initializes the position cache for all insets + // in (at least partially) visible top-level paragraphs. + if (update) + view()->update(); + + // fitCursor() needs valid inset position. The previous call to + // update() makes sure we have such even for freshly created + // insets. + if (view()->fitCursor()) view()->update(); // if we executed a mutating lfun, mark the buffer as dirty if (getStatus(cmd).enabled() diff --git a/src/mathed/math_data.C b/src/mathed/math_data.C index 8a97e3e53a..b8f44dea08 100644 --- a/src/mathed/math_data.C +++ b/src/mathed/math_data.C @@ -19,6 +19,7 @@ #include "math_support.h" #include "math_replace.h" +#include "coordcache.h" #include "LColor.h" #include "BufferView.h" #include "buffer.h" @@ -38,12 +39,11 @@ using std::vector; MathArray::MathArray() - : xo_(0), yo_(0) {} MathArray::MathArray(const_iterator from, const_iterator to) - : base_type(from, to), xo_(0), yo_(0) + : base_type(from, to) {} @@ -276,8 +276,7 @@ void MathArray::metrics(MetricsInfo & mi) const void MathArray::draw(PainterInfo & pi, int x, int y) const { //lyxerr << "MathArray::draw: x: " << x << " y: " << y << endl; - xo_ = x; - yo_ = y; + setXY(x, y); if (empty()) { pi.pain.rectangle(x, y - ascent(), width(), height(), LColor::mathline); @@ -332,8 +331,7 @@ void MathArray::metricsT(TextMetricsInfo const & mi, Dimension & dim) const void MathArray::drawT(TextPainter & pain, int x, int y) const { //lyxerr << "x: " << x << " y: " << y << ' ' << pain.workAreaHeight() << endl; - xo_ = x; - yo_ = y; + setXY(x, y); for (const_iterator it = begin(), et = end(); it != et; ++it) { (*it)->drawT(pain, x, y); @@ -393,6 +391,9 @@ int MathArray::dist(int x, int y) const int xx = 0; int yy = 0; + const int xo_ = xo(); + const int yo_ = yo(); + if (x < xo_) xx = xo_ - x; else if (x > xo_ + width()) @@ -409,6 +410,19 @@ int MathArray::dist(int x, int y) const void MathArray::setXY(int x, int y) const { - xo_ = x; - yo_ = y; + lyxerr << "setting position cache for MathArray " << this << std::endl; + theCoords.arrays_.add(this, x, y); +} + + +int MathArray::xo() const +{ + return theCoords.arrays_.x(this); } + + +int MathArray::yo() const +{ + return theCoords.arrays_.y(this); +} + diff --git a/src/mathed/math_data.h b/src/mathed/math_data.h index 7e774d2850..1720ba4423 100644 --- a/src/mathed/math_data.h +++ b/src/mathed/math_data.h @@ -112,13 +112,13 @@ public: void touch() const; /// access to cached x coordinate of last drawing - int xo() const { return xo_; } + int xo() const; /// access to cached y coordinate of last drawing - int yo() const { return yo_; } + int yo() const; /// access to cached x coordinate of mid point of last drawing - int xm() const { return xo_ + dim_.wid / 2; } + int xm() const { return xo() + dim_.wid / 2; } /// access to cached y coordinate of mid point of last drawing - int ym() const { return yo_ + (dim_.des - dim_.asc) / 2; } + int ym() const { return yo() + (dim_.des - dim_.asc) / 2; } /// write access to coordinate; void setXY(int x, int y) const; /// returns x coordinate of given position in the array @@ -152,10 +152,6 @@ private: /// cached dimensions of cell mutable Dimension dim_; - /// cached x coordinate of last drawing - mutable int xo_; - /// cached y coordinate of last drawing - mutable int yo_; }; /// diff --git a/src/mathed/math_decorationinset.C b/src/mathed/math_decorationinset.C index 2b1d87cadb..3f24a73e05 100644 --- a/src/mathed/math_decorationinset.C +++ b/src/mathed/math_decorationinset.C @@ -18,6 +18,8 @@ #include "math_mathmlstream.h" #include "math_streamstr.h" +#include "debug.h" + #include "support/std_ostream.h" using std::auto_ptr; @@ -25,7 +27,9 @@ using std::auto_ptr; MathDecorationInset::MathDecorationInset(latexkeys const * key) : MathNestInset(1), key_(key) -{} +{ + lyxerr << " creating deco " << key->name << std::endl; +} auto_ptr MathDecorationInset::clone() const diff --git a/src/mathed/math_diminset.C b/src/mathed/math_diminset.C index e2e898cfa3..00a1befa17 100644 --- a/src/mathed/math_diminset.C +++ b/src/mathed/math_diminset.C @@ -11,11 +11,11 @@ #include #include "math_diminset.h" +#include "coordcache.h" #include "debug.h" MathDimInset::MathDimInset() - : xo_(-3), yo_(-3) // some sentinel value for debugging {} @@ -40,6 +40,5 @@ int MathDimInset::width() const void MathDimInset::setPosCache(PainterInfo const &, int x, int y) const { //lyxerr << "MathDimInset: cache to " << x << " " << y << std::endl; - xo_ = x; - yo_ = y; + theCoords.insets_.add(this, x, y); } diff --git a/src/mathed/math_diminset.h b/src/mathed/math_diminset.h index f0b206b2d7..3294e8f12e 100644 --- a/src/mathed/math_diminset.h +++ b/src/mathed/math_diminset.h @@ -33,20 +33,12 @@ public: /// int width() const; - /// - int xo() const { return xo_; } - /// - int yo() const { return yo_; } /// void setPosCache(PainterInfo const & pi, int x, int y) const; protected: /// mutable Dimension dim_; - /// - mutable int xo_; - /// - mutable int yo_; }; #endif diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index 039a7947a2..5ed3010ee4 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -286,7 +286,7 @@ MathAtom createMathInset(string const & s) return MathAtom(new MathKernInset); if (s == "xrightarrow" || s == "xleftarrow") return MathAtom(new MathXArrowInset(s)); - if (s == "split" || s == "gathered" || s == "aligned") + if (s == "split" || s == "gathered" || s == "aligned" || s == "alignedat") return MathAtom(new MathSplitInset(s)); if (s == "cases") return MathAtom(new MathCasesInset); diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 3306b06384..2d1596bbff 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -196,8 +196,11 @@ void MathNestInset::draw(PainterInfo & pi, int x, int y) const } -void MathNestInset::drawSelection(PainterInfo & pi, int, int) const +void MathNestInset::drawSelection(PainterInfo & pi, int x, int y) const { + // FIXME: hack to get position cache warm + draw(pi, x, y); + // this should use the x/y values given, not the cached values LCursor & cur = pi.base.bv->cursor(); if (!cur.selection()) diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index cd2bf6ba90..3fe2e5c331 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -985,7 +985,8 @@ void Parser::parse1(MathGridInset & grid, unsigned flags, } else if (name == "split" || name == "cases" || - name == "gathered" || name == "aligned") { + name == "gathered" || name == "aligned" || + name == "alignedat") { cell->push_back(createMathInset(name)); parse2(cell->back(), FLAG_END, mode, false); } diff --git a/src/mathed/math_splitinset.C b/src/mathed/math_splitinset.C index 83a9caf3b3..90388dbd38 100644 --- a/src/mathed/math_splitinset.C +++ b/src/mathed/math_splitinset.C @@ -41,6 +41,8 @@ char MathSplitInset::defaultColAlign(col_type col) return 'c'; if (name_ == "aligned") return (col & 1) ? 'l' : 'r'; + if (name_ == "alignedat") + return (col & 1) ? 'l' : 'r'; return 'l'; } diff --git a/src/rowpainter.C b/src/rowpainter.C index 6bdae7a813..56fd368fe4 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -14,6 +14,7 @@ #include "rowpainter.h" #include "buffer.h" +#include "coordcache.h" #include "cursor.h" #include "debug.h" #include "bufferparams.h" @@ -200,6 +201,7 @@ void RowPainter::paintInset(pos_type const pos) BOOST_ASSERT(inset); PainterInfo pi(const_cast(&bv_), pain_); pi.base.font = getFont(pos); + theCoords.insets_.add(inset, int(x_), yo_ + row_.baseline()); inset->drawSelection(pi, int(x_), yo_ + row_.baseline()); inset->draw(pi, int(x_), yo_ + row_.baseline()); x_ += inset->width(); diff --git a/src/text.C b/src/text.C index d5bbf53c3a..6c6c06b303 100644 --- a/src/text.C +++ b/src/text.C @@ -2143,6 +2143,7 @@ string LyXText::getPossibleLabel(LCursor & cur) const } +// Manhattan distance to nearest corner int LyXText::dist(int x, int y) const { int xx = 0; diff --git a/src/text3.C b/src/text3.C index a185e9d0a6..adf27cfc27 100644 --- a/src/text3.C +++ b/src/text3.C @@ -23,6 +23,7 @@ #include "bufferparams.h" #include "BufferView.h" #include "cursor.h" +#include "coordcache.h" #include "CutAndPaste.h" #include "debug.h" #include "dispatchresult.h" @@ -203,10 +204,14 @@ InsetBase * LyXText::checkInsetHit(int x, int y) const for (; iit != iend; ++iit) { InsetBase * inset = iit->inset; #if 1 - lyxerr << "examining inset " << inset - << " xo: " << inset->xo() << "..." << inset->xo() + inset->width() - << " yo: " << inset->yo() - inset->ascent() << "..." - << inset->yo() + inset->descent() << endl; + lyxerr << "examining inset " << inset << endl; + if (theCoords.insets_.has(inset)) + lyxerr + << " xo: " << inset->xo() << "..." << inset->xo() + inset->width() + << " yo: " << inset->yo() - inset->ascent() << "..." + << inset->yo() + inset->descent() << endl; + else + lyxerr << " inset has no cached position"; #endif if (inset->covers(x, y)) { lyxerr << "Hit inset: " << inset << endl; -- 2.39.2