X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fmath_scriptinset.C;h=11f858c31a6b16a329471a8eeeaff9087edbc80c;hb=57501b93064a6deed43e415beed45606054d86ad;hp=3c226e2ab3f04ece5185d0e314c26dd27d669c03;hpb=c1319d2c6738ff3e72283917ea903f4878298d41;p=lyx.git diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index 3c226e2ab3..11f858c31a 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -16,40 +16,34 @@ #include "math_support.h" #include "math_symbolinset.h" #include "dispatchresult.h" +#include "cursor.h" #include "debug.h" #include "funcrequest.h" #include - using std::string; using std::max; using std::auto_ptr; using std::endl; + MathScriptInset::MathScriptInset() - : MathNestInset(3), limits_(0) -{ - script_[0] = false; - script_[1] = false; -} + : MathNestInset(1), cell_1_is_up_(false), limits_(0) +{} MathScriptInset::MathScriptInset(bool up) - : MathNestInset(3), limits_(0) -{ - script_[0] = !up; - script_[1] = up; -} + : MathNestInset(2), cell_1_is_up_(up), limits_(0) +{} MathScriptInset::MathScriptInset(MathAtom const & at, bool up) - : MathNestInset(3), limits_(0) + : MathNestInset(2), cell_1_is_up_(up), limits_(0) { - script_[0] = !up; - script_[1] = up; - cell(2).push_back(at); + BOOST_ASSERT(nargs() >= 1); + cell(0).push_back(at); } @@ -72,61 +66,80 @@ MathScriptInset * MathScriptInset::asScriptInset() } -bool MathScriptInset::idxFirst(idx_type & idx, pos_type & pos) const +bool MathScriptInset::idxFirst(LCursor & cur) const { - idx = 2; - pos = 0; + cur.idx() = 0; + cur.pos() = 0; return true; } -bool MathScriptInset::idxLast(idx_type & idx, pos_type & pos) const +bool MathScriptInset::idxLast(LCursor & cur) const { - idx = 2; - pos = nuc().size(); + cur.idx() = 0; + cur.pos() = nuc().size(); return true; } MathArray const & MathScriptInset::down() const { - return cell(0); + if (nargs() == 3) + return cell(2); + BOOST_ASSERT(nargs() > 1); + return cell(1); } MathArray & MathScriptInset::down() { - return cell(0); + if (nargs() == 3) + return cell(2); + BOOST_ASSERT(nargs() > 1); + return cell(1); } MathArray const & MathScriptInset::up() const { + BOOST_ASSERT(nargs() > 1); return cell(1); } MathArray & MathScriptInset::up() { + BOOST_ASSERT(nargs() > 1); return cell(1); } void MathScriptInset::ensure(bool up) { - script_[up] = true; + if (nargs() == 1) { + // just nucleus so far + cells_.push_back(MathArray()); + cell_1_is_up_ = up; + } else if (nargs() == 2 && !has(up)) { + if (up) { + cells_.push_back(cell(1)); + cell(1).clear(); + } else { + cells_.push_back(MathArray()); + } + } } MathArray const & MathScriptInset::nuc() const { - return cell(2); + return cell(0); } MathArray & MathScriptInset::nuc() { - return cell(2); + return cell(0); } @@ -199,28 +212,30 @@ int MathScriptInset::ndes() const void MathScriptInset::metrics(MetricsInfo & mi, Dimension & dim) const { - cell(2).metrics(mi); - ScriptChanger dummy(mi.base); cell(0).metrics(mi); - cell(1).metrics(mi); - dim_.wid = 0; + ScriptChanger dummy(mi.base); + if (nargs() > 1) + cell(1).metrics(mi); + if (nargs() > 2) + cell(2).metrics(mi); + dim.wid = 0; if (hasLimits()) { - dim_.wid = nwid(); + dim.wid = nwid(); if (hasUp()) - dim_.wid = max(dim_.wid, up().width()); + dim.wid = max(dim.wid, up().width()); if (hasDown()) - dim_.wid = max(dim_.wid, down().width()); + dim.wid = max(dim.wid, down().width()); } else { if (hasUp()) - dim_.wid = max(dim_.wid, up().width()); + dim.wid = max(dim.wid, up().width()); if (hasDown()) - dim_.wid = max(dim_.wid, down().width()); - dim_.wid += nwid(); + dim.wid = max(dim.wid, down().width()); + dim.wid += nwid(); } - dim_.asc = dy1() + (hasUp() ? up().ascent() : 0); - dim_.des = dy0() + (hasDown() ? down().descent() : 0); - metricsMarkers(); - dim = dim_; + dim.asc = dy1() + (hasUp() ? up().ascent() : 0); + dim.des = dy0() + (hasDown() ? down().descent() : 0); + metricsMarkers(dim); + dim_ = dim; } @@ -230,7 +245,7 @@ void MathScriptInset::draw(PainterInfo & pi, int x, int y) const nuc().draw(pi, x + dxx(), y); else { nuc().setXY(x + dxx(), y); - if (editing()) + if (editing(pi.base.bv)) drawStr(pi, pi.base.font, x + dxx(), y, "."); } ScriptChanger dummy(pi.base); @@ -290,76 +305,113 @@ bool MathScriptInset::hasLimits() const void MathScriptInset::removeScript(bool up) { - cell(up).clear(); - script_[up] = false; + lyxerr << "MathNestInset::removeScript: 1 up: " << up << endl; + if (nargs() == 2) { + lyxerr << "MathNestInset::removeScript: a up: " << up << endl; + if (up == cell_1_is_up_) + cells_.pop_back(); + lyxerr << "MathNestInset::removeScript: b up: " << up << endl; + } else if (nargs() == 3) { + if (up == true) { + swap(cells_[1], cells_[2]); + cell_1_is_up_ = false; + } else { + cell_1_is_up_ = true; + } + cells_.pop_back(); + } + lyxerr << "MathNestInset::removeScript: 2 up: " << up << endl; } bool MathScriptInset::has(bool up) const { - return script_[up]; + return idxOfScript(up); } bool MathScriptInset::hasUp() const { - return script_[1]; + //lyxerr << "1up: " << bool(cell_1_is_up_) << endl; + //lyxerr << "hasUp: " << bool(idxOfScript(true)) << endl; + return idxOfScript(true); } bool MathScriptInset::hasDown() const { - return script_[0]; + //lyxerr << "1up: " << bool(cell_1_is_up_) << endl; + //lyxerr << "hasDown: " << bool(idxOfScript(false)) << endl; + return idxOfScript(false); } -bool MathScriptInset::idxRight(idx_type &, pos_type &) const +InsetBase::idx_type MathScriptInset::idxOfScript(bool up) const { - return false; + if (nargs() == 1) + return 0; + if (nargs() == 2) + return (cell_1_is_up_ == up) ? 1 : 0; + if (nargs() == 3) + return up ? 1 : 2; + BOOST_ASSERT(false); + // Silence compiler + return 0; } -bool MathScriptInset::idxLeft(idx_type &, pos_type &) const +bool MathScriptInset::idxRight(LCursor &) const { return false; } -bool MathScriptInset::idxUpDown(idx_type & idx, pos_type & pos, bool up, - int) const +bool MathScriptInset::idxLeft(LCursor &) const { - if (idx == 1) { - // if we are 'up' we can't go further up - if (up) - return false; - // otherwise go to last base position - idx = 2; - pos = cell(2).size(); - } + return false; +} - else if (idx == 0) { - // if we are 'down' we can't go further down - if (!up) - return false; - idx = 2; - pos = cell(2).size(); - } - else { - // in nucleus - // don't go up/down if there is no cell. +bool MathScriptInset::idxUpDown(LCursor & cur, bool up) const +{ + // in nucleus? + if (cur.idx() == 0) { + // don't go up/down if there is no cell in this direction if (!has(up)) return false; // go up/down only if in the last position // or in the first position of something with displayed limits - if (pos == cell(2).size() || (pos == 0 && hasLimits())) { - idx = up; - pos = 0; + if (cur.pos() == cur.lastpos() || (cur.pos() == 0 && hasLimits())) { + cur.idx() = idxOfScript(up); + cur.pos() = 0; return true; } return false; } - return true; + + // Are we 'up'? + if (has(up) && cur.idx() == idxOfScript(true)) { + // can't go further up + if (up) + return false; + // otherwise go to last position in the nucleus + cur.idx() = 0; + cur.pos() = cur.lastpos(); + return true; + } + + // Are we 'down'? + if (has(up) && cur.idx() == idxOfScript(false)) { + // can't go further down + if (!up) + return false; + // otherwise go to last position in the nucleus + cur.idx() = 0; + cur.pos() = cur.lastpos(); + return true; + } + + return false; } @@ -444,13 +496,14 @@ void MathScriptInset::mathematica(MathematicaStream & os) const if (u) os << "^(" << up() << ')'; - if (nuc().size()) + if (nuc().size()) { if (d) os << ',' << down() << ']'; + } } -void MathScriptInset::mathmlize( MathMLStream & os) const +void MathScriptInset::mathmlize(MathMLStream & os) const { bool d = hasDown() && down().size(); bool u = hasUp() && up().size(); @@ -500,22 +553,31 @@ void MathScriptInset::infoize2(std::ostream & os) const } -void MathScriptInset::notifyCursorLeaves(idx_type idx) +void MathScriptInset::notifyCursorLeaves(LCursor & cur) { - MathNestInset::notifyCursorLeaves(idx); + MathNestInset::notifyCursorLeaves(cur); // remove empty scripts if possible - if (idx != 2 && script_[idx] && cell(idx).empty()) { - cell(idx).clear(); - script_[idx] = false; + if (nargs() > 2 && cur.idx() == 2 && cell(2).empty()) { + // must be a subscript... + removeScript(false); + // sanitize cursor, even if this slice will be removed immediately + cur.idx() = 0; + cur.pos() = 0; + } else if (nargs() > 1 && cur.idx() == 1 && cell(1).empty()) { + // could be either subscript or super script + removeScript(cell_1_is_up_); + // sanitize cursor, even if this slice will be removed immediately + cur.idx() = 0; + cur.pos() = 0; } } -DispatchResult -MathScriptInset::priv_dispatch(FuncRequest const & cmd, - idx_type & idx, pos_type & pos) +void MathScriptInset::priv_dispatch(LCursor & cur, FuncRequest & cmd) { + //lyxerr << "MathScriptInset: request: " << cmd << std::endl; + if (cmd.action == LFUN_MATH_LIMITS) { if (!cmd.argument.empty()) { if (cmd.argument == "limits") @@ -525,11 +587,11 @@ MathScriptInset::priv_dispatch(FuncRequest const & cmd, else limits_ = 0; } else if (limits_ == 0) - limits_ = (hasLimits()) ? -1 : 1; + limits_ = hasLimits() ? -1 : 1; else limits_ = 0; - return DispatchResult(true, true); + return; } - return MathNestInset::priv_dispatch(cmd, idx, pos); + MathNestInset::priv_dispatch(cur, cmd); }