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