A bit more re-organization.
[lyx.git] / src / mathed / InsetMathSpace.cpp
blob00435ddc792ea69baa7f4c3d61c1a677f6e82a35
1 /**
2 * \file InsetMathSpace.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author André Pönitz
8 * Full author contact details are available in file CREDITS.
9 */
11 #include <config.h>
13 #include "InsetMathSpace.h"
14 #include "MathData.h"
15 #include "MathFactory.h"
16 #include "MathStream.h"
17 #include "MathSupport.h"
19 #include "BufferView.h"
20 #include "Cursor.h"
21 #include "FuncRequest.h"
22 #include "FuncStatus.h"
23 #include "LaTeXFeatures.h"
25 #include "insets/InsetSpace.h"
27 #include "frontends/Application.h"
28 #include "frontends/Painter.h"
30 #include "support/lassert.h"
32 using namespace std;
34 namespace lyx {
36 namespace {
38 struct SpaceInfo {
39 string name;
40 int width;
41 InsetSpaceParams::Kind kind;
42 bool negative;
43 bool visible;
44 bool custom;
47 SpaceInfo space_info[] = {
48 // name width kind negative visible custom
49 {"!", 6, InsetSpaceParams::NEGTHIN, true, true, false},
50 {"negthinspace", 6, InsetSpaceParams::NEGTHIN, true, true, false},
51 {"negmedspace", 8, InsetSpaceParams::NEGMEDIUM, true, true, false},
52 {"negthickspace", 10, InsetSpaceParams::NEGTHICK, true, true, false},
53 {",", 6, InsetSpaceParams::THIN, false, true, false},
54 {"thinspace", 6, InsetSpaceParams::THIN, false, true, false},
55 {":", 8, InsetSpaceParams::MEDIUM, false, true, false},
56 {"medspace", 8, InsetSpaceParams::MEDIUM, false, true, false},
57 {";", 10, InsetSpaceParams::THICK, false, true, false},
58 {"thickspace", 10, InsetSpaceParams::THICK, false, true, false},
59 {"enskip", 10, InsetSpaceParams::ENSKIP, false, true, false},
60 {"quad", 20, InsetSpaceParams::QUAD, false, true, false},
61 {"qquad", 40, InsetSpaceParams::QQUAD, false, true, false},
62 {"lyxnegspace", -2, InsetSpaceParams::NEGTHIN, true, false, false},
63 {"lyxposspace", 2, InsetSpaceParams::THIN, false, false, false},
64 {"hspace", 0, InsetSpaceParams::CUSTOM, false, true, true},
67 int const nSpace = sizeof(space_info)/sizeof(SpaceInfo);
68 int const defaultSpace = 4;
70 } // anon namespace
72 InsetMathSpace::InsetMathSpace()
73 : space_(defaultSpace)
78 InsetMathSpace::InsetMathSpace(string const & name, string const & length)
79 : space_(defaultSpace)
81 for (int i = 0; i < nSpace; ++i)
82 if (space_info[i].name == name) {
83 space_ = i;
84 break;
86 if (space_info[space_].custom) {
87 length_ = Length(length);
88 if (length_.zero() || length_.empty()) {
89 length_.value(1.0);
90 length_.unit(Length::EM);
96 InsetMathSpace::InsetMathSpace(Length const & length)
97 : space_(defaultSpace), length_(length)
99 for (int i = 0; i < nSpace; ++i)
100 if (space_info[i].name == "hspace") {
101 space_ = i;
102 break;
107 InsetMathSpace::~InsetMathSpace()
109 hideDialogs("mathspace", this);
113 Inset * InsetMathSpace::clone() const
115 return new InsetMathSpace(*this);
119 void InsetMathSpace::metrics(MetricsInfo & mi, Dimension & dim) const
121 dim.asc = 4;
122 dim.des = 0;
123 if (space_info[space_].custom)
124 dim.wid = abs(length_.inPixels(
125 mi.base.textwidth,
126 mathed_char_width(mi.base.font, 'M')));
127 else
128 dim.wid = space_info[space_].width;
132 void InsetMathSpace::draw(PainterInfo & pi, int x, int y) const
134 // Sadly, HP-UX CC can't handle that kind of initialization.
135 // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
136 if (!space_info[space_].visible)
137 return;
139 Dimension const dim = dimension(*pi.base.bv);
140 int xp[4];
141 int yp[4];
142 int w = dim.wid;
144 xp[0] = ++x; yp[0] = y - 3;
145 xp[1] = x; yp[1] = y;
146 xp[2] = x + w - 2; yp[2] = y;
147 xp[3] = x + w - 2; yp[3] = y - 3;
149 pi.pain.lines(xp, yp, 4,
150 space_info[space_].custom ?
151 Color_special :
152 (isNegative() ? Color_latex : Color_math));
156 void InsetMathSpace::incSpace()
158 int const oldwidth = space_info[space_].width;
160 space_ = (space_ + 1) % nSpace;
161 while ((space_info[space_].width == oldwidth && !space_info[space_].custom) ||
162 !space_info[space_].visible);
163 if (space_info[space_].custom && (length_.zero() || length_.empty())) {
164 length_.value(1.0);
165 length_.unit(Length::EM);
170 void InsetMathSpace::validate(LaTeXFeatures & features) const
172 if (space_info[space_].name == "negmedspace" ||
173 space_info[space_].name == "negthickspace")
174 features.require("amsmath");
178 void InsetMathSpace::maple(MapleStream & os) const
180 os << ' ';
183 void InsetMathSpace::mathematica(MathematicaStream & os) const
185 os << ' ';
189 void InsetMathSpace::octave(OctaveStream & os) const
191 os << ' ';
195 void InsetMathSpace::normalize(NormalStream & os) const
197 os << "[space " << int(space_) << "] ";
201 void InsetMathSpace::write(WriteStream & os) const
203 // no MathEnsurer - all kinds work in text and math mode
204 os << '\\' << space_info[space_].name.c_str();
205 if (space_info[space_].custom)
206 os << '{' << length_.asLatexString().c_str() << '}';
207 else
208 os.pendingSpace(true);
212 string const InsetMathSpace::createDialogStr() const
214 LASSERT(space_info[space_].visible, /**/);
215 InsetSpaceParams isp(true);
216 isp.kind = space_info[space_].kind;
217 isp.length = GlueLength(length_);
218 return InsetSpace::params2string(isp);
222 docstring InsetMathSpace::contextMenu(BufferView const &, int, int) const
224 return from_ascii("context-mathspace");
228 bool InsetMathSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
229 FuncStatus & status) const
231 switch (cmd.action) {
232 // we handle these
233 case LFUN_INSET_MODIFY:
234 case LFUN_INSET_DIALOG_UPDATE:
235 case LFUN_MOUSE_RELEASE:
236 case LFUN_MOUSE_PRESS:
237 case LFUN_MOUSE_MOTION:
238 status.setEnabled(true);
239 return true;
240 default:
241 bool retval = InsetMath::getStatus(cur, cmd, status);
242 return retval;
247 void InsetMathSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
249 switch (cmd.action) {
250 case LFUN_INSET_MODIFY:
251 if (cmd.getArg(0) == "mathspace") {
252 MathData ar;
253 if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
254 *this = *ar[0].nucleus()->asSpaceInset();
255 break;
258 cur.undispatched();
259 break;
261 case LFUN_INSET_DIALOG_UPDATE:
262 cur.bv().updateDialog("mathspace", createDialogStr());
263 break;
265 case LFUN_MOUSE_RELEASE:
266 if (cmd.button() == mouse_button::button1) {
267 string const data = createDialogStr();
268 cur.bv().showDialog("mathspace", data, this);
269 break;
271 cur.undispatched();
272 break;
274 case LFUN_MOUSE_PRESS:
275 case LFUN_MOUSE_MOTION:
276 // eat other mouse commands
277 break;
279 default:
280 InsetMath::doDispatch(cur, cmd);
281 break;
286 bool InsetMathSpace::isNegative() const
288 if (space_info[space_].custom)
289 return length_.value() < 0;
290 return space_info[space_].negative;
293 } // namespace lyx