]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/InsetMathSpace.cpp
Reduce horizontal spacing for simple inline equations
[lyx.git] / src / mathed / InsetMathSpace.cpp
index 985e93f12784adc0040e311960fdf3df19da5a10..0adce6ff28e3458b21813ee0c558903c9d102703 100644 (file)
@@ -21,6 +21,7 @@
 #include "FuncRequest.h"
 #include "FuncStatus.h"
 #include "LaTeXFeatures.h"
+#include "MetricsInfo.h"
 
 #include "insets/InsetSpace.h"
 
@@ -42,26 +43,33 @@ struct SpaceInfo {
        bool negative;
        bool visible;
        bool custom;
+       bool escape; ///< whether a backslash needs to be added for writing
 };
 
 SpaceInfo space_info[] = {
-       // name           width kind                         negative visible custom
-       {"!",              6,   InsetSpaceParams::NEGTHIN,   true,    true,   false},
-       {"negthinspace",   6,   InsetSpaceParams::NEGTHIN,   true,    true,   false},
-       {"negmedspace",    8,   InsetSpaceParams::NEGMEDIUM, true,    true,   false},
-       {"negthickspace", 10,   InsetSpaceParams::NEGTHICK,  true,    true,   false},
-       {",",              6,   InsetSpaceParams::THIN,      false,   true,   false},
-       {"thinspace",      6,   InsetSpaceParams::THIN,      false,   true,   false},
-       {":",              8,   InsetSpaceParams::MEDIUM,    false,   true,   false},
-       {"medspace",       8,   InsetSpaceParams::MEDIUM,    false,   true,   false},
-       {";",             10,   InsetSpaceParams::THICK,     false,   true,   false},
-       {"thickspace",    10,   InsetSpaceParams::THICK,     false,   true,   false},
-       {"enskip",        10,   InsetSpaceParams::ENSKIP,    false,   true,   false},
-       {"quad",          20,   InsetSpaceParams::QUAD,      false,   true,   false},
-       {"qquad",         40,   InsetSpaceParams::QQUAD,     false,   true,   false},
-       {"lyxnegspace",   -2,   InsetSpaceParams::NEGTHIN,   true,    false,  false},
-       {"lyxposspace",    2,   InsetSpaceParams::THIN,      false,   false,  false},
-       {"hspace",         0,   InsetSpaceParams::CUSTOM,    false,   true,   true},
+       // name           width kind                            negative visible custom escape
+       {"!",                6, InsetSpaceParams::NEGTHIN,         true,  true,  false, true},
+       {"negthinspace",     6, InsetSpaceParams::NEGTHIN,         true,  true,  false, true},
+       {"negmedspace",      8, InsetSpaceParams::NEGMEDIUM,       true,  true,  false, true},
+       {"negthickspace",   10, InsetSpaceParams::NEGTHICK,        true,  true,  false, true},
+       {",",                6, InsetSpaceParams::THIN,            false, true,  false, true},
+       {"thinspace",        6, InsetSpaceParams::THIN,            false, true,  false, true},
+       {":",                8, InsetSpaceParams::MEDIUM,          false, true,  false, true},
+       {"medspace",         8, InsetSpaceParams::MEDIUM,          false, true,  false, true},
+       {";",               10, InsetSpaceParams::THICK,           false, true,  false, true},
+       {"thickspace",      10, InsetSpaceParams::THICK,           false, true,  false, true},
+       {"enskip",          10, InsetSpaceParams::ENSKIP,          false, true,  false, true},
+       {"enspace",         10, InsetSpaceParams::ENSPACE,         false, true,  false, true},
+       {"quad",            20, InsetSpaceParams::QUAD,            false, true,  false, true},
+       {"qquad",           40, InsetSpaceParams::QQUAD,           false, true,  false, true},
+       {"lyxnegspace",     -2, InsetSpaceParams::NEGTHIN,         true,  false, false, true},
+       {"lyxposspace",      2, InsetSpaceParams::THIN,            false, false, false, true},
+       {"hfill",           80, InsetSpaceParams::HFILL,           false, true,  false, true},
+       {"hspace*{\\fill}", 80, InsetSpaceParams::HFILL_PROTECTED, false, true,  false, true},
+       {"hspace*",          0, InsetSpaceParams::CUSTOM_PROTECTED,false, true,  true,  true},
+       {"hspace",           0, InsetSpaceParams::CUSTOM,          false, true,  true,  true},
+       {" ",               10, InsetSpaceParams::NORMAL,          false, true,  false, true},
+       {"~",               10, InsetSpaceParams::PROTECTED,       false, true,  false, false},
 };
 
 int const nSpace = sizeof(space_info)/sizeof(SpaceInfo);
@@ -93,11 +101,12 @@ InsetMathSpace::InsetMathSpace(string const & name, string const & length)
 }
 
 
-InsetMathSpace::InsetMathSpace(Length const & length)
+InsetMathSpace::InsetMathSpace(Length const & length, bool const prot)
        : space_(defaultSpace), length_(length)
 {
        for (int i = 0; i < nSpace; ++i)
-               if (space_info[i].name == "hspace") {
+               if ((prot && space_info[i].name == "hspace*")
+                       || (!prot && space_info[i].name == "hspace")) {
                        space_ = i;
                        break;
                }
@@ -112,12 +121,11 @@ Inset * InsetMathSpace::clone() const
 
 void InsetMathSpace::metrics(MetricsInfo & mi, Dimension & dim) const
 {
+       Changer dummy = mi.base.changeEnsureMath();
        dim.asc = 4;
        dim.des = 0;
        if (space_info[space_].custom)
-               dim.wid = abs(length_.inPixels(
-                               mi.base.textwidth,
-                               mathed_char_width(mi.base.font, 'M')));
+               dim.wid = abs(length_.inPixels(mi.base));
        else
                dim.wid = space_info[space_].width;
 }
@@ -125,6 +133,7 @@ void InsetMathSpace::metrics(MetricsInfo & mi, Dimension & dim) const
 
 void InsetMathSpace::draw(PainterInfo & pi, int x, int y) const
 {
+       Changer dummy = pi.base.changeEnsureMath();
        // Sadly, HP-UX CC can't handle that kind of initialization.
        // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
        if (!space_info[space_].visible)
@@ -221,6 +230,7 @@ void InsetMathSpace::htmlize(HtmlStream & ms) const
                ms << from_ascii("&emsp;");
                break;
        case InsetSpaceParams::ENSKIP:
+       case InsetSpaceParams::ENSPACE:
                ms << from_ascii("&ensp;");
                break;
        case InsetSpaceParams::QUAD:
@@ -229,12 +239,21 @@ void InsetMathSpace::htmlize(HtmlStream & ms) const
        case InsetSpaceParams::QQUAD:
                ms << from_ascii("&emsp;&emsp;");
                break;
-       case InsetSpaceParams::CUSTOM: {
+       case InsetSpaceParams::HFILL:
+       case InsetSpaceParams::HFILL_PROTECTED:
+               // FIXME: is there a useful HTML entity?
+               break;
+       case InsetSpaceParams::CUSTOM:
+       case InsetSpaceParams::CUSTOM_PROTECTED: {
                string l = length_.asHTMLString();
                ms << MTag("span", "width='" + l + "'") 
                   << from_ascii("&nbsp;") << ETag("span");
                break;
        }
+       case InsetSpaceParams::NORMAL:
+       case InsetSpaceParams::PROTECTED:
+               ms << from_ascii("&nbsp;");
+               break;
        default:
                break;
        }
@@ -249,41 +268,43 @@ void InsetMathSpace::normalize(NormalStream & os) const
 
 void InsetMathSpace::write(WriteStream & os) const
 {
-       // no MathEnsurer - all kinds work in text and math mode
-       os << '\\' << space_info[space_].name.c_str();
+       // All kinds work in text and math mode, so simply suspend
+       // writing a possibly pending mode closing brace.
+       MathEnsurer ensurer(os, false);
+       if (space_info[space_].escape)
+               os << '\\';
+       os << space_info[space_].name.c_str();
        if (space_info[space_].custom)
                os << '{' << length_.asLatexString().c_str() << '}';
-       else
+       else if (space_info[space_].escape && space_info[space_].name.length() > 1)
                os.pendingSpace(true);
 }
 
 
 InsetSpaceParams InsetMathSpace::params() const
 {
-       LASSERT(space_info[space_].visible, /**/);
        InsetSpaceParams isp(true);
+       LASSERT(space_info[space_].visible, return isp);
        isp.kind = space_info[space_].kind;
        isp.length = GlueLength(length_);
        return isp;
 }
 
 
-docstring InsetMathSpace::contextMenu(BufferView const &, int, int) const
+string InsetMathSpace::contextMenuName() const
 {
-       return from_ascii("context-mathspace");
+       return "context-mathspace";
 }
 
 
 bool InsetMathSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
                                FuncStatus & status) const
 {
-       switch (cmd.action) {
+       switch (cmd.action()) {
        // we handle these
        case LFUN_INSET_MODIFY:
        case LFUN_INSET_DIALOG_UPDATE:
        case LFUN_MOUSE_RELEASE:
-       case LFUN_MOUSE_PRESS:
-       case LFUN_MOUSE_MOTION:
                status.setEnabled(true);
                return true;
        default:
@@ -295,11 +316,12 @@ bool InsetMathSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
 
 void InsetMathSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
-       switch (cmd.action) {
+       switch (cmd.action()) {
        case LFUN_INSET_MODIFY:
                if (cmd.getArg(0) == "mathspace") {
                        MathData ar;
                        if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
+                               cur.recordUndo();
                                *this = *ar[0].nucleus()->asSpaceInset();
                                break;
                        }
@@ -308,18 +330,13 @@ void InsetMathSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
                break;
 
        case LFUN_MOUSE_RELEASE:
-               if (cmd.button() == mouse_button::button1) {
+               if (cmd.button() == mouse_button::button1 && !cur.selection()) {
                        showInsetDialog(&cur.bv());
                        break;
                }
                cur.undispatched();
                break;
 
-       case LFUN_MOUSE_PRESS:
-       case LFUN_MOUSE_MOTION:
-               // eat other mouse commands
-               break;
-
        default:
                InsetMath::doDispatch(cur, cmd);
                break;