Overhaul (no)limits support

- Add limits support to InsetMathScript
- Add limits support to InsetMathClass
- Fix bug where limits changing is disabled in inline math

Now the MathData objects remember whether they are in diaply mode.

Fixes bug #12045.
This commit is contained in:
Jean-Marc Lasgouttes 2020-12-09 09:39:49 +01:00
parent 041b67d990
commit 99fb1c7003
14 changed files with 81 additions and 17 deletions

View File

@ -209,8 +209,8 @@ public:
/// Whether the inset allows \(no)limits
bool allowsLimitsChange() const { return mathClass() == MC_OP; }
/// The default limits value
virtual Limits defaultLimits() const { return NO_LIMITS; }
/// The default limits value depending on whether display mode is on
virtual Limits defaultLimits(bool /* display */) const { return NO_LIMITS; }
/// whether the inset has limit-like sub/superscript
virtual Limits limits() const { return AUTO_LIMITS; }
/// sets types of sub/superscripts

View File

@ -28,6 +28,15 @@ Inset * InsetMathClass::clone() const
}
Limits InsetMathClass::defaultLimits(bool display) const
{
if (allowsLimitsChange() && display)
return LIMITS;
else
return NO_LIMITS;
}
void InsetMathClass::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi, dim);
@ -40,6 +49,13 @@ void InsetMathClass::draw(PainterInfo & pi, int x, int y) const
}
void InsetMathClass::write(WriteStream & os) const
{
InsetMathNest::write(os);
writeLimits(os);
}
docstring InsetMathClass::name() const
{
return class_to_string(math_class_);

View File

@ -30,11 +30,19 @@ public:
docstring name() const override;
///
MathClass mathClass() const override { return math_class_; }
/// The default limits value in \c display style
Limits defaultLimits(bool display) const override;
/// whether the inset has limit-like sub/superscript
Limits limits() const override { return limits_; }
/// sets types of sub/superscripts
void limits(Limits lim) override { limits_ = lim; }
///
void metrics(MetricsInfo & mi, Dimension & dim) const override;
///
void draw(PainterInfo & pi, int x, int y) const override;
///
void write(WriteStream & os) const override;
///
void infoize(odocstream & os) const override;
///
InsetCode lyxCode() const override { return MATH_CLASS_CODE; }
@ -47,6 +55,8 @@ private:
Inset * clone() const override;
///
MathClass math_class_;
///
Limits limits_ = AUTO_LIMITS;
};

View File

@ -64,6 +64,15 @@ MathClass InsetMathDecoration::mathClass() const
}
Limits InsetMathDecoration::defaultLimits(bool display) const
{
if (allowsLimitsChange() && display)
return LIMITS;
else
return NO_LIMITS;
}
bool InsetMathDecoration::protect() const
{
return

View File

@ -39,8 +39,8 @@ public:
void infoize(odocstream & os) const override;
///
MathClass mathClass() const override;
/// The default limits value
Limits defaultLimits() const override { return allowsLimitsChange() ? LIMITS : NO_LIMITS; }
/// The default limits value in \c display style
Limits defaultLimits(bool display) const override;
/// whether the inset has limit-like sub/superscript
Limits limits() const override { return limits_; }
/// sets types of sub/superscripts

View File

@ -398,14 +398,14 @@ bool InsetMathMacro::allowsLimitsChange() const
}
Limits InsetMathMacro::defaultLimits() const
Limits InsetMathMacro::defaultLimits(bool display) const
{
if (d->expanded_.empty())
return NO_LIMITS;
// Guess from the expanded macro
InsetMath const * in = d->expanded_.back().nucleus();
Limits const lim = in->limits() == AUTO_LIMITS
? in->defaultLimits() : in->limits();
? in->defaultLimits(display) : in->limits();
LATTEST(lim != AUTO_LIMITS);
return lim;
}

View File

@ -45,7 +45,7 @@ public:
/// Whether the inset allows \(no)limits
bool allowsLimitsChange() const;
/// The default limits value
Limits defaultLimits() const override;
Limits defaultLimits(bool display) const override;
/// whether the inset has limit-like sub/superscript
Limits limits() const override;
/// sets types of sub/superscripts

View File

@ -1299,10 +1299,12 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
in->limits(NO_LIMITS);
else
in->limits(AUTO_LIMITS);
} else if (in->limits() == AUTO_LIMITS)
in->limits(in->defaultLimits() == LIMITS ? NO_LIMITS : LIMITS);
else
} else if (in->limits() != AUTO_LIMITS)
in->limits(AUTO_LIMITS);
else if (in->defaultLimits(cur.cell().displayStyle()) == LIMITS)
in->limits(NO_LIMITS);
else
in->limits(LIMITS);
return;
}

View File

@ -253,6 +253,23 @@ int InsetMathScript::nker(BufferView const * bv) const
}
Limits InsetMathScript::limits() const
{
if (nuc().empty())
return AUTO_LIMITS;
else
// only the limits status of the last element counts
return nuc().back()->limits();
}
void InsetMathScript::limits(Limits lim)
{
if (!nuc().empty())
nuc().back()->limits(lim);
}
MathClass InsetMathScript::mathClass() const
{
// FIXME: this is a hack, since the class will not be correct if
@ -370,13 +387,12 @@ void InsetMathScript::drawT(TextPainter & pain, int x, int y) const
bool InsetMathScript::hasLimits(FontInfo const & font) const
{
if (font.style() != DISPLAY_STYLE)
return false;
if (nuc().empty())
return false;
Limits const lim = nuc().back()->limits() == AUTO_LIMITS
? nuc().back()->defaultLimits() : nuc().back()->limits();
? nuc().back()->defaultLimits(font.style() == DISPLAY_STYLE)
: nuc().back()->limits();
LASSERT(lim != AUTO_LIMITS, return false);
return lim == LIMITS;
}

View File

@ -32,6 +32,10 @@ public:
InsetMathScript(Buffer * buf, MathAtom const & at, bool up);
///
mode_type currentMode() const override { return MATH_MODE; }
/// whether the inset has limit-like sub/superscript
Limits limits() const override;
/// sets types of sub/superscripts
void limits(Limits lim) override;
///
MathClass mathClass() const override;
///

View File

@ -58,10 +58,12 @@ docstring InsetMathSymbol::name() const
/// The default limits value
Limits InsetMathSymbol::defaultLimits() const
Limits InsetMathSymbol::defaultLimits(bool display) const
{
return (allowsLimitsChange() && sym_->extra != "func")
? LIMITS : NO_LIMITS;
if (allowsLimitsChange() && sym_->extra != "func" && display)
return LIMITS;
else
return NO_LIMITS;
}

View File

@ -42,7 +42,7 @@ public:
///
bool isOrdAlpha() const;
/// The default limits value
Limits defaultLimits() const override;
Limits defaultLimits(bool display) const override;
/// whether the inset has limit-like sub/superscript
Limits limits() const override { return limits_; }
/// sets types of sub/superscripts

View File

@ -224,6 +224,7 @@ bool MathData::addToMathRow(MathRow & mrow, MetricsInfo & mi) const
{
bool has_contents = false;
BufferView * bv = mi.base.bv;
display_style_ = mi.base.font.style() == DISPLAY_STYLE;
MathData * ar = const_cast<MathData*>(this);
ar->updateMacros(&bv->cursor(), mi.macrocontext,
InternalUpdate, mi.base.macro_nesting);

View File

@ -146,6 +146,8 @@ public:
MathClass mathClass() const;
/// math class of last interesting element
MathClass lastMathClass() const;
/// is the cell in display style
bool displayStyle() const { return display_style_; }
/// access to cached x coordinate of last drawing
int xo(BufferView const & bv) const;
@ -192,6 +194,8 @@ protected:
mutable int mindes_ = 0;
mutable int slevel_ = 0;
mutable int sshift_ = 0;
/// cached value for display style
mutable bool display_style_ = false;
Buffer * buffer_ = nullptr;
private: