8 #include "support/LOstream.h"
16 int const MATH_COLSEP = 10;
18 int const MATH_ROWSEP = 10;
20 int const MATH_BORDER = 2;
25 MathGridInset::RowInfo::RowInfo()
26 : upperline_(false), lowerline_(false)
30 MathGridInset::ColInfo::ColInfo()
31 : h_align_('c'), leftline_(false), rightline_(false)
35 MathGridInset::MathGridInset(int m, int n, string const & nm, MathInsetTypes ot)
36 : MathInset(nm, ot, m * n), rowinfo_(n), colinfo_(m), v_align_('c')
39 lyxerr << "positve number of columns expected\n";
41 lyxerr << "positve number of rows expected\n";
45 int MathGridInset::index(int row, int col) const
47 return col + ncols() * row;
51 void MathGridInset::halign(string const & hh)
56 for (int i = 0; i < n; ++i)
57 colinfo_[i].h_align_ = hh[i];
60 void MathGridInset::halign(char h, int col)
62 colinfo_[col].h_align_ = h;
65 char MathGridInset::halign(int col) const
67 return colinfo_[col].h_align_;
70 void MathGridInset::valign(char c)
75 char MathGridInset::valign() const
80 void MathGridInset::Metrics(MathStyles st)
82 // let the cells adjust themselves
83 MathInset::Metrics(st);
86 // adjust vertical structure
87 for (int row = 0; row < nrows(); ++row) {
90 for (int col = 0; col < ncols(); ++col) {
91 MathXArray const & c = xcell(index(row, col));
92 asc = std::max(asc, c.ascent());
93 desc = std::max(desc, c.descent());
95 rowinfo_[row].ascent_ = asc;
96 rowinfo_[row].descent_ = desc;
99 rowinfo_[row].offset_ =
100 rowinfo_[row - 1].offset_ +
101 rowinfo_[row - 1].descent_ +
103 rowinfo_[row].ascent_;
105 rowinfo_[row].offset_ = 0;
108 // adjust vertical offset
115 h = rowinfo_.back().offset_;
118 h = rowinfo_.back().offset_ / 2;
121 for (int row = 0; row < nrows(); ++row) {
122 rowinfo_[row].offset_ -= h;
123 rowinfo_[row].offset_ += MATH_BORDER;
126 // adjust horizontal structure
127 for (int col = 0; col < ncols(); ++col) {
129 for (int row = 0; row < nrows(); ++row)
130 wid = std::max(wid, xcell(index(row, col)).width());
131 colinfo_[col].width_ = wid;
132 colinfo_[col].offset_ = colinfo_[col].width_;
135 colinfo_[col].offset_ =
136 colinfo_[col - 1].offset_ + colinfo_[col - 1].width_ + MATH_COLSEP;
138 colinfo_[col].offset_ = 0;
140 colinfo_[col].offset_ += MATH_BORDER;
143 width_ = colinfo_.back().offset_ + colinfo_.back().width_;
144 ascent_ = - rowinfo_.front().offset_ + rowinfo_.front().ascent_;
145 descent_ = rowinfo_.back().offset_ + rowinfo_.back().descent_;
148 // Increase ws_[i] for 'R' columns (except the first one)
149 for (int i = 1; i < nc_; ++i)
150 if (h_align_[i] == 'R')
151 ws_[i] += 10 * df_width;
152 // Increase ws_[i] for 'C' column
153 if (h_align_[0] == 'C')
154 if (ws_[0] < 7 * workwidth / 8)
155 ws_[0] = 7 * workwidth / 8;
159 for (cxrow = row_.begin(); cxrow; ++cxrow) {
160 int rg = MATH_COLSEP;
162 for (int i = 0; i < nc_; ++i) {
164 if (cxrow->getTab(i) <= 0) {
165 cxrow->setTab(i, df_width);
168 switch (h_align_[i]) {
173 lf = (ws_[i] - cxrow->getTab(i))/2;
177 lf = ws_[i] - cxrow->getTab(i);
180 if (cxrow == row_.begin())
182 else if (cxrow.is_last())
183 lf = ws_[i] - cxrow->getTab(i);
185 lf = (ws_[i] - cxrow->getTab(i))/2;
188 int const ww = (isvoid) ? lf : lf + cxrow->getTab(i);
189 cxrow->setTab(i, lf + rg);
190 rg = ws_[i] - ww + MATH_COLSEP;
191 if (cxrow == row_.begin())
192 width += ws_[i] + MATH_COLSEP;
194 cxrow->setBaseline(cxrow->getBaseline() - ascent);
199 void MathGridInset::draw(Painter & pain, int x, int y)
203 for (int row = 0; row < nrows(); ++row) {
204 int yy = y + rowinfo_[row].offset_;
205 for (int col = 0; col < ncols(); ++col) {
206 int xx = x + colinfo_[col].offset_;
207 char align = colinfo_[col].h_align_;
208 if (align == 'r' || align == 'R')
209 xx += colinfo_[col].width_ - xcell(index(row, col)).width();
210 if (align == 'c' || align == 'C')
211 xx += (colinfo_[col].width_ - xcell(index(row, col)).width()) / 2;
212 xcell(index(row, col)).draw(pain, xx, yy);
218 void MathGridInset::Write(std::ostream & os, bool fragile) const
220 for (int row = 0; row < nrows(); ++row) {
223 for (int col = 0; col < ncols(); ++col) {
226 cell(index(row, col)).Write(os, fragile);
232 void MathGridInset::addRow(int row)
234 rowinfo_.insert(rowinfo_.begin() + row + 1, RowInfo());
235 cells_.insert(cells_.begin() + (row + 1) * ncols(), ncols(), MathXArray());
238 void MathGridInset::appendRow()
240 rowinfo_.push_back(RowInfo());
241 for (int i = 0; i < ncols(); ++i)
242 cells_.push_back(cells_type::value_type());
246 void MathGridInset::delRow(int row)
251 lyxerr << "delRow: nr: " << nrows() << " nc: " << ncols()
252 << " row: " << row << "\n";
254 cells_type::iterator it = cells_.begin() + row * ncols();
255 cells_.erase(it, it + ncols());
257 rowinfo_.erase(rowinfo_.begin() + row);
261 void MathGridInset::addCol(int newcol)
263 int const nc = ncols();
264 int const nr = nrows();
265 cells_type new_cells((nc + 1) * nr);
267 for (int row = 0; row < nr; ++row)
268 for (int col = 0; col < nc; ++col)
269 new_cells[row * (nc + 1) + col + (col > newcol)]
270 = cells_[row * nc + col];
271 std::swap(cells_, new_cells);
273 colinfo_.insert(colinfo_.begin() + newcol, ColInfo());
277 void MathGridInset::delCol(int col)
283 for (int i = 0; i < nargs(); ++i)
284 if (i % ncols() != col)
285 tmpcells.push_back(cells_[i]);
286 std::swap(cells_, tmpcells);
288 colinfo_.erase(colinfo_.begin() + col);
292 bool MathGridInset::idxUp(int & idx, int & pos) const
302 bool MathGridInset::idxDown(int & idx, int & pos) const
304 if (idx >= ncols() * (nrows() - 1))
312 bool MathGridInset::idxLeft(int & idx, int & pos) const
314 // leave matrix if on the left hand edge
318 pos = cell(idx).size();
323 bool MathGridInset::idxRight(int & idx, int & pos) const
325 // leave matrix if on the right hand edge
326 if (col(idx) == ncols() - 1)
334 bool MathGridInset::idxFirst(int & idx, int & pos) const
341 idx = (nrows() - 1) * ncols();
344 idx = (nrows() / 2) * ncols();
351 bool MathGridInset::idxLast(int & idx, int & pos) const
361 idx = (nrows() / 2 + 1) * ncols() - 1;
363 pos = cell(idx).size();
369 MathGridInset::RowInfo const & MathGridInset::rowinfo(int i) const
375 MathGridInset::RowInfo & MathGridInset::rowinfo(int i)