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
{
for (idx_type i = 0; i < nargs(); ++i)

View File

@ -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);

View File

@ -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);
}

View File

@ -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

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)
{
if (d->displayMode_ != mode) {

View File

@ -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

View File

@ -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)