From d2ad9ae6e2db76c1cbb92f0f069aa0f2fdcbcc31 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 22 Feb 2017 10:43:48 +0100 Subject: [PATCH] Rewrite selection code in mathed Now the selection is not done by the inset, but by the MathData itself. This allows for some code simplification and avoids an extra redraw. Additionally, this fixes the selection inside macros, which was broken by the new MathRow code. --- src/mathed/InsetMathNest.cpp | 48 ------------------------------------ src/mathed/InsetMathNest.h | 4 +-- src/mathed/MathData.cpp | 36 +++++++++++++++++++++++++++ src/mathed/MathData.h | 2 ++ src/mathed/MathMacro.cpp | 8 ------ src/mathed/MathMacro.h | 2 -- src/mathed/MathRow.cpp | 7 +++--- 7 files changed, 43 insertions(+), 64 deletions(-) diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 484e0ed56e..1f0adda504 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -277,54 +277,6 @@ void InsetMathNest::draw(PainterInfo &, int, int) const } -void InsetMathNest::drawSelection(PainterInfo & pi, int x, int y) const -{ - BufferView & bv = *pi.base.bv; - // this should use the x/y values given, not the cached values - Cursor & cur = bv.cursor(); - if (!cur.selection()) - return; - if (&cur.inset() != this) - return; - - // FIXME: hack to get position cache warm - bool const original_drawing_state = pi.pain.isDrawingEnabled(); - pi.pain.setDrawingEnabled(false); - draw(pi, x, y); - pi.pain.setDrawingEnabled(original_drawing_state); - - CursorSlice s1 = cur.selBegin(); - CursorSlice s2 = cur.selEnd(); - - //lyxerr << "InsetMathNest::drawing selection: " - // << " s1: " << s1 << " s2: " << s2 << endl; - if (s1.idx() == s2.idx()) { - MathData const & c = cell(s1.idx()); - Geometry const & g = bv.coordCache().getArrays().geometry(&c); - int x1 = g.pos.x_ + c.pos2x(pi.base.bv, s1.pos()); - int y1 = g.pos.y_ - g.dim.ascent(); - int x2 = g.pos.x_ + c.pos2x(pi.base.bv, s2.pos()); - int y2 = g.pos.y_ + g.dim.descent(); - pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, Color_selection); - //lyxerr << "InsetMathNest::drawing selection 3: " - // << " x1: " << x1 << " x2: " << x2 - // << " y1: " << y1 << " y2: " << y2 << endl; - } else { - for (idx_type i = 0; i < nargs(); ++i) { - if (idxBetween(i, s1.idx(), s2.idx())) { - MathData const & c = cell(i); - Geometry const & g = bv.coordCache().getArrays().geometry(&c); - int x1 = g.pos.x_; - int y1 = g.pos.y_ - g.dim.ascent(); - int x2 = g.pos.x_ + g.dim.width(); - int y2 = g.pos.y_ + g.dim.descent(); - pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, Color_selection); - } - } - } -} - - void InsetMathNest::validate(LaTeXFeatures & features) const { for (idx_type i = 0; i < nargs(); ++i) diff --git a/src/mathed/InsetMathNest.h b/src/mathed/InsetMathNest.h index f1cfdd8beb..51670a2c64 100644 --- a/src/mathed/InsetMathNest.h +++ b/src/mathed/InsetMathNest.h @@ -37,8 +37,6 @@ public: void cellsMetrics(MetricsInfo const & mi) const; /// draw background if locked void draw(PainterInfo & pi, int x, int y) const; - /// draw selection background - void drawSelection(PainterInfo & pi, int x, int y) const; /// void updateBuffer(ParIterator const &, UpdateType); /// identifies NestInsets @@ -49,7 +47,7 @@ public: void cursorPos(BufferView const & bv, CursorSlice const & sl, bool boundary, int & x, int & y) const; /// - void edit(Cursor & cur, bool front, + void edit(Cursor & cur, bool front, EntryDirection entry_from = ENTRY_DIRECTION_IGNORE); /// Inset * editXY(Cursor & cur, int x, int y); diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp index dcf9647b2e..322a8e9ceb 100644 --- a/src/mathed/MathData.cpp +++ b/src/mathed/MathData.cpp @@ -31,6 +31,7 @@ #include "mathed/InsetMathUnknown.h" #include "frontends/FontMetrics.h" +#include "frontends/Painter.h" #include "support/debug.h" #include "support/docstream.h" @@ -285,6 +286,40 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const } +void MathData::drawSelection(PainterInfo & pi, int const x, int const y) const +{ + BufferView const * bv = pi.base.bv; + Cursor const & cur = bv->cursor(); + InsetMath const * inset = cur.inset().asInsetMath(); + if (!cur.selection() || !inset || inset->nargs() == 0) + return; + + CursorSlice const s1 = cur.selBegin(); + CursorSlice const s2 = cur.selEnd(); + MathData const & c1 = inset->cell(s1.idx()); + + if (s1.idx() == s2.idx() && &c1 == this) { + // selection indide cell + Dimension const dim = bv->coordCache().getArrays().dim(&c1); + int const beg = c1.pos2x(bv, s1.pos()); + int const end = c1.pos2x(bv, s2.pos()); + pi.pain.fillRectangle(x + beg, y - dim.ascent(), + end - beg, dim.height(), Color_selection); + } else { + for (idx_type i = 0; i < inset->nargs(); ++i) { + MathData const & c = inset->cell(i); + if (&c == this && inset->idxBetween(i, s1.idx(), s2.idx())) { + // The whole cell is selected + Dimension const dim = bv->coordCache().getArrays().dim(&c); + pi.pain.fillRectangle(x, y - dim.ascent(), + dim.width(), dim.height(), + Color_selection); + } + } + } +} + + void MathData::draw(PainterInfo & pi, int const x, int const y) const { //lyxerr << "MathData::draw: x: " << x << " y: " << y << endl; @@ -300,6 +335,7 @@ void MathData::draw(PainterInfo & pi, int const x, int const y) const || x >= bv. workWidth()) return; + drawSelection(pi, x, y); MathRow const & mrow = mrow_cache_[pi.base.bv]; mrow.draw(pi, x, y); } diff --git a/src/mathed/MathData.h b/src/mathed/MathData.h index 1d2617c8dd..ed85c78977 100644 --- a/src/mathed/MathData.h +++ b/src/mathed/MathData.h @@ -129,6 +129,8 @@ public: /// Dimension const & dimension(BufferView const &) const; + /// draw the selection over the cell + void drawSelection(PainterInfo & pi, int x, int y) const; /// redraw cell using cache metrics information void draw(PainterInfo & pi, int x, int y) const; /// rebuild cached metrics information diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp index 4f478d0995..8b86dc6422 100644 --- a/src/mathed/MathMacro.cpp +++ b/src/mathed/MathMacro.cpp @@ -802,14 +802,6 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const } -void MathMacro::drawSelection(PainterInfo & pi, int x, int y) const -{ - // We may have 0 arguments, but InsetMathNest requires at least one. - if (!cells_.empty()) - InsetMathNest::drawSelection(pi, x, y); -} - - void MathMacro::setDisplayMode(MathMacro::DisplayMode mode, int appetite) { if (d->displayMode_ != mode) { diff --git a/src/mathed/MathMacro.h b/src/mathed/MathMacro.h index f1e61dcb4c..5392754969 100644 --- a/src/mathed/MathMacro.h +++ b/src/mathed/MathMacro.h @@ -56,8 +56,6 @@ public: bool editMetrics(BufferView const * bv) const; /// void draw(PainterInfo & pi, int x, int y) const; - /// draw selection background - void drawSelection(PainterInfo & pi, int x, int y) const; /// int kerning(BufferView const * bv) const; /// get cursor position diff --git a/src/mathed/MathRow.cpp b/src/mathed/MathRow.cpp index e046add470..c3c9a1c934 100644 --- a/src/mathed/MathRow.cpp +++ b/src/mathed/MathRow.cpp @@ -278,7 +278,6 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const Dimension d2 = d; d2.wid -= e.before + e.after; coords.insets().add(e.inset, d2); - e.inset->drawSelection(pi, x + e.before, y); e.inset->draw(pi, x + e.before, y); coords.insets().add(e.inset, x, y); coords.insets().add(e.inset, d); @@ -287,14 +286,16 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const break; } case BEGIN: + if (e.ar) { + coords.arrays().add(e.ar, x, y); + e.ar->drawSelection(pi, x, y); + } if (e.inset) { coords.insets().add(e.inset, x, y); drawMarkers(pi, e, x, y); e.inset->beforeDraw(pi); } x += e.before + e.after; - if (e.ar) - coords.arrays().add(e.ar, x, y); break; case END: if (e.inset)