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.
This commit is contained in:
Jean-Marc Lasgouttes 2017-02-22 10:43:48 +01:00
parent 05b90abaf7
commit d2ad9ae6e2
7 changed files with 43 additions and 64 deletions

View File

@ -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 void InsetMathNest::validate(LaTeXFeatures & features) const
{ {
for (idx_type i = 0; i < nargs(); ++i) for (idx_type i = 0; i < nargs(); ++i)

View File

@ -37,8 +37,6 @@ public:
void cellsMetrics(MetricsInfo const & mi) const; void cellsMetrics(MetricsInfo const & mi) const;
/// draw background if locked /// draw background if locked
void draw(PainterInfo & pi, int x, int y) const; 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); void updateBuffer(ParIterator const &, UpdateType);
/// identifies NestInsets /// identifies NestInsets

View File

@ -31,6 +31,7 @@
#include "mathed/InsetMathUnknown.h" #include "mathed/InsetMathUnknown.h"
#include "frontends/FontMetrics.h" #include "frontends/FontMetrics.h"
#include "frontends/Painter.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/docstream.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 void MathData::draw(PainterInfo & pi, int const x, int const y) const
{ {
//lyxerr << "MathData::draw: x: " << x << " y: " << y << endl; //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()) || x >= bv. workWidth())
return; return;
drawSelection(pi, x, y);
MathRow const & mrow = mrow_cache_[pi.base.bv]; MathRow const & mrow = mrow_cache_[pi.base.bv];
mrow.draw(pi, x, y); mrow.draw(pi, x, y);
} }

View File

@ -129,6 +129,8 @@ public:
/// ///
Dimension const & dimension(BufferView const &) const; 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 /// redraw cell using cache metrics information
void draw(PainterInfo & pi, int x, int y) const; void draw(PainterInfo & pi, int x, int y) const;
/// rebuild cached metrics information /// rebuild cached metrics information

View File

@ -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) void MathMacro::setDisplayMode(MathMacro::DisplayMode mode, int appetite)
{ {
if (d->displayMode_ != mode) { if (d->displayMode_ != mode) {

View File

@ -56,8 +56,6 @@ public:
bool editMetrics(BufferView const * bv) const; bool editMetrics(BufferView const * bv) const;
/// ///
void draw(PainterInfo & pi, int x, int y) 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; int kerning(BufferView const * bv) const;
/// get cursor position /// get cursor position

View File

@ -278,7 +278,6 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const
Dimension d2 = d; Dimension d2 = d;
d2.wid -= e.before + e.after; d2.wid -= e.before + e.after;
coords.insets().add(e.inset, d2); coords.insets().add(e.inset, d2);
e.inset->drawSelection(pi, x + e.before, y);
e.inset->draw(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, x, y);
coords.insets().add(e.inset, d); coords.insets().add(e.inset, d);
@ -287,14 +286,16 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const
break; break;
} }
case BEGIN: case BEGIN:
if (e.ar) {
coords.arrays().add(e.ar, x, y);
e.ar->drawSelection(pi, x, y);
}
if (e.inset) { if (e.inset) {
coords.insets().add(e.inset, x, y); coords.insets().add(e.inset, x, y);
drawMarkers(pi, e, x, y); drawMarkers(pi, e, x, y);
e.inset->beforeDraw(pi); e.inset->beforeDraw(pi);
} }
x += e.before + e.after; x += e.before + e.after;
if (e.ar)
coords.arrays().add(e.ar, x, y);
break; break;
case END: case END:
if (e.inset) if (e.inset)