From 6c13af3f298a96c5564684b83c52989473b020ce Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 1 Feb 2017 15:20:06 +0100 Subject: [PATCH] Introduce hooks to encapsulate macro code of MathRow New hooks (before|after)(Metrics|Draw) are run by the MathRow code as needed. They are actually also used internally by the MathMacro code. The gain is that most traces of explicit macro handling (and the MathRow::Element::macro member) have been removed from MathRw.cpp. The next step will be to extend the tokenizing process to allow for linearizing insets other than macros. --- src/mathed/InsetMath.h | 8 ++++ src/mathed/MathMacro.cpp | 86 ++++++++++++++++++++++++++++++---------- src/mathed/MathMacro.h | 15 +++++-- src/mathed/MathRow.cpp | 47 +++++++++------------- src/mathed/MathRow.h | 5 --- 5 files changed, 105 insertions(+), 56 deletions(-) diff --git a/src/mathed/InsetMath.h b/src/mathed/InsetMath.h index 9c65fafe4d..2fc4c1ddf6 100644 --- a/src/mathed/InsetMath.h +++ b/src/mathed/InsetMath.h @@ -171,6 +171,14 @@ public: virtual MathClass mathClass() const; /// Add this inset to a math row. Return true if contents got added virtual bool addToMathRow(MathRow &, MetricsInfo & mi) const; + /// Hook that is run before metrics computation starts + virtual void beforeMetrics() const {} + /// Hook that is run after metrics computation + virtual void afterMetrics() const {} + /// Hook that is run before actual drawing + virtual void beforeDraw(PainterInfo const &) const {} + /// Hook that is run after drawing + virtual void afterDraw(PainterInfo const &) const {} /// identifies things that can get scripts virtual bool isScriptable() const { return false; } diff --git a/src/mathed/MathMacro.cpp b/src/mathed/MathMacro.cpp index d06813f57d..4ea986a847 100644 --- a/src/mathed/MathMacro.cpp +++ b/src/mathed/MathMacro.cpp @@ -88,7 +88,7 @@ public: mathMacro_->nesting() == 1 ? 0 : mathMacro_->nesting()); MathRow::Element e_beg(mi, MathRow::BEG_ARG); - e_beg.macro = mathMacro_; + e_beg.inset = this; e_beg.ar = &mathMacro_->cell(idx_); mrow.push_back(e_beg); @@ -107,7 +107,7 @@ public: } MathRow::Element e_end(mi, MathRow::END_ARG); - e_end.macro = mathMacro_; + e_end.inset = this; e_end.ar = &mathMacro_->cell(idx_); mrow.push_back(e_end); @@ -115,20 +115,44 @@ public: return has_contents; } /// - void metrics(MetricsInfo &, Dimension &) const { - // This should never be invoked, since ArgumentProxy insets are linearized - LATTEST(false); + void beforeMetrics() const + { + mathMacro_->macro()->unlock(); } /// - int kerning(BufferView const * bv) const + void afterMetrics() const { - return displayCell(bv).kerning(bv); + mathMacro_->macro()->lock(); + } + /// + void beforeDraw(PainterInfo const & pi) const + { + // if the macro is being edited, then the painter is in + // monochrome mode. + if (mathMacro_->editMetrics(pi.base.bv)) + pi.pain.leaveMonochromeMode(); + } + /// + void afterDraw(PainterInfo const & pi) const + { + if (mathMacro_->editMetrics(pi.base.bv)) + pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend); + } + /// + void metrics(MetricsInfo &, Dimension &) const { + // This should never be invoked, since ArgumentProxy insets are linearized + LATTEST(false); } /// void draw(PainterInfo &, int, int) const { // This should never be invoked, since ArgumentProxy insets are linearized LATTEST(false); } + /// + int kerning(BufferView const * bv) const + { + return displayCell(bv).kerning(bv); + } // write(), normalize(), infoize() and infoize2() are not needed since // MathMacro uses the definition and not the expanded cells. /// @@ -316,7 +340,6 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const MathRow::Element e_beg(mi, MathRow::BEG_MACRO); e_beg.inset = this; - e_beg.macro = this; e_beg.marker = (d->nesting_ == 1 && nargs()) ? marker() : NO_MARKER; mrow.push_back(e_beg); @@ -335,12 +358,37 @@ bool MathMacro::addToMathRow(MathRow & mrow, MetricsInfo & mi) const } MathRow::Element e_end(mi, MathRow::END_MACRO); - e_end.macro = this; + e_end.inset = this; mrow.push_back(e_end); return has_contents; } +void MathMacro::beforeMetrics() const +{ + d->macro_->lock(); +} + + +void MathMacro::afterMetrics() const +{ + d->macro_->unlock(); +} + + +void MathMacro::beforeDraw(PainterInfo const & pi) const +{ + if (d->editing_[pi.base.bv]) + pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend); +} + + +void MathMacro::afterDraw(PainterInfo const & pi) const +{ + if (d->editing_[pi.base.bv]) + pi.pain.leaveMonochromeMode(); +} + Inset * MathMacro::clone() const { @@ -720,13 +768,14 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const pi.pain.rectangle(expx, expy - dim.asc + 1, dim.wid - 3, dim.height() - 2, Color_mathmacroframe); } else { - bool drawBox = lyxrc.macro_edit_style == LyXRC::MACRO_EDIT_INLINE_BOX; + 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 && d->editing_[pi.base.bv]) { + if (drawBox) { // draw header and rectangle around FontInfo font = pi.base.font; augmentFont(font, "lyxtex"); @@ -740,16 +789,13 @@ void MathMacro::draw(PainterInfo & pi, int x, int y) const expx += (dim.wid - d->expanded_.dimension(*pi.base.bv).width()) / 2; } - if (d->editing_[pi.base.bv]) { - pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend); - d->expanded_.draw(pi, expx, expy); - pi.pain.leaveMonochromeMode(); + 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); - } else - d->expanded_.draw(pi, expx, expy); + if (drawBox) + pi.pain.rectangle(x, y - dim.asc, dim.wid, + dim.height(), Color_mathmacroframe); } // edit mode changed? diff --git a/src/mathed/MathMacro.h b/src/mathed/MathMacro.h index c7dca261fa..f1e61dcb4c 100644 --- a/src/mathed/MathMacro.h +++ b/src/mathed/MathMacro.h @@ -42,14 +42,23 @@ public: /// the row. Otherwise, just insert the inset. bool addToMathRow(MathRow &, MetricsInfo & mi) const; /// - void draw(PainterInfo & pi, int x, int y) const; - /// draw selection background - void drawSelection(PainterInfo & pi, int x, int y) const; + void beforeMetrics() const; + /// + void afterMetrics() const; + /// + void beforeDraw(PainterInfo const &) const; + /// + void afterDraw(PainterInfo const &) const; + /// void metrics(MetricsInfo & mi, Dimension & dim) const; /// was the macro in edit mode when computing metrics? 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 void cursorPos(BufferView const & bv, CursorSlice const & sl, diff --git a/src/mathed/MathRow.cpp b/src/mathed/MathRow.cpp index 0f4e654827..0f9436dbb8 100644 --- a/src/mathed/MathRow.cpp +++ b/src/mathed/MathRow.cpp @@ -15,7 +15,6 @@ #include "InsetMath.h" #include "MathClass.h" #include "MathData.h" -#include "MathMacro.h" #include "MathSupport.h" #include "BufferView.h" @@ -39,7 +38,7 @@ namespace lyx { MathRow::Element::Element(MetricsInfo const & mi, Type t, MathClass mc) : type(t), mclass(mc), before(0), after(0), macro_nesting(mi.base.macro_nesting), marker(InsetMath::NO_MARKER), inset(0), compl_unique_to(0), - macro(0), color(Color_red) + color(Color_red) {} @@ -133,7 +132,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = 0; // In order to compute the dimension of macros and their // arguments, it is necessary to keep track of them. - map dim_macros; + map dim_insets; map dim_arrays; CoordCache & coords = mi.base.bv->coordCache(); for (Element const & e : elements_) { @@ -148,28 +147,26 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const coords.insets().add(e.inset, d); break; case BEG_MACRO: - e.macro->macro()->lock(); + e.inset->beforeMetrics(); // Add a macro to current list - dim_macros[e.macro] = Dimension(); + dim_insets[e.inset] = Dimension(); break; case END_MACRO: - LATTEST(dim_macros.find(e.macro) != dim_macros.end()); - e.macro->macro()->unlock(); + LATTEST(dim_insets.find(e.inset) != dim_insets.end()); + e.inset->afterMetrics(); // Cache the dimension of the macro and remove it from // tracking map. - coords.insets().add(e.macro, dim_macros[e.macro]); - dim_macros.erase(e.macro); + coords.insets().add(e.inset, dim_insets[e.inset]); + dim_insets.erase(e.inset); break; // This is basically like macros case BEG_ARG: - if (e.macro) - e.macro->macro()->unlock(); + e.inset->beforeMetrics(); dim_arrays[e.ar] = Dimension(); break; case END_ARG: LATTEST(dim_arrays.find(e.ar) != dim_arrays.end()); - if (e.macro) - e.macro->macro()->lock(); + e.inset->afterMetrics(); coords.arrays().add(e.ar, dim_arrays[e.ar]); dim_arrays.erase(e.ar); break; @@ -200,7 +197,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const if (!d.empty()) { dim += d; // Now add the dimension to current macros and arguments. - for (auto & dim_macro : dim_macros) + for (auto & dim_macro : dim_insets) dim_macro.second += d; for (auto & dim_array : dim_arrays) dim_array.second += d; @@ -212,7 +209,7 @@ void MathRow::metrics(MetricsInfo & mi, Dimension & dim) const augmentFont(font, "mathnormal"); dim.wid += mathed_string_width(font, e.compl_text); } - LATTEST(dim_macros.empty() && dim_arrays.empty()); + LATTEST(dim_insets.empty() && dim_arrays.empty()); } @@ -275,25 +272,19 @@ void MathRow::draw(PainterInfo & pi, int x, int const y) const break; } case BEG_MACRO: - coords.insets().add(e.macro, x, y); + coords.insets().add(e.inset, x, y); drawMarkers(pi, e, x, y); - if (e.macro->editMetrics(pi.base.bv)) - pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend); + e.inset->beforeDraw(pi); break; case END_MACRO: - if (e.macro->editMetrics(pi.base.bv)) - pi.pain.leaveMonochromeMode(); + e.inset->afterDraw(pi); break; case BEG_ARG: coords.arrays().add(e.ar, x, y); - // if the macro is being edited, then the painter is in - // monochrome mode. - if (e.macro->editMetrics(pi.base.bv)) - pi.pain.leaveMonochromeMode(); + e.inset->beforeDraw(pi); break; case END_ARG: - if (e.macro->editMetrics(pi.base.bv)) - pi.pain.enterMonochromeMode(Color_mathbg, Color_mathmacroblend); + e.inset->afterDraw(pi); break; case BOX: { if (e.color == Color_none) @@ -354,8 +345,8 @@ ostream & operator<<(ostream & os, MathRow::Element const & e) << "-" << e.after << ">"; break; case MathRow::BEG_MACRO: - os << "\\" << to_utf8(e.macro->name()) - << "^" << e.macro->nesting() << "["; + os << "\\" << to_utf8(e.inset->name()) + << "^" << e.macro_nesting << "["; break; case MathRow::END_MACRO: os << "]"; diff --git a/src/mathed/MathRow.h b/src/mathed/MathRow.h index 760ac18eb1..692c1e4ae5 100644 --- a/src/mathed/MathRow.h +++ b/src/mathed/MathRow.h @@ -30,7 +30,6 @@ class PainterInfo; class InsetMath; class MathData; -class MathMacro; /* * While for editing purpose it is important that macros are counted @@ -81,10 +80,6 @@ public: // the number of characters forming the unique part. size_t compl_unique_to; - /// When type is BEG_MACRO, END_MACRO, BEG_ARG, END_ARG - /// the math macro - MathMacro const * macro; - // type is BEG_ARG, END_ARG MathData const * ar; -- 2.39.2