]> git.lyx.org Git - lyx.git/blob - src/mathed/math_xdata.C
Tweaking of the math panel dialogs from Martin...
[lyx.git] / src / mathed / math_xdata.C
1 #include <config.h>
2
3 #ifdef __GNUG__
4 #pragma implementation
5 #endif
6
7 #include "math_scriptinset.h"
8 #include "math_support.h"
9 #include "Painter.h"
10 #include "debug.h"
11
12
13 using std::max;
14 using std::min;
15
16
17 extern MathScriptInset const * asScript(MathArray::const_iterator it);
18
19
20 MathXArray::MathXArray()
21         : width_(0), ascent_(0), descent_(0), xo_(0), yo_(0), size_()
22 {}
23
24
25 void MathXArray::metrics(MathMetricsInfo const & mi) const
26 {
27         size_ = mi;
28
29         if (data_.empty()) {
30                 mathed_char_dim(LM_TC_VAR, mi, 'I', ascent_, descent_, width_);
31                 return;
32         }
33
34         ascent_  = 0;
35         descent_ = 0;
36         width_   = 0;
37
38         for (const_iterator it = begin(); it != end(); ++it) {
39                 MathInset const * p = it->nucleus();
40                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
41                 if (q) {
42                         q->metrics(p, mi);
43                         ascent_  = max(ascent_,  q->ascent2(p));
44                         descent_ = max(descent_, q->descent2(p));
45                         width_  += q->width2(p);        
46                         ++it;
47                 } else {
48                         p->metrics(mi);
49                         ascent_  = max(ascent_,  p->ascent());
50                         descent_ = max(descent_, p->descent());
51                         width_  += p->width();  
52                 }
53         }
54         //lyxerr << "MathXArray::metrics(): '" << ascent_ << " " 
55         //      << descent_ << " " << width_ << "'\n";
56 }
57
58
59 void MathXArray::draw(Painter & pain, int x, int y) const
60 {
61         xo_ = x;
62         yo_ = y;
63
64         if (data_.empty()) {
65                 pain.rectangle(x, y - ascent_, width_, height(), LColor::mathline);
66                 return;
67         }
68
69         for (const_iterator it = begin(); it != end(); ++it) {
70                 MathInset const * p = it->nucleus();
71                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
72                 if (q) {
73                         q->draw(p, pain, x, y);
74                         x += q->width2(p);
75                         ++it;
76                 } else {
77                         p->draw(pain, x, y);
78                         x += p->width();
79                 }
80         }
81 }
82
83
84 int MathXArray::pos2x(size_type targetpos) const
85 {
86         int x = 0;
87         const_iterator target = min(begin() + targetpos, end());
88         for (const_iterator it = begin(); it < target; ++it) {
89                 MathInset const * p = it->nucleus();
90                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
91                 if (q) {
92                         ++it;
93                         if (it < target)
94                                 x += q->width2(p);
95                         else  // "half" position
96                                 x += q->dxx(p) + q->nwid(p);
97                 } else
98                         x += p->width();
99         }
100         return x;
101 }
102
103
104 MathArray::size_type MathXArray::x2pos(int targetx) const
105 {
106         const_iterator it = begin();
107         int lastx = 0;
108         int currx = 0;
109         for (; currx < targetx && it < end(); ++it) {
110                 lastx = currx;
111
112                 int wid = 0;
113                 MathInset const * p = it->nucleus();
114                 MathScriptInset const * q = 0;
115                 if (it + 1 != end())
116                         q = asScript(it);
117                 if (q) {
118                         wid = q->width2(p);
119                         ++it;
120                 } else
121                         wid = p->width();
122
123                 currx += wid;
124         }
125         if (abs(lastx - targetx) < abs(currx - targetx) && it != begin())
126                 --it;
127         return it - begin();
128 }
129
130
131 int MathXArray::dist(int x, int y) const
132 {
133         int xx = 0;
134         int yy = 0;
135
136         if (x < xo_)
137                 xx = xo_ - x;
138         else if (x > xo_ + width_)
139                 xx = x - xo_ - width_;
140
141         if (y < yo_ - ascent_)
142                 yy = yo_ - ascent_ - y;
143         else if (y > yo_ + descent_)
144                 yy = y - yo_ - descent_;
145
146         return xx + yy; 
147 }
148
149
150 void MathXArray::boundingBox(int & x1, int & x2, int & y1, int & y2)
151 {
152         x1 = xo_;
153         x2 = xo_ + width_;
154         y1 = yo_ - ascent_;
155         y2 = yo_ + descent_;
156 }
157
158 /*
159 void MathXArray::findPos(MathPosFinder & f) const
160 {
161         double x = xo_;
162         double y = yo_; 
163         for (const_iterator it = begin(); it < end(); ++it) {
164                 // check this position in the cell first
165                 f.visit(x, y);
166                 f.nextPos();
167
168                 // check inset
169                 MathInset const * p = it->nucleus();
170                 p->findPos(f);
171
172                 // move on
173                 MathScriptInset const * q = (it + 1 == end()) ? 0 : asScript(it);
174                 if (q) {
175                         x += q->width(p);
176                         f.nextPos();
177                         ++it;
178                 } else {
179                         x += p->width();
180                 }
181         }
182 }
183 */
184
185 void MathXArray::center(int & x, int & y) const
186 {
187         x = xo_ + width_ / 2;
188         y = yo_ + (descent_ - ascent_) / 2;
189 }
190
191
192 void MathXArray::towards(int & x, int & y) const
193 {
194         int cx = 0;
195         int cy = 0;
196         center(cx, cy);
197
198         double r = 1.0;
199         //int dist = (x - cx) * (x - cx) + (y - cy) * (y - cy);
200
201         x = cx + int(r * (x - cx));
202         y = cy + int(r * (y - cy));
203 }