+//////////////////////////////////////////////////////////////////////
+
+class InsetLabelBox : public InsetMathNest {
+public:
+ ///
+ InsetLabelBox(Buffer * buf, MathAtom const & atom, docstring label,
+ MathMacroTemplate const & parent, bool frame = false);
+ InsetLabelBox(Buffer * buf, docstring label, MathMacroTemplate const & parent,
+ bool frame = false);
+ ///
+ void metrics(MetricsInfo & mi, Dimension & dim) const;
+ ///
+ void draw(PainterInfo &, int x, int y) const;
+
+protected:
+ ///
+ MathMacroTemplate const & parent_;
+ ///
+ Inset * clone() const;
+ ///
+ docstring const label_;
+ ///
+ bool frame_;
+};
+
+
+InsetLabelBox::InsetLabelBox(Buffer * buf, MathAtom const & atom, docstring label,
+ MathMacroTemplate const & parent, bool frame)
+ : InsetMathNest(buf, 1), parent_(parent), label_(label), frame_(frame)
+{
+ cell(0).insert(0, atom);
+}
+
+
+InsetLabelBox::InsetLabelBox(Buffer * buf, docstring label,
+ MathMacroTemplate const & parent, bool frame)
+ : InsetMathNest(buf, 1), parent_(parent), label_(label), frame_(frame)
+{
+}
+
+
+Inset * InsetLabelBox::clone() const
+{
+ return new InsetLabelBox(*this);
+}
+
+
+void InsetLabelBox::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ // kernel
+ cell(0).metrics(mi, dim);
+
+ // frame
+ if (frame_) {
+ dim.wid += 6;
+ dim.asc += 5;
+ dim.des += 5;
+ }
+
+ // adjust to common height in main metrics phase
+ if (!parent_.premetrics()) {
+ dim.asc = max(dim.asc, parent_.commonLabelBoxAscent());
+ dim.des = max(dim.des, parent_.commonLabelBoxDescent());
+ }
+
+ // label
+ if (parent_.editing(mi.base.bv) && label_.length() > 0) {
+ // grey
+ FontInfo font = sane_font;
+ font.setSize(FONT_SIZE_TINY);
+ font.setColor(Color_mathmacrolabel);
+
+ // make space for label and box
+ int lwid = mathed_string_width(font, label_);
+ int maxasc;
+ int maxdes;
+ math_font_max_dim(font, maxasc, maxdes);
+
+ dim.wid = max(dim.wid, lwid + 2);
+
+ // space for the label
+ if (!parent_.premetrics())
+ dim.des += maxasc + maxdes + 1;
+ }
+}
+
+
+void InsetLabelBox::draw(PainterInfo & pi, int x, int y) const
+{
+ Dimension const dim = dimension(*pi.base.bv);
+ Dimension const cdim = cell(0).dimension(*pi.base.bv);
+
+ // kernel
+ cell(0).draw(pi, x + (dim.wid - cdim.wid) / 2, y);
+
+ // label
+ if (parent_.editing(pi.base.bv) && label_.length() > 0) {
+ // grey
+ FontInfo font = sane_font;
+ font.setSize(FONT_SIZE_TINY);
+ font.setColor(Color_mathmacrolabel);
+
+ // make space for label and box
+ int lwid = mathed_string_width(font, label_);
+ int maxasc;
+ int maxdes;
+ math_font_max_dim(font, maxasc, maxdes);
+
+ if (lwid < dim.wid)
+ pi.pain.text(x + (dim.wid - lwid) / 2, y + dim.des - maxdes, label_, font);
+ else
+ pi.pain.text(x, y + dim.des - maxdes, label_, font);
+ }
+
+ // draw frame
+ int boxHeight = parent_.commonLabelBoxAscent() + parent_.commonLabelBoxDescent();
+ if (frame_) {
+ pi.pain.rectangle(x + 1, y - dim.ascent() + 1,
+ dim.wid - 2, boxHeight - 2,
+ Color_mathline);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+class DisplayLabelBox : public InsetLabelBox {
+public:
+ ///
+ DisplayLabelBox(Buffer * buf, MathAtom const & atom, docstring label,
+ MathMacroTemplate const & parent);
+
+ ///
+ void metrics(MetricsInfo & mi, Dimension & dim) const;
+ ///
+ void draw(PainterInfo &, int x, int y) const;
+
+protected:
+ ///
+ Inset * clone() const;
+};
+
+
+DisplayLabelBox::DisplayLabelBox(Buffer * buf, MathAtom const & atom,
+ docstring label,
+ MathMacroTemplate const & parent)
+ : InsetLabelBox(buf, atom, label, parent, true)
+{
+}
+
+
+
+Inset * DisplayLabelBox::clone() const
+{
+ return new DisplayLabelBox(*this);
+}
+
+
+void DisplayLabelBox::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ InsetLabelBox::metrics(mi, dim);
+ if (!parent_.editing(mi.base.bv)
+ && parent_.cell(parent_.displayIdx()).empty()) {
+ dim.wid = 0;
+ dim.asc = 0;
+ dim.des = 0;
+ }
+}
+
+
+void DisplayLabelBox::draw(PainterInfo & pi, int x, int y) const
+{
+ if (parent_.editing(pi.base.bv)
+ || !parent_.cell(parent_.displayIdx()).empty()) {
+ InsetLabelBox::draw(pi, x, y);
+ } else {
+ bool enabled = pi.pain.isDrawingEnabled();
+ pi.pain.setDrawingEnabled(false);
+ InsetLabelBox::draw(pi, x, y);
+ pi.pain.setDrawingEnabled(enabled);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////