TextMetrics::checkInsetHit: do not rely on CoordCache

The required information is present in Row objects.

This is a requirement for my Next Secret Project.
This commit is contained in:
Jean-Marc Lasgouttes 2025-01-13 16:44:45 +01:00
parent 9250f5bbe6
commit a25d94c315
2 changed files with 20 additions and 25 deletions

View File

@ -1536,17 +1536,13 @@ Row const & TextMetrics::getRowNearY(int & y, pit_type pit)
// sets cursor recursively descending into nested editable insets // sets cursor recursively descending into nested editable insets
Inset * TextMetrics::editXY(Cursor & cur, int x, int y) Inset * TextMetrics::editXY(Cursor & cur, int x, int y)
{ {
if (lyxerr.debugging(Debug::WORKAREA)) {
LYXERR0("TextMetrics::editXY(cur, " << x << ", " << y << ")");
cur.bv().coordCache().dump();
}
pit_type const pit = getPitNearY(y); pit_type const pit = getPitNearY(y);
LASSERT(pit != -1, return 0); LASSERT(pit != -1, return 0);
Row const & row = getRowNearY(y, pit); Row const & row = getRowNearY(y, pit);
cur.pit() = pit; cur.pit() = pit;
// Do we cover an inset? // Do we cover an inset?
InsetList::Element * e = checkInsetHit(pit, x, y); Row::Element const * e = checkInsetHit(row, x);
if (!e) { if (!e) {
// No inset, set position in the text // No inset, set position in the text
@ -1558,7 +1554,7 @@ Inset * TextMetrics::editXY(Cursor & cur, int x, int y)
return 0; return 0;
} }
Inset * inset = e->inset; Inset * inset = const_cast<Inset *>(e->inset);
//lyxerr << "inset " << inset << " hit at x: " << x << " y: " << y << endl; //lyxerr << "inset " << inset << " hit at x: " << x << " y: " << y << endl;
// Set position in front of inset // Set position in front of inset
@ -1603,23 +1599,24 @@ void TextMetrics::setCursorFromCoordinates(Cursor & cur, int x, int y)
//takes screen x,y coordinates //takes screen x,y coordinates
InsetList::Element * TextMetrics::checkInsetHit(pit_type pit, int x, int y) Row::Element const * TextMetrics::checkInsetHit(Row const & row, int x) const
{ {
Paragraph const & par = text_->paragraphs()[pit]; int const xo = origin_.x;
CoordCache::Insets const & insetCache = bv_->coordCache().getInsets(); x -= xo;
LYXERR(Debug::PAINTING, "x: " << x << " y: " << y << " pit: " << pit); // Adapt to cursor row scroll offset if applicable.
int const offset = bv_->horizScrollOffset(text_, row.pit(), row.pos());
x += offset;
for (InsetList::Element const & e : par.insetList()) { int xx = row.left_margin;
LYXERR(Debug::PAINTING, "examining inset " << e.inset); for (auto const & e : row) {
if (xx > x)
if (insetCache.covers(e.inset, x, y)) { break;
LYXERR(Debug::PAINTING, "Hit inset: " << e.inset); if (xx + e.full_width() > x)
return const_cast<InsetList::Element *>(&e); return (e.type == Row::INSET) ? &e : nullptr;
} xx += e.full_width();
} }
LYXERR(Debug::PAINTING, "No inset hit. ");
return nullptr; return nullptr;
} }
@ -1628,13 +1625,11 @@ InsetList::Element * TextMetrics::checkInsetHit(pit_type pit, int x, int y)
Inset * TextMetrics::checkInsetHit(int x, int y) Inset * TextMetrics::checkInsetHit(int x, int y)
{ {
pit_type const pit = getPitNearY(y); pit_type const pit = getPitNearY(y);
LASSERT(pit != -1, return 0); LASSERT(pit != -1, return nullptr);
InsetList::Element * e = checkInsetHit(pit, x, y); Row const & row = getRowNearY(y, pit);
Row::Element const * e = checkInsetHit(row, x);
if (!e) return e ? const_cast<Inset *>(e->inset) : nullptr;
return 0;
return e->inset;
} }

View File

@ -184,7 +184,7 @@ private:
int parBottomSpacing(pit_type pit) const; int parBottomSpacing(pit_type pit) const;
// Helper function for the other checkInsetHit method. // Helper function for the other checkInsetHit method.
InsetList::Element * checkInsetHit(pit_type pit, int x, int y); Row::Element const * checkInsetHit(Row const & row, int x) const;
// Temporary public: // Temporary public: