]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/math_nestinset.C
Final touches, corner markers & clickability in math
[lyx.git] / src / mathed / math_nestinset.C
index d3ca2922d07c2ff56c6d06d1332f182f6cffb6c8..9c66c3d898c5d8c46937574143b932c7199ede5c 100644 (file)
@@ -13,6 +13,7 @@
 #include "math_nestinset.h"
 
 #include "math_arrayinset.h"
+#include "math_boxinset.h"
 #include "math_braceinset.h"
 #include "math_commentinset.h"
 #include "math_data.h"
@@ -21,7 +22,7 @@
 #include "math_hullinset.h"
 #include "math_mathmlstream.h"
 #include "math_macroarg.h"
-#include "math_mboxinset.h"
+//#include "math_mboxinset.h"
 #include "math_parser.h"
 #include "math_scriptinset.h"
 #include "math_spaceinset.h"
@@ -34,6 +35,7 @@
 #include "FuncStatus.h"
 #include "LColor.h"
 #include "bufferview_funcs.h"
+#include "coordcache.h"
 #include "cursor.h"
 #include "debug.h"
 #include "dispatchresult.h"
@@ -62,18 +64,6 @@ using std::string;
 using std::istringstream;
 
 
-
-namespace {
-
-// local global
-int first_x;
-int first_y;
-
-} // namespace anon
-
-
-
-
 MathNestInset::MathNestInset(idx_type nargs)
        : cells_(nargs), lock_(false)
 {}
@@ -97,14 +87,44 @@ MathArray const & MathNestInset::cell(idx_type i) const
 }
 
 
-void MathNestInset::getCursorPos(LCursor const & cur, int & x, int & y) const
+void MathNestInset::getCursorPos(CursorSlice const & sl,
+       int & x, int & y) const
 {
-       BOOST_ASSERT(ptr_cmp(&cur.inset(), this));
-       MathArray const & ar = cur.cell();
-       x = ar.xo() + ar.pos2x(cur.pos());
-       y = ar.yo() + cur.bv().top_y();
+// FIXME: This is a hack. Ideally, the coord cache should not store
+// absolute positions, but relative ones. This would mean to call
+// setXY() not in MathArray::draw(), but in the parent insets' draw()
+// with the correctly adjusted x,y values. But this means that we'd have
+// to touch all (math)inset's draw() methods. Right now, we'll store
+// absolute value, and make them here relative, only to make them
+// absolute again when actually drawing the cursor. What a mess.
+       BOOST_ASSERT(ptr_cmp(&sl.inset(), this));
+       MathArray const & ar = sl.cell();
+       if (!theCoords.getArrays().has(&ar)) {
+               // this can (semi-)legally happen if we just created this cell
+               // and it never has been drawn before. So don't ASSERT.
+               //lyxerr << "no cached data for array " << &ar << endl;
+               x = 0;
+               y = 0;
+               return;
+       }
+       Point const pt = theCoords.getArrays().xy(&ar);
+       if (!theCoords.getInsets().has(this)) {
+               // same as above
+               //lyxerr << "no cached data for inset " << this << endl;
+               x = 0;
+               y = 0;
+               return;
+       }
+       Point const pt2 = theCoords.getInsets().xy(this);
+       //lyxerr << "retrieving position cache for MathArray "
+       //      << pt.x_ << ' ' << pt.y_ << std::endl;
+       x = pt.x_ - pt2.x_ + ar.pos2x(sl.pos());
+       y = pt.y_ - pt2.y_;
+//     lyxerr << "pt.y_ : " << pt.y_ << " pt2_.y_ : " << pt2.y_
+//             << " asc: " << ascent() << "  des: " << descent()
+//             << " ar.asc: " << ar.ascent() << " ar.des: " << ar.descent() << endl;
        // move cursor visually into empty cells ("blue rectangles");
-       if (cur.cell().empty())
+       if (ar.empty())
                x += 2;
 }
 
@@ -112,7 +132,7 @@ void MathNestInset::getCursorPos(LCursor const & cur, int & x, int & y) const
 void MathNestInset::metrics(MetricsInfo const & mi) const
 {
        MetricsInfo m = mi;
-       for (idx_type i = 0; i < nargs(); ++i)
+       for (idx_type i = 0, n = nargs(); i != n; ++i)
                cell(i).metrics(m);
 }
 
@@ -179,7 +199,7 @@ void MathNestInset::dump() const
        os << "---------------------------------------------\n";
        write(os);
        os << "\n";
-       for (idx_type i = 0; i < nargs(); ++i)
+       for (idx_type i = 0, n = nargs(); i != n; ++i)
                os << cell(i) << "\n";
        os << "---------------------------------------------\n";
 }
@@ -207,6 +227,7 @@ void MathNestInset::drawSelection(PainterInfo & pi, int x, int y) const
                return;
        if (!ptr_cmp(&cur.inset(), this))
                return;
+
        CursorSlice s1 = cur.selBegin();
        CursorSlice s2 = cur.selEnd();
        //lyxerr << "MathNestInset::drawing selection: "
@@ -380,7 +401,7 @@ void MathNestInset::handleFont2(LCursor & cur, string const & arg)
 }
 
 
-void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
+void MathNestInset::doDispatch(LCursor & cur, FuncRequest & cmd)
 {
        //lyxerr << "MathNestInset: request: " << cmd << std::endl;
        //CursorSlice sl = cur.current();
@@ -478,6 +499,8 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
                cur.selHandle(cmd.action == LFUN_UPSEL);
                if (!cur.up())
                        cmd = FuncRequest(LFUN_FINISHED_UP);
+               // fixes bug 1598. Please check!
+               cur.normalize();
                break;
 
        case LFUN_DOWNSEL:
@@ -485,6 +508,8 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
                cur.selHandle(cmd.action == LFUN_DOWNSEL);
                if (!cur.down())
                        cmd = FuncRequest(LFUN_FINISHED_DOWN);
+               // fixes bug 1598. Please check!
+               cur.normalize();
                break;
 
        case LFUN_MOUSE_DOUBLE:
@@ -684,9 +709,13 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
 
        case LFUN_MATH_MODE:
 #if 1
+               // ignore math-mode on when already in math mode
+               if (currentMode() == InsetBase::MATH_MODE && cmd.argument == "on")
+                       break;
                cur.macroModeClose();
                selClearOrDel(cur);
-               cur.plainInsert(MathAtom(new MathMBoxInset(cur.bv())));
+               //cur.plainInsert(MathAtom(new MathMBoxInset(cur.bv())));
+               cur.plainInsert(MathAtom(new MathBoxInset("mbox")));
                cur.posLeft();
                cur.pushLeft(*cur.nextInset());
 #else
@@ -751,6 +780,18 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
                interpret(cur, '\\');
                break;
 
+       case LFUN_SUBSCRIPT:
+               // interpret this as if a _ was typed
+               recordUndo(cur, Undo::ATOMIC);
+               interpret(cur, '_');
+               break;
+
+       case LFUN_SUPERSCRIPT:
+               // interpret this as if a ^ was typed
+               recordUndo(cur, Undo::ATOMIC);
+               interpret(cur, '^');
+               break;
+
 // FIXME: We probably should swap parts of "math-insert" and "self-insert"
 // handling such that "self-insert" works on "arbitrary stuff" too, and
 // math-insert only handles special math things like "matrix".
@@ -791,7 +832,7 @@ void MathNestInset::priv_dispatch(LCursor & cur, FuncRequest & cmd)
        }
 
        default:
-               MathDimInset::priv_dispatch(cur, cmd);
+               MathDimInset::doDispatch(cur, cmd);
                break;
        }
 }
@@ -906,11 +947,9 @@ InsetBase * MathNestInset::editXY(LCursor & cur, int x, int y) const
 
 void MathNestInset::lfunMousePress(LCursor & cur, FuncRequest & cmd)
 {
-       lyxerr << "lfunMousePress: buttons: " << cmd.button() << endl;
+       //lyxerr << "## lfunMousePress: buttons: " << cmd.button() << endl;
        if (cmd.button() == mouse_button::button1) {
-               first_x = cmd.x;
-               first_y = cmd.y;
-               lyxerr << "lfunMousePress: setting cursor to: " << cur << endl;
+               //lyxerr << "## lfunMousePress: setting cursor to: " << cur << endl;
                cur.resetAnchor();
                cur.bv().cursor() = cur;
        }
@@ -926,13 +965,14 @@ void MathNestInset::lfunMouseMotion(LCursor & cur, FuncRequest & cmd)
        // only select with button 1
        if (cmd.button() == mouse_button::button1) {
                LCursor & bvcur = cur.bv().cursor();
-               if (abs(cmd.x - first_x) + abs(cmd.y - first_y) > 4
-        && bvcur.anchor_.hasPart(cur)) {
-                       first_x = cmd.x;
-                       first_y = cmd.y;
-
+               if (bvcur.anchor_.hasPart(cur)) {
+                       //lyxerr << "## lfunMouseMotion: cursor: " << cur << endl;
                        bvcur.setCursor(cur);
                        bvcur.selection() = true;
+                       //lyxerr << "MOTION " << bvcur << endl;
+               }
+               else {
+                       cur.undispatched();
                }
        }
 }
@@ -940,7 +980,7 @@ void MathNestInset::lfunMouseMotion(LCursor & cur, FuncRequest & cmd)
 
 void MathNestInset::lfunMouseRelease(LCursor & cur, FuncRequest & cmd)
 {
-       lyxerr << "lfunMouseRelease: buttons: " << cmd.button() << endl;
+       //lyxerr << "## lfunMouseRelease: buttons: " << cmd.button() << endl;
 
        if (cmd.button() == mouse_button::button1) {
                //cur.bv().stuffClipboard(cur.grabSelection());