diff --git a/src/insets/Inset.h b/src/insets/Inset.h index b8fd6377d7..5d7f27f89f 100644 --- a/src/insets/Inset.h +++ b/src/insets/Inset.h @@ -201,8 +201,6 @@ public: /// virtual bool showInsetDialog(BufferView *) const; - // The possible marker types for insets - enum marker_type { NO_MARKER, MARKER2, MARKER }; /// draw two angular markers void drawMarkers(PainterInfo & pi, int x, int y) const; /// draw four angular markers diff --git a/src/mathed/CommandInset.h b/src/mathed/CommandInset.h index 68d0d13c53..b820d72602 100644 --- a/src/mathed/CommandInset.h +++ b/src/mathed/CommandInset.h @@ -28,7 +28,7 @@ public: explicit CommandInset(Buffer * buf, docstring const & name, bool needs_math_mode = true); /// - marker_type marker() const { return NO_MARKER; } + marker_type marker(BufferView const *) const { return NO_MARKER; } /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// diff --git a/src/mathed/InsetMath.cpp b/src/mathed/InsetMath.cpp index e3b46b9e5c..441cc7cfd5 100644 --- a/src/mathed/InsetMath.cpp +++ b/src/mathed/InsetMath.cpp @@ -58,7 +58,7 @@ MathClass InsetMath::mathClass() const } -InsetMath::marker_type InsetMath::marker() const +InsetMath::marker_type InsetMath::marker(BufferView const *) const { return nargs() > 0 ? MARKER : NO_MARKER; } @@ -68,7 +68,7 @@ bool InsetMath::addToMathRow(MathRow & mrow, MetricsInfo & mi) const { MathRow::Element e(mi, MathRow::INSET, mathClass()); e.inset = this; - e.marker = mi.base.macro_nesting ? NO_MARKER : marker(); + e.marker = mi.base.macro_nesting ? NO_MARKER : marker(mi.base.bv); mrow.push_back(e); return true; } diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h index 2fc4c1ddf6..81cad09b48 100644 --- a/src/mathed/InsetMath.h +++ b/src/mathed/InsetMath.h @@ -114,8 +114,10 @@ public: /// this is overridden by specific insets virtual mode_type currentMode() const { return MATH_MODE; } + // The possible marker types for math insets + enum marker_type { NO_MARKER, MARKER2, MARKER, BOX_MARKER }; /// this is overridden by insets with specific edit marker type - virtual marker_type marker() const; + virtual marker_type marker(BufferView const *) const; /// the ascent of the inset above the baseline /// compute the size of the object for text based drawing diff --git a/src/mathed/InsetMathBox.h b/src/mathed/InsetMathBox.h index e898a35920..af166c19c7 100644 --- a/src/mathed/InsetMathBox.h +++ b/src/mathed/InsetMathBox.h @@ -58,7 +58,7 @@ public: /// mode_type currentMode() const { return TEXT_MODE; } /// - marker_type marker() const { return NO_MARKER; } + marker_type marker(BufferView const *) const { return NO_MARKER; } /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// @@ -118,7 +118,7 @@ public: /// InsetMathBoxed(Buffer * buf); /// - marker_type marker() const { return NO_MARKER; } + marker_type marker(BufferView const *) const { return NO_MARKER; } /// void validate(LaTeXFeatures & features) const; /// diff --git a/src/mathed/InsetMathDelim.h b/src/mathed/InsetMathDelim.h index bc49ce3c59..69242d50a7 100644 --- a/src/mathed/InsetMathDelim.h +++ b/src/mathed/InsetMathDelim.h @@ -33,7 +33,7 @@ public: /// MathClass mathClass() const { return MC_INNER; } /// - marker_type marker() const { return NO_MARKER; } + marker_type marker(BufferView const *) const { return NO_MARKER; } /// is it (...)? bool isParenthesis() const; /// is it [...]? diff --git a/src/mathed/InsetMathFrac.h b/src/mathed/InsetMathFrac.h index b43180c416..f82f3b43cd 100644 --- a/src/mathed/InsetMathFrac.h +++ b/src/mathed/InsetMathFrac.h @@ -125,7 +125,7 @@ public: /// Generalized fractions are of inner class (see The TeXbook, p.292) MathClass mathClass() const { return MC_INNER; } /// - marker_type marker() const { return MARKER2; } + marker_type marker(BufferView const *) const { return MARKER2; } /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp index 60ef524b0e..d6522ab3a3 100644 --- a/src/mathed/MathData.cpp +++ b/src/mathed/MathData.cpp @@ -277,8 +277,8 @@ void MathData::metrics(MetricsInfo & mi, Dimension & dim) const sshift_ = xascent / 4; MathRow mrow(mi, this); - mrow_cache_[mi.base.bv] = mrow; mrow.metrics(mi, dim); + mrow_cache_[mi.base.bv] = mrow; kerning_ = mrow.kerning(mi.base.bv); // Cache the dimension. diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp index e71b2881d0..8f16e2b696 100644 --- a/src/mathed/MathMacro.cpp +++ b/src/mathed/MathMacro.cpp @@ -67,7 +67,7 @@ public: /// MathMacro const * owner() { return mathMacro_; } /// - marker_type marker() const { return NO_MARKER; } + marker_type marker(BufferView const *) const { return NO_MARKER; } /// InsetCode lyxCode() const { return ARGUMENT_PROXY_CODE; } /// The math data to use for display @@ -331,7 +331,7 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const // - editing with parameter list // - editing with box around macro if (displayMode() != MathMacro::DISPLAY_NORMAL - || (d->editing_[mi.base.bv] && lyxrc.macro_edit_style != LyXRC::MACRO_EDIT_INLINE)) + || (d->editing_[mi.base.bv] && lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_LIST)) return InsetMath::addToMathRow(mrow, mi); /// The macro nesting can change display of insets. Change it locally. @@ -339,7 +339,7 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const MathRow::Element e_beg(mi, MathRow::BEGIN); e_beg.inset = this; - e_beg.marker = (d->nesting_ == 1 && nargs()) ? marker() : NO_MARKER; + e_beg.marker = (d->nesting_ == 1) ? marker(mi.base.bv) : NO_MARKER; mrow.push_back(e_beg); d->macro_->lock(); @@ -358,6 +358,7 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const MathRow::Element e_end(mi, MathRow::END); e_end.inset = this; + e_end.marker = (d->nesting_ == 1) ? marker(mi.base.bv) : NO_MARKER; mrow.push_back(e_end); return has_contents; @@ -485,24 +486,29 @@ bool MathMacro::editMetrics(BufferView const * bv) const } -Inset::marker_type MathMacro::marker() const +InsetMath::marker_type MathMacro::marker(BufferView const * bv) const { + if (nargs() == 0) + return NO_MARKER; + switch (d->displayMode_) { case DISPLAY_INIT: case DISPLAY_INTERACTIVE_INIT: return NO_MARKER; case DISPLAY_UNFOLDED: return MARKER; - default: + case DISPLAY_NORMAL: switch (lyxrc.macro_edit_style) { + case LyXRC::MACRO_EDIT_INLINE: + return MARKER; + case LyXRC::MACRO_EDIT_INLINE_BOX: + return d->editing_[bv] ? BOX_MARKER : NO_MARKER; case LyXRC::MACRO_EDIT_LIST: return MARKER2; - case LyXRC::MACRO_EDIT_INLINE_BOX: - return NO_MARKER; - default: - return MARKER; } } + // please gcc 4.6 + return NO_MARKER; } @@ -566,38 +572,8 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const dim.des += 1; dim.wid += 2; } else { - LBUFERR(d->macro_); - - // calculate metrics, hoping that all cells are seen - d->macro_->lock(); - d->expanded_.metrics(mi, dim); - - // otherwise do a manual metrics call - CoordCache & coords = mi.base.bv->coordCache(); - for (idx_type i = 0; i < nargs(); ++i) { - if (!coords.getArrays().hasDim(&cell(i))) { - Dimension tdim; - cell(i).metrics(mi, tdim); - } - } - d->macro_->unlock(); - - // calculate dimension with label while editing - if (lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX - && d->editing_[mi.base.bv]) { - FontInfo font; - font.setSize(FONT_SIZE_TINY); - Dimension namedim; - mathed_string_dim(font, name(), namedim); -#if 0 - dim.wid += 2 + namedim.wid + 2 + 2; - dim.asc = max(dim.asc, namedim.asc) + 2; - dim.des = max(dim.des, namedim.des) + 2; -#endif - dim.wid = max(1 + namedim.wid + 1, 2 + dim.wid + 2); - dim.asc += 1 + namedim.height() + 1; - dim.des += 2; - } + // We should not be here, since the macro is linearized in this case. + LBUFERR(false); } } @@ -767,33 +743,8 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const pi.pain.rectangle(expx, expy - dim.asc + 1, dim.wid - 1, dim.height() - 2, Color_mathmacroframe); } else { - bool drawBox = lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX - && d->editing_[pi.base.bv]; - - // warm up cells - for (size_t i = 0; i < nargs(); ++i) - cell(i).setXY(*pi.base.bv, x, y); - - if (drawBox) { - // draw header and rectangle around - FontInfo font; - font.setSize(FONT_SIZE_TINY); - font.setColor(Color_mathmacrolabel); - Dimension namedim; - mathed_string_dim(font, name(), namedim); - - pi.pain.fillRectangle(x, y - dim.asc, dim.wid, 1 + namedim.height() + 1, Color_mathmacrobg); - pi.pain.text(x + 1, y - dim.asc + namedim.asc + 2, name(), font); - expx += (dim.wid - d->expanded_.dimension(*pi.base.bv).width()) / 2; - } - - beforeDraw(pi); - d->expanded_.draw(pi, expx, expy); - afterDraw(pi); - - if (drawBox) - pi.pain.rectangle(x, y - dim.asc, dim.wid, - dim.height(), Color_mathmacroframe); + // We should not be here, since the macro is linearized in this case. + LBUFERR(false); } // edit mode changed? diff --git a/src/mathed/MathMacro.h b/src/mathed/MathMacro.h index 5392754969..0d4ba34bf5 100644 --- a/src/mathed/MathMacro.h +++ b/src/mathed/MathMacro.h @@ -37,7 +37,7 @@ public: /// virtual MathMacro const * asMacro() const { return this; } /// - marker_type marker() const; + marker_type marker(BufferView const *) const; /// If the macro is in normal edit mode, dissolve its contents in /// the row. Otherwise, just insert the inset. bool addToMathRow(MathRow &, MetricsInfo & mi) const; diff --git a/src/mathed/MathRow.cpp b/src/mathed/MathRow.cpp index c3c9a1c934..783e85ab54 100644 --- a/src/mathed/MathRow.cpp +++ b/src/mathed/MathRow.cpp @@ -43,6 +43,95 @@ MathRow::Element::Element(MetricsInfo const & mi, Type t, MathClass mc) {} +namespace { + +// Helper functions for markers + +int markerMargin(MathRow::Element const & e) +{ + return e.marker == InsetMath::MARKER + || e.marker == InsetMath::MARKER2; +} + + +void afterMetricsMarkers(MetricsInfo const & , MathRow::Element & e, + Dimension & dim) +{ + // handle vertical space for markers + switch(e.marker) { + case InsetMath::NO_MARKER: + break; + case InsetMath::MARKER: + ++dim.des; + break; + case InsetMath::MARKER2: + ++dim.asc; + ++dim.des; + break; + case InsetMath::BOX_MARKER: + FontInfo font; + font.setSize(FONT_SIZE_TINY); + Dimension namedim; + mathed_string_dim(font, e.inset->name(), namedim); + int const namewid = 1 + namedim.wid + 1; + + if (namewid > dim.wid) + e.after += namewid - dim.wid; + dim.des += 3 + namedim.height(); + } +} + + +void drawMarkers(PainterInfo const & pi, MathRow::Element const & e, + int const x, int const y) +{ + if (e.marker == InsetMath::NO_MARKER) + return; + + CoordCache const & coords = pi.base.bv->coordCache(); + Dimension const dim = coords.getInsets().dim(e.inset); + + // the marker is before/after the inset. Necessary space has been reserved already. + int const l = x + e.before - markerMargin(e); + int const r = x + dim.width() - e.after; + + if (e.marker == InsetMath::BOX_MARKER) { + // draw header and rectangle around + FontInfo font; + font.setSize(FONT_SIZE_TINY); + font.setColor(Color_mathmacrolabel); + Dimension namedim; + mathed_string_dim(font, e.inset->name(), namedim); + pi.pain.fillRectangle(l, y + dim.des - namedim.height() - 2, + dim.wid, namedim.height() + 2, Color_mathmacrobg); + pi.pain.text(l, y + dim.des - namedim.des - 1, e.inset->name(), font); + return; + } + + // Now markers with corners + bool const highlight = e.inset->mouseHovered(pi.base.bv) + || e.inset->editing(pi.base.bv); + ColorCode const pen_color = highlight ? Color_mathframe : Color_mathcorners; + + int const d = y + dim.descent(); + pi.pain.line(l, d - 3, l, d, pen_color); + pi.pain.line(r, d - 3, r, d, pen_color); + pi.pain.line(l, d, l + 3, d, pen_color); + pi.pain.line(r - 3, d, r, d, pen_color); + + if (e.marker == InsetMath::MARKER) + return; + + int const a = y - dim.ascent(); + pi.pain.line(l, a + 3, l, a, pen_color); + pi.pain.line(r, a + 3, r, a, pen_color); + pi.pain.line(l, a, l + 3, a, pen_color); + pi.pain.line(r - 3, a, r, a, pen_color); +} + +} + + MathRow::MathRow(MetricsInfo & mi, MathData const * ar) { // First there is a dummy element of type "open" @@ -90,16 +179,15 @@ MathRow::MathRow(MetricsInfo & mi, MathData const * ar) } // finally reserve space for markers - if (bef.marker != Inset::NO_MARKER) - bef.after = max(bef.after, 1); - if (e.mclass != MC_UNKNOWN && e.marker != Inset::NO_MARKER) - e.before = max(e.before, 1); + bef.after = max(bef.after, markerMargin(bef)); + if (e.mclass != MC_UNKNOWN) + e.before = max(e.before, markerMargin(e)); // for linearized insets (macros...) too - if (e.type == BEGIN && e.marker != Inset::NO_MARKER) - bef.after = max(bef.after, 1); - if (e.type == END && e.marker != Inset::NO_MARKER) { + if (e.type == BEGIN) + bef.after = max(bef.after, markerMargin(e)); + if (e.type == END && e.marker != InsetMath::NO_MARKER) { Element & aft = elements_[after(i)]; - aft.before = max(aft.before, 1); + aft.before = max(aft.before, markerMargin(e)); } } @@ -131,28 +219,7 @@ int MathRow::after(int i) const } -namespace { - -void metricsMarkersVertical(MetricsInfo const & , MathRow::Element const & e, - Dimension & dim) -{ - // handle vertical space for markers - switch(e.marker) { - case InsetMath::NO_MARKER: - break; - case InsetMath::MARKER: - ++dim.des; - break; - case InsetMath::MARKER2: - ++dim.asc; - ++dim.des; - } -} - -} - - -void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const +void MathRow::metrics(MetricsInfo & mi, Dimension & dim) { dim.asc = 0; dim.wid = 0; @@ -161,7 +228,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const vector> dim_insets; vector> dim_arrays; CoordCache & coords = mi.base.bv->coordCache(); - for (Element const & e : elements_) { + for (Element & e : elements_) { mi.base.macro_nesting = e.macro_nesting; Dimension d; switch (e.type) { @@ -176,6 +243,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const if (e.inset) { dim_insets.push_back(make_pair(e.inset, Dimension())); dim_insets.back().second.wid += e.before + e.after; + d.wid = e.before + e.after; e.inset->beforeMetrics(); } if (e.ar) @@ -185,11 +253,14 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const if (e.inset) { e.inset->afterMetrics(); LATTEST(dim_insets.back().first == e.inset); - Dimension & idim = dim_insets.back().second; - metricsMarkersVertical(mi, e, idim); - idim.wid += e.before + e.after; - coords.insets().add(e.inset, idim); + d = dim_insets.back().second; + afterMetricsMarkers(mi, e, d); + d.wid += e.before + e.after; + coords.insets().add(e.inset, d); dim_insets.pop_back(); + // We do not want to count the width again, but the + // padding and the vertical dimension are meaningful. + d.wid = e.before + e.after; } if (e.ar) { LATTEST(dim_arrays.back().first == e.ar); @@ -203,7 +274,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const // allow for one pixel before/after the box. d.wid += e.before + e.after + 2; } else { - // hide the box, but give it some height + // hide the box, but keep its height d.wid = 0; } break; @@ -228,43 +299,6 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const } -namespace { - -void drawMarkers(PainterInfo const & pi, MathRow::Element const & e, int const x, int const y) -{ - if (e.marker == InsetMath::NO_MARKER) - return; - - CoordCache const & coords = pi.base.bv->coordCache(); - Dimension const dim = coords.getInsets().dim(e.inset); - - // the marker is before/after the inset. Normally some space has been reserved already. - int const l = x + e.before - 1; - int const r = x + dim.width() - e.after; - - // Duplicated from Inset.cpp and adapted. It is believed that the - // Inset version should die eventually - ColorCode pen_color = e.inset->mouseHovered(pi.base.bv) || e.inset->editing(pi.base.bv)? - Color_mathframe : Color_mathcorners; - - int const d = y + dim.descent(); - pi.pain.line(l, d - 3, l, d, pen_color); - pi.pain.line(r, d - 3, r, d, pen_color); - pi.pain.line(l, d, l + 3, d, pen_color); - pi.pain.line(r - 3, d, r, d, pen_color); - - if (e.marker == InsetMath::MARKER) - return; - - int const a = y - dim.ascent(); - pi.pain.line(l, a + 3, l, a, pen_color); - pi.pain.line(r, a + 3, r, a, pen_color); - pi.pain.line(l, a, l + 3, a, pen_color); - pi.pain.line(r - 3, a, r, a, pen_color); -} - -} - void MathRow::draw(PainterInfo & pi, int x, int const y) const { CoordCache & coords = pi.base.bv->coordCache(); diff --git a/src/mathed/MathRow.h b/src/mathed/MathRow.h index 797248c3a5..de63ec965f 100644 --- a/src/mathed/MathRow.h +++ b/src/mathed/MathRow.h @@ -111,7 +111,7 @@ public: MathRow(MetricsInfo & mi, MathData const * ar); // - void metrics(MetricsInfo & mi, Dimension & dim) const; + void metrics(MetricsInfo & mi, Dimension & dim); // void draw(PainterInfo & pi, int const x, int const y) const;