Fix cursor navigation in \overbrace and \underbrace

Due to the way these decorations are implemented, entering
them with the cursor (either form right or left) required
pressing two times cursor left or right.

Fixes #2264
This commit is contained in:
Enrico Forestieri 2021-02-26 20:30:41 +01:00
parent d74367a96e
commit c2facb8c56

View File

@ -2037,20 +2037,39 @@ bool Cursor::mathForward(bool word)
posForward(); posForward();
while (pos() < lastpos() && mc == nextMath().mathClass()); while (pos() < lastpos() && mc == nextMath().mathClass());
} else if (openable(nextAtom())) { } else if (openable(nextAtom())) {
InsetMathScript const * n = nextMath().asScriptInset();
bool to_brace_deco = n
&& n->nuc().back()->lyxCode() == MATH_DECORATION_CODE
&& n->nuc().back()->mathClass() == MC_OP;
// single step: try to enter the next inset // single step: try to enter the next inset
pushBackward(nextMath()); pushBackward(nextMath());
inset().idxFirst(*this); inset().idxFirst(*this);
// Make sure the cursor moves directly to an
// \overbrace or \underbrace inset (bug 2264)
if (to_brace_deco) {
pushBackward(nextMath());
inset().idxFirst(*this);
}
} else } else
posForward(); posForward();
return true; return true;
} }
if (inset().idxForward(*this)) if (inset().idxForward(*this))
return true; return true;
InsetMath const * m = inset().asInsetMath();
bool from_brace_deco = m
&& m->lyxCode() == MATH_DECORATION_CODE
&& m->mathClass() == MC_OP;
// try to pop forwards --- but don't pop out of math! leave that to // try to pop forwards --- but don't pop out of math! leave that to
// the FINISH lfuns // the FINISH lfuns
int s = depth() - 2; int s = depth() - 2;
if (s >= 0 && operator[](s).inset().asInsetMath()) if (s >= 0 && operator[](s).inset().asInsetMath() && popForward()) {
return popForward(); // Make sure the cursor moves directly to an
// \overbrace or \underbrace inset (bug 2264)
bool to_script = inset().asInsetMath()
&& inset().asInsetMath()->asScriptInset();
return from_brace_deco && to_script ? mathForward(word) : true;
}
return false; return false;
} }
@ -2072,21 +2091,41 @@ bool Cursor::mathBackward(bool word)
while (pos() > 0 && mc == prevMath().mathClass()); while (pos() > 0 && mc == prevMath().mathClass());
} }
} else if (openable(prevAtom())) { } else if (openable(prevAtom())) {
InsetMathScript const * p = prevMath().asScriptInset();
bool to_brace_deco = p
&& p->nuc().back()->lyxCode() == MATH_DECORATION_CODE
&& p->nuc().back()->mathClass() == MC_OP;
// single step: try to enter the preceding inset // single step: try to enter the preceding inset
posBackward(); posBackward();
push(nextMath()); push(nextMath());
inset().idxLast(*this); inset().idxLast(*this);
// Make sure the cursor moves directly to an
// \overbrace or \underbrace inset (bug 2264)
if (to_brace_deco) {
posBackward();
push(nextMath());
inset().idxLast(*this);
}
} else } else
posBackward(); posBackward();
return true; return true;
} }
if (inset().idxBackward(*this)) if (inset().idxBackward(*this))
return true; return true;
InsetMath const * m = inset().asInsetMath();
bool from_brace_deco = m
&& m->lyxCode() == MATH_DECORATION_CODE
&& m->mathClass() == MC_OP;
// try to pop backwards --- but don't pop out of math! leave that to // try to pop backwards --- but don't pop out of math! leave that to
// the FINISH lfuns // the FINISH lfuns
int s = depth() - 2; int s = depth() - 2;
if (s >= 0 && operator[](s).inset().asInsetMath()) if (s >= 0 && operator[](s).inset().asInsetMath() && popBackward()) {
return popBackward(); // Make sure the cursor moves directly to an
// \overbrace or \underbrace inset (bug 2264)
bool to_script = inset().asInsetMath()
&& inset().asInsetMath()->asScriptInset();
return from_brace_deco && to_script ? mathBackward(word) : true;
}
return false; return false;
} }