]> git.lyx.org Git - lyx.git/blob - src/mathed/math_nestinset.C
small up/down tweaking
[lyx.git] / src / mathed / math_nestinset.C
1 #ifdef __GNUG__
2 #pragma implementation
3 #endif
4
5 #include "math_nestinset.h"
6 #include "math_cursor.h"
7 #include "math_mathmlstream.h"
8 #include "math_parser.h"
9 #include "funcrequest.h"
10 #include "debug.h"
11 #include "BufferView.h"
12 #include "frontends/Painter.h"
13
14
15 MathNestInset::MathNestInset(idx_type nargs)
16         : MathDimInset(), cells_(nargs), lock_(false)
17 {}
18
19
20 MathInset::idx_type MathNestInset::nargs() const
21 {
22         return cells_.size();
23 }
24
25
26 MathArray & MathNestInset::cell(idx_type i)
27 {
28         return cells_[i];
29 }
30
31
32 MathArray const & MathNestInset::cell(idx_type i) const
33 {
34         return cells_[i];
35 }
36
37
38 void MathNestInset::getPos(idx_type idx, pos_type pos, int & x, int & y) const
39 {
40         MathArray const & ar = cell(idx);
41         x = ar.xo() + ar.pos2x(pos);
42         y = ar.yo();
43         // move cursor visually into empty cells ("blue rectangles");
44         if (cell(idx).empty())
45                 x += 2;
46 }
47
48
49 void MathNestInset::substitute(MathMacro const & m)
50 {
51         for (idx_type i = 0; i < nargs(); ++i)
52                 cell(i).substitute(m);
53 }
54
55
56 void MathNestInset::metrics(MathMetricsInfo const & mi) const
57 {
58         MathMetricsInfo m = mi;
59         for (idx_type i = 0; i < nargs(); ++i)
60                 cell(i).metrics(m);
61 }
62
63
64 void MathNestInset::metricsMarkers(int frame) const
65 {
66         dim_.d += frame;
67         dim_.w += 2 * frame;
68 }
69
70
71 void MathNestInset::metricsMarkers2(int frame) const
72 {
73         dim_.a += frame;
74         dim_.d += frame;
75         dim_.w += 2 * frame;
76 }
77
78
79 bool MathNestInset::idxNext(idx_type & idx, pos_type & pos) const
80 {
81         if (idx + 1 >= nargs())
82                 return false;
83         ++idx;
84         pos = 0;
85         return true;
86 }
87
88
89 bool MathNestInset::idxRight(idx_type & idx, pos_type & pos) const
90 {
91         return idxNext(idx, pos);
92 }
93
94
95 bool MathNestInset::idxPrev(idx_type & idx, pos_type & pos) const
96 {
97         if (idx == 0)
98                 return false;
99         --idx;
100         pos = cell(idx).size();
101         return true;
102 }
103
104
105 bool MathNestInset::idxLeft(idx_type & idx, pos_type & pos) const
106 {
107         return idxPrev(idx, pos);
108 }
109
110
111 bool MathNestInset::idxFirst(idx_type & i, pos_type & pos) const
112 {
113         if (nargs() == 0)
114                 return false;
115         i = 0;
116         pos = 0;
117         return true;
118 }
119
120
121 bool MathNestInset::idxLast(idx_type & i, pos_type & pos) const
122 {
123         if (nargs() == 0)
124                 return false;
125         i = nargs() - 1;
126         pos = cell(i).size();
127         return true;
128 }
129
130
131 bool MathNestInset::idxHome(idx_type & /* idx */, pos_type & pos) const
132 {
133         if (pos == 0)
134                 return false;
135         pos = 0;
136         return true;
137 }
138
139
140 bool MathNestInset::idxEnd(idx_type & idx, pos_type & pos) const
141 {
142         pos_type n = cell(idx).size();
143         if (pos == n)
144                 return false;
145         pos = n;
146         return true;
147 }
148
149
150 void MathNestInset::dump() const
151 {
152         WriteStream os(lyxerr);
153         os << "---------------------------------------------\n";
154         write(os);
155         os << "\n";
156         for (idx_type i = 0; i < nargs(); ++i)
157                 os << cell(i) << "\n";
158         os << "---------------------------------------------\n";
159 }
160
161
162 //void MathNestInset::draw(MathPainterInfo & pi, int x, int y) const
163 void MathNestInset::draw(MathPainterInfo &, int, int) const
164 {
165 #if 0
166         if (lock_)
167                 pi.pain.fillRectangle(x, y - ascent(), width(), height(),
168                                         LColor::mathlockbg);
169 #endif
170 }
171
172
173 void MathNestInset::drawSelection(MathPainterInfo & pi,
174                 idx_type idx1, pos_type pos1, idx_type idx2, pos_type pos2) const
175 {
176         if (idx1 == idx2) {
177                 MathArray const & c = cell(idx1);
178                 int x1 = c.xo() + c.pos2x(pos1);
179                 int y1 = c.yo() - c.ascent();
180                 int x2 = c.xo() + c.pos2x(pos2);
181                 int y2 = c.yo() + c.descent();
182                 pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
183         } else {
184                 for (idx_type i = 0; i < nargs(); ++i) {
185                         if (idxBetween(i, idx1, idx2)) {
186                                 MathArray const & c = cell(i);
187                                 int x1 = c.xo();
188                                 int y1 = c.yo() - c.ascent();
189                                 int x2 = c.xo() + c.width();
190                                 int y2 = c.yo() + c.descent();
191                                 pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, LColor::selection);
192                         }
193                 }
194         }
195 }
196
197
198 void MathNestInset::drawMarkers(MathPainterInfo & pi, int x, int y) const
199 {
200         if (!editing())
201                 return;
202         int t = x + width() - 1;
203         int d = y + descent();
204         pi.pain.line(x, d - 3, x, d, LColor::mathframe);
205         pi.pain.line(t, d - 3, t, d, LColor::mathframe);
206         pi.pain.line(x, d, x + 3, d, LColor::mathframe);
207         pi.pain.line(t - 2, d, t, d, LColor::mathframe);
208 }
209
210
211 void MathNestInset::drawMarkers2(MathPainterInfo & pi, int x, int y) const
212 {
213         if (!editing())
214                 return;
215         drawMarkers(pi, x, y);
216         int t = x + width() - 1;
217         int a = y - ascent();
218         pi.pain.line(x, a + 3, x, a, LColor::mathframe);
219         pi.pain.line(t, a + 3, t, a, LColor::mathframe);
220         pi.pain.line(x, a, x + 3, a, LColor::mathframe);
221         pi.pain.line(t - 2, a, t, a, LColor::mathframe);
222 }
223
224
225 void MathNestInset::validate(LaTeXFeatures & features) const
226 {
227         for (idx_type i = 0; i < nargs(); ++i)
228                 cell(i).validate(features);
229 }
230
231
232 bool MathNestInset::match(MathAtom const & at) const
233 {
234         if (nargs() != at->nargs())
235                 return false;
236         for (idx_type i = 0; i < nargs(); ++i)
237                 if (!cell(i).match(at->cell(i)))
238                         return false;
239         return true;
240 }
241
242
243 void MathNestInset::replace(ReplaceData & rep)
244 {
245         for (idx_type i = 0; i < nargs(); ++i)
246                 cell(i).replace(rep);
247 }
248
249
250 bool MathNestInset::contains(MathArray const & ar) const
251 {
252         for (idx_type i = 0; i < nargs(); ++i)
253                 if (cell(i).contains(ar))
254                         return true;
255         return false;
256 }
257
258
259 bool MathNestInset::editing() const
260 {
261         return mathcursor && mathcursor->isInside(this);
262 }
263
264
265 bool MathNestInset::lock() const
266 {
267         return lock_;
268 }
269
270
271 void MathNestInset::lock(bool l)
272 {
273         lock_ = l;
274 }
275
276
277 bool MathNestInset::isActive() const
278 {
279         return nargs() > 0;
280 }
281
282
283 MathArray MathNestInset::glue() const
284 {
285         MathArray ar;
286         for (unsigned i = 0; i < nargs(); ++i)
287                 ar.append(cell(i));
288         return ar;
289 }
290
291
292 void MathNestInset::write(WriteStream & os) const
293 {
294         os << '\\' << name().c_str();
295         for (unsigned i = 0; i < nargs(); ++i)
296                 os << '{' << cell(i) << '}';
297         if (nargs() == 0)
298                 os.pendingSpace(true);
299         if (lock_ && !os.latex()) {
300                 os << "\\lyxlock";
301                 os.pendingSpace(true);
302         }
303 }
304
305
306 void MathNestInset::normalize(NormalStream & os) const
307 {
308         os << '[' << name().c_str();
309         for (unsigned i = 0; i < nargs(); ++i)
310                 os << ' ' << cell(i);
311         os << ']';
312 }
313
314
315 void MathNestInset::notifyCursorLeaves(idx_type idx)
316 {
317         cell(idx).notifyCursorLeaves();
318 }
319
320
321 MathInset::result_type MathNestInset::dispatch
322         (FuncRequest const & cmd, idx_type & idx, pos_type & pos)
323 {
324         BufferView * bv = cmd.view();
325
326         switch (cmd.action) {
327
328                 case LFUN_PASTE: {
329                         MathArray ar;
330                         mathed_parse_cell(ar, cmd.argument);
331                         cell(idx).insert(pos, ar);
332                         pos += ar.size();
333                         return DISPATCHED;
334                 }
335
336                 case LFUN_PASTESELECTION:
337                         return
338                                 dispatch(
339                                         FuncRequest(bv, LFUN_PASTE, bv->getClipboard()), idx, pos);
340
341                 case LFUN_MOUSE_PRESS:
342                         if (cmd.button() == mouse_button::button2)
343                                 return dispatch(FuncRequest(bv, LFUN_PASTESELECTION), idx, pos);
344                         return UNDISPATCHED;
345
346                 default:
347                         return MathInset::dispatch(cmd, idx, pos);
348         }
349         return UNDISPATCHED;
350 }