]>
Commit | Line | Data |
---|---|---|
58580a7e JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: multicell.cpp | |
3 | // Purpose: provide two new classes for layout, wxMultiCellSizer and wxMultiCellCanvas | |
4 | // Author: Jonathan Bayer | |
5 | // Modified by: | |
6 | // Created: | |
1c4e8f38 | 7 | // RCS-ID: $Id$ |
58580a7e JS |
8 | // Copyright: (c) Jonathan Bayer |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // This was inspired by the gbsizer class written by Alex Andruschak | |
13 | ||
58580a7e JS |
14 | // For compilers that support precompilation, includes "wx.h". |
15 | #include "wx/wxprec.h" | |
16 | ||
17 | #ifdef __BORLANDC__ | |
a2d49353 | 18 | #pragma hdrstop |
58580a7e JS |
19 | #endif |
20 | ||
21 | // ---------------------------------------------------------------------------- | |
22 | // headers | |
23 | // ---------------------------------------------------------------------------- | |
24 | ||
25 | #ifndef WX_PRECOMP | |
a2d49353 | 26 | #include "wx/wx.h" |
58580a7e JS |
27 | #endif |
28 | ||
a2d49353 | 29 | #include "wx/gizmos/multicell.h" |
58580a7e JS |
30 | |
31 | ||
32 | ||
33 | ||
34 | //--------------------------------------------------------------------------- | |
35 | ||
36 | IMPLEMENT_ABSTRACT_CLASS(wxMultiCellSizer, wxSizer); | |
cd72551c | 37 | IMPLEMENT_ABSTRACT_CLASS(wxMultiCellItemHandle, wxObject); |
58580a7e JS |
38 | |
39 | //--------------------------------------------------------------------------- | |
40 | // wxMultiCellItemHandle | |
41 | //--------------------------------------------------------------------------- | |
42 | /* | |
a2d49353 | 43 | *Function Name: wxMultiCellItemHandle :: wxMultiCellItemHandle |
58580a7e | 44 | * |
a2d49353 WS |
45 | *Parameters: int row |
46 | * int column | |
47 | * int height | |
48 | * int width | |
49 | * wxSize size | |
50 | * wxResizable Style | |
51 | * wxSize weight | |
52 | * int align | |
58580a7e | 53 | * |
a2d49353 | 54 | *Description: This is the constructor for the class. |
58580a7e JS |
55 | * |
56 | */ | |
57 | ||
58 | void wxMultiCellItemHandle :: Initialize( int row, int column, int height, int width, wxSize size, wxResizable Style, wxSize weight, int align) | |
59 | { | |
a2d49353 WS |
60 | m_column = column; |
61 | m_row = row; | |
62 | m_width = width; | |
63 | m_height = height; | |
58580a7e | 64 | |
a2d49353 WS |
65 | m_style = Style; |
66 | m_fixedSize = size; | |
67 | m_alignment = align; | |
68 | m_weight = weight; | |
58580a7e JS |
69 | } |
70 | //--------------------------------------------------------------------------- | |
71 | wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, int height, int width, wxSize size, wxResizable Style, wxSize weight, int align) | |
72 | { | |
a2d49353 | 73 | Initialize(row, column,height, width, size, Style, weight, align); |
58580a7e JS |
74 | } |
75 | //--------------------------------------------------------------------------- | |
76 | wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, wxSize size, wxResizable style, wxSize weight, int align) | |
77 | { | |
a2d49353 | 78 | Initialize(row, column,1, 1, size, style, weight, align); |
58580a7e JS |
79 | } |
80 | //--------------------------------------------------------------------------- | |
81 | wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, wxResizable style, wxSize weight, int align) | |
82 | { | |
a2d49353 | 83 | Initialize(row, column, 1, 1, wxSize(1, 1), style, weight, align); |
58580a7e | 84 | } |
58580a7e JS |
85 | //--------------------------------------------------------------------------- |
86 | int wxMultiCellItemHandle::GetColumn() | |
87 | { | |
a2d49353 | 88 | return m_column; |
58580a7e JS |
89 | } |
90 | //--------------------------------------------------------------------------- | |
91 | int wxMultiCellItemHandle::GetRow() | |
92 | { | |
a2d49353 | 93 | return m_row; |
58580a7e JS |
94 | } |
95 | //--------------------------------------------------------------------------- | |
96 | int wxMultiCellItemHandle::GetWidth() | |
97 | { | |
a2d49353 | 98 | return m_width; |
58580a7e JS |
99 | } |
100 | //--------------------------------------------------------------------------- | |
101 | int wxMultiCellItemHandle::GetHeight() | |
102 | { | |
a2d49353 | 103 | return m_height; |
58580a7e JS |
104 | } |
105 | //--------------------------------------------------------------------------- | |
106 | wxResizable wxMultiCellItemHandle :: GetStyle() | |
107 | { | |
a2d49353 | 108 | return m_style; |
58580a7e JS |
109 | }; |
110 | //--------------------------------------------------------------------------- | |
111 | wxSize wxMultiCellItemHandle :: GetLocalSize() | |
112 | { | |
a2d49353 | 113 | return m_fixedSize; |
58580a7e JS |
114 | }; |
115 | //--------------------------------------------------------------------------- | |
116 | int wxMultiCellItemHandle :: GetAlignment() | |
117 | { | |
a2d49353 | 118 | return m_alignment; |
58580a7e JS |
119 | }; |
120 | //--------------------------------------------------------------------------- | |
121 | wxSize wxMultiCellItemHandle :: GetWeight() | |
122 | { | |
a2d49353 | 123 | return m_weight; |
58580a7e JS |
124 | }; |
125 | ||
126 | ||
127 | ||
128 | //--------------------------------------------------------------------------- | |
129 | ||
130 | //--------------------------------------------------------------------------- | |
131 | // wxMultiCellSizer | |
132 | //--------------------------------------------------------------------------- | |
133 | ||
134 | /* | |
a2d49353 | 135 | *Function Name: wxMultiCellSizer::Initialize |
58580a7e | 136 | * |
a2d49353 | 137 | *Parameters: wxsize Initial size of sizer |
58580a7e | 138 | * |
a2d49353 WS |
139 | *Description: This is a common function to initialize all the members of |
140 | * this class. It is only called from the constructors | |
58580a7e JS |
141 | * |
142 | */ | |
143 | ||
144 | void wxMultiCellSizer::Initialize( wxSize size ) | |
145 | { | |
a2d49353 WS |
146 | m_cell_count = size; |
147 | m_maxHeight = (int *)malloc((1 + m_cell_count.GetHeight()) * sizeof(int)); | |
148 | m_maxWidth = (int *)malloc( (1 + m_cell_count.GetWidth()) * sizeof(int)); | |
149 | m_rowStretch = (int *)malloc( (1 + m_cell_count.GetHeight()) * sizeof(int)); | |
150 | m_colStretch = (int *)malloc((1 + m_cell_count.GetWidth()) * sizeof(int)); | |
151 | ||
152 | m_weights = (wxSize **)malloc((1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth())) * sizeof(wxSize *)); | |
153 | m_minSizes = (wxSize **)malloc((1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth())) * sizeof(wxSize *)); | |
154 | for (int x = 0; x < 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
155 | { | |
156 | m_weights[x] = new wxSize(0,0); | |
157 | m_minSizes[x] = new wxSize(0,0); | |
158 | } | |
159 | ||
160 | m_maxWeights = 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); | |
161 | m_defaultCellSize = wxSize(5, 5); | |
162 | m_win = NULL; | |
163 | m_pen = wxRED_PEN; | |
58580a7e JS |
164 | } |
165 | //--------------------------------------------------------------------------- | |
166 | wxMultiCellSizer::wxMultiCellSizer( wxSize & size ) | |
167 | { | |
a2d49353 | 168 | Initialize(size); |
58580a7e JS |
169 | } |
170 | //--------------------------------------------------------------------------- | |
171 | wxMultiCellSizer::wxMultiCellSizer( int rows, int cols) | |
172 | { | |
a2d49353 WS |
173 | wxSize size(cols, rows); |
174 | Initialize(size); | |
58580a7e JS |
175 | } |
176 | //--------------------------------------------------------------------------- | |
177 | wxMultiCellSizer::~wxMultiCellSizer() | |
178 | { | |
a2d49353 | 179 | WX_CLEAR_LIST(wxSizerItemList, m_children); |
58580a7e | 180 | |
a2d49353 WS |
181 | free(m_maxHeight); |
182 | free(m_maxWidth); | |
183 | free(m_rowStretch); | |
184 | free(m_colStretch); | |
58580a7e | 185 | |
a2d49353 WS |
186 | for (int x = 0; x < 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) |
187 | { | |
188 | delete m_weights[x]; | |
189 | delete m_minSizes[x]; | |
190 | } | |
191 | free(m_weights); | |
192 | free(m_minSizes); | |
58580a7e JS |
193 | } |
194 | //--------------------------------------------------------------------------- | |
195 | bool wxMultiCellSizer::EnableGridLines(wxWindow *win) | |
196 | { | |
a2d49353 WS |
197 | m_win = win; |
198 | return true; | |
58580a7e JS |
199 | } |
200 | //--------------------------------------------------------------------------- | |
d0363d3d | 201 | bool wxMultiCellSizer::SetGridPen(const wxPen *pen) |
58580a7e | 202 | { |
a2d49353 WS |
203 | m_pen = pen; |
204 | return true; | |
58580a7e JS |
205 | } |
206 | ||
207 | //--------------------------------------------------------------------------- | |
208 | bool wxMultiCellSizer::SetDefaultCellSize(wxSize size) | |
209 | { | |
a2d49353 WS |
210 | m_defaultCellSize = size; |
211 | return true; | |
58580a7e JS |
212 | } |
213 | //--------------------------------------------------------------------------- | |
214 | bool wxMultiCellSizer::SetColumnWidth(int column, int colSize, bool expandable) | |
215 | { | |
a2d49353 WS |
216 | if (expandable) |
217 | { | |
218 | m_minSizes[column]->SetWidth(-colSize); | |
219 | } | |
220 | else | |
221 | { | |
222 | m_minSizes[column]->SetWidth(colSize); | |
223 | } | |
224 | return true; | |
58580a7e JS |
225 | } |
226 | //--------------------------------------------------------------------------- | |
227 | bool wxMultiCellSizer::SetRowHeight(int row, int rowSize, bool expandable) | |
228 | { | |
a2d49353 WS |
229 | if (expandable) |
230 | { | |
231 | m_minSizes[row]->SetHeight(-rowSize); | |
232 | } | |
233 | else | |
234 | { | |
235 | m_minSizes[row]->SetHeight(rowSize); | |
236 | } | |
237 | return true; | |
58580a7e JS |
238 | } |
239 | //--------------------------------------------------------------------------- | |
240 | void wxMultiCellSizer::RecalcSizes() | |
241 | { | |
a2d49353 WS |
242 | if (m_children.GetCount() == 0) |
243 | return; | |
244 | wxSize size = GetSize(); | |
245 | wxPoint pos = GetPosition(); | |
246 | ||
247 | GetMinimums(); | |
248 | ||
249 | // We need to take the unused space and equally give it out to all the rows/columns | |
250 | // which are stretchable | |
251 | ||
252 | int unUsedWidth = size.GetWidth() - Sum(m_maxWidth, m_cell_count.GetWidth()); | |
253 | int unUsedHeight = size.GetHeight() - Sum(m_maxHeight, m_cell_count.GetHeight()); | |
254 | int totalWidthWeight = 0; | |
255 | int totalHeightWeight = 0; | |
256 | int x; | |
257 | ||
258 | for (x = 0; x < wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
259 | { | |
260 | if (m_rowStretch[x]) | |
261 | { | |
262 | totalHeightWeight += m_weights[x]->GetHeight(); | |
263 | } | |
264 | if (x < m_cell_count.GetWidth() && m_colStretch[x]) | |
265 | { | |
266 | totalWidthWeight += m_weights[x]->GetWidth(); | |
267 | } | |
268 | } | |
269 | for (x = 0; x < wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
270 | { | |
271 | if (x < m_cell_count.GetHeight() && m_rowStretch[x]) | |
272 | { | |
273 | m_maxHeight[x] += unUsedHeight * m_weights[x]->GetHeight() / totalHeightWeight; | |
274 | } | |
275 | if (x < m_cell_count.GetWidth() && m_colStretch[x]) | |
276 | { | |
277 | m_maxWidth[x] += unUsedWidth * m_weights[x]->GetWidth() / totalWidthWeight; | |
278 | } | |
279 | } | |
280 | // We now have everything we need to figure each cell position and size | |
281 | // The arrays m_maxHeight and m_maxWidth now contain the final widths and height of | |
282 | // each row and column. | |
283 | ||
284 | double cell_width = (double)size.GetWidth() / (double)m_cell_count.GetWidth(); | |
285 | double cell_height = (double)size.GetHeight() / (double)m_cell_count.GetHeight(); | |
286 | wxPoint c_point; | |
287 | wxSize c_size; | |
288 | ||
289 | wxSizerItemList::compatibility_iterator current = m_children.GetFirst(); | |
290 | while (current) | |
291 | { | |
292 | wxSizerItem *item = current->GetData(); | |
293 | ||
294 | wxMultiCellItemHandle *rect; | |
295 | if (item != NULL && | |
296 | (rect = (wxMultiCellItemHandle *)item->GetUserData()) != NULL) | |
297 | { | |
298 | c_point.x = pos.x + (int)(rect->GetColumn() * cell_width); | |
299 | c_point.y = pos.y + (int)(rect->GetRow() * cell_height); | |
300 | ||
301 | c_point.x = pos.x + Sum(m_maxWidth, rect->GetColumn()); | |
302 | c_point.y = pos.y + Sum(m_maxHeight, rect->GetRow()); | |
303 | ||
304 | ||
305 | c_size = rect->GetLocalSize(); | |
306 | wxSize minSize( item->CalcMin() ); | |
422d0ff0 WS |
307 | if (c_size.GetHeight() != wxDefaultCoord || |
308 | c_size.GetWidth() != wxDefaultCoord) | |
a2d49353 WS |
309 | { |
310 | minSize.SetHeight(wxMax(minSize.GetHeight(), c_size.GetHeight())); | |
311 | minSize.SetWidth(wxMax(minSize.GetWidth(), c_size.GetWidth())); | |
312 | } | |
313 | if (rect->GetStyle() & wxHORIZONTAL_RESIZABLE || | |
314 | rect->GetWidth() > 1 | |
315 | || m_minSizes[rect->GetColumn()]->GetWidth() < 0) | |
316 | { | |
317 | int w = 0; | |
318 | for (int x = 0; x < rect->GetWidth(); x++) | |
319 | { | |
320 | w += m_maxWidth[rect->GetColumn() + x]; | |
321 | } | |
322 | c_size.SetWidth(w); | |
323 | } | |
324 | else | |
325 | { | |
326 | c_size.SetWidth(minSize.GetWidth() ); | |
327 | } | |
328 | if (rect->GetStyle() & wxVERTICAL_RESIZABLE || | |
329 | rect->GetHeight() > 1 || | |
330 | m_minSizes[rect->GetRow()]->GetHeight() < 0) | |
331 | { | |
332 | int h = 0; | |
333 | for (int x = 0; x < rect->GetHeight(); x++) | |
334 | { | |
335 | h += m_maxHeight[rect->GetRow() + x]; | |
336 | } | |
337 | c_size.SetHeight(h); | |
338 | } | |
339 | else | |
340 | { | |
341 | c_size.SetHeight(minSize.GetHeight()); | |
342 | } | |
343 | int extraHeight = (m_maxHeight[rect->GetRow()] - c_size.GetHeight()); | |
344 | int extraWidth = (m_maxWidth[rect->GetColumn()] - c_size.GetWidth()); | |
345 | ||
346 | if (rect->GetWidth() == 1 && rect->GetAlignment() & wxALIGN_CENTER_HORIZONTAL) | |
347 | { | |
348 | c_point.x += extraWidth / 2; | |
349 | } | |
350 | if (rect->GetWidth() == 1 && rect->GetAlignment() & wxALIGN_RIGHT) | |
351 | { | |
352 | c_point.x += extraWidth; | |
353 | } | |
354 | if (rect->GetHeight() == 1 && rect->GetAlignment() & wxALIGN_CENTER_VERTICAL) | |
355 | { | |
356 | c_point.y += extraHeight / 2; | |
357 | } | |
358 | if (rect->GetHeight() == 1 && rect->GetAlignment() & wxALIGN_BOTTOM) | |
359 | { | |
360 | c_point.y += extraHeight; | |
361 | } | |
362 | item->SetDimension(c_point, c_size); | |
363 | } | |
364 | current = current->GetNext(); | |
365 | } | |
58580a7e JS |
366 | } |
367 | //--------------------------------------------------------------------------- | |
368 | wxSize wxMultiCellSizer::CalcMin() | |
369 | { | |
a2d49353 WS |
370 | if (m_children.GetCount() == 0) |
371 | return wxSize(10,10); | |
58580a7e | 372 | |
a2d49353 WS |
373 | GetMinimums(); |
374 | int m_minWidth = Sum(m_maxWidth, m_cell_count.GetWidth()); | |
375 | int m_minHeight = Sum(m_maxHeight, m_cell_count.GetHeight()); | |
376 | return wxSize( m_minWidth, m_minHeight ); | |
58580a7e JS |
377 | } |
378 | //--------------------------------------------------------------------------- | |
379 | void wxMultiCellSizer :: GetMinimums() | |
380 | { | |
a2d49353 WS |
381 | // We first initial all the arrays EXCEPT for the m_minsizes array. |
382 | ||
383 | memset(m_maxHeight, 0, sizeof(int) * m_cell_count.GetHeight()); | |
384 | memset(m_maxWidth, 0, sizeof(int) * m_cell_count.GetWidth()); | |
385 | memset(m_rowStretch, 0, sizeof(int) * m_cell_count.GetHeight()); | |
386 | memset(m_colStretch, 0, sizeof(int) * m_cell_count.GetWidth()); | |
387 | for (int x = 0; x < 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
388 | { | |
389 | m_weights[x]->SetHeight(0); | |
390 | m_weights[x]->SetWidth(0); | |
391 | } | |
392 | ||
393 | wxSizerItemList::compatibility_iterator node = m_children.GetFirst(); | |
394 | while (node) | |
395 | { | |
396 | wxSizerItem *item = node->GetData(); | |
397 | wxMultiCellItemHandle *rect; | |
398 | if (item != NULL && | |
399 | (rect = (wxMultiCellItemHandle *)item->GetUserData()) != NULL) | |
400 | { | |
401 | int row = rect->GetRow(); | |
402 | int col = rect->GetColumn(); | |
403 | ||
404 | // First make sure that the control knows about the max rows and columns | |
405 | ||
406 | int changed = false; | |
407 | if (row + 1 > m_cell_count.GetHeight()) | |
408 | { | |
409 | changed++; | |
410 | m_maxHeight = (int *)realloc(m_maxHeight, (1 + row) * sizeof(int)); | |
411 | m_rowStretch = (int *)realloc(m_rowStretch, (1 + row) * sizeof(int)); | |
412 | for (int x = m_cell_count.GetHeight(); x < row + 1; x++) | |
413 | { | |
414 | m_maxHeight[x - 1] = 0; | |
415 | m_rowStretch[x - 1] = 0; | |
416 | } | |
417 | m_cell_count.SetHeight(row + 1); | |
418 | } | |
419 | if (col + 1 > m_cell_count.GetWidth()) | |
420 | { | |
421 | changed++; | |
422 | m_maxWidth = (int *)realloc(m_maxWidth, (1 + col) * sizeof(int)); | |
423 | m_colStretch = (int *)realloc(m_colStretch, ( 1 + col) * sizeof(int)); | |
424 | for (int x = m_cell_count.GetWidth(); x < col + 1; x++) | |
425 | { | |
426 | m_maxWidth[x - 1] = 0; | |
427 | m_colStretch[x - 1] = 0; | |
428 | } | |
429 | m_cell_count.SetWidth(col + 1); | |
430 | } | |
431 | if (changed) | |
432 | { | |
433 | m_weights = (wxSize **)realloc(m_weights, (1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth())) * sizeof(wxSize *)); | |
434 | m_minSizes = (wxSize **)realloc(m_minSizes, (1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth())) * sizeof(wxSize *)); | |
435 | for (int x = m_maxWeights; x < 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
436 | { | |
437 | m_weights[x - 1] = new wxSize(0,0); | |
438 | m_minSizes[x - 1] = new wxSize(0,0); | |
439 | } | |
440 | m_maxWeights = 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); | |
441 | } | |
442 | ||
443 | // Sum the m_weights for each row/column, but only if they are resizable | |
444 | ||
445 | wxSize minSize( item->CalcMin() ); | |
446 | wxSize c_size = rect->GetLocalSize(); | |
422d0ff0 WS |
447 | if (c_size.GetHeight() != wxDefaultCoord || |
448 | c_size.GetWidth() != wxDefaultCoord) | |
a2d49353 WS |
449 | { |
450 | minSize.SetHeight(wxMax(minSize.GetHeight(), c_size.GetHeight())); | |
451 | minSize.SetWidth(wxMax(minSize.GetWidth(), c_size.GetWidth())); | |
452 | } | |
453 | ||
454 | // For each row, calculate the max height for those fields which are not | |
455 | // resizable in the vertical pane | |
456 | ||
457 | if (!(rect->GetStyle() & wxVERTICAL_RESIZABLE || m_minSizes[row]->GetHeight() < 0)) | |
458 | { | |
459 | m_maxHeight[row] = wxMax(m_maxHeight[row], minSize.GetHeight() / rect->GetHeight()); | |
460 | } | |
461 | else | |
462 | { | |
463 | m_rowStretch[row] = 1; | |
464 | if (m_minSizes[row]->GetHeight()) | |
465 | { | |
466 | m_maxHeight[row] = abs(m_minSizes[row]->GetHeight()); | |
467 | } | |
468 | else | |
469 | { | |
470 | m_maxHeight[row] = wxMax(m_maxHeight[row], m_defaultCellSize.GetHeight()); | |
471 | } | |
472 | m_weights[row]->SetHeight(wxMax(m_weights[row]->GetHeight(), rect->GetWeight().GetHeight())); | |
473 | } | |
474 | ||
475 | // For each column, calculate the max width for those fields which are not | |
476 | // resizable in the horizontal pane | |
477 | ||
478 | if (!(rect->GetStyle() & wxHORIZONTAL_RESIZABLE || m_minSizes[col]->GetWidth() < 0)) | |
479 | { | |
480 | if (m_minSizes[col]->GetWidth()) | |
481 | { | |
482 | m_maxWidth[col] = abs(m_minSizes[col]->GetWidth()); | |
483 | } | |
484 | else | |
485 | { | |
486 | m_maxWidth[col] = wxMax(m_maxWidth[col], minSize.GetWidth() / rect->GetWidth()); | |
487 | } | |
488 | } | |
489 | else | |
490 | { | |
491 | m_colStretch[col] = 1; | |
492 | m_maxWidth[col] = wxMax(m_maxWidth[col], m_defaultCellSize.GetWidth()); | |
493 | m_weights[col]->SetWidth(wxMax(m_weights[col]->GetWidth(), rect->GetWeight().GetWidth())); | |
494 | } | |
495 | node = node->GetNext(); | |
496 | } | |
497 | } | |
58580a7e JS |
498 | } // wxMultiCellSizer :: GetMinimums |
499 | //--------------------------------------------------------------------------- | |
500 | /* | |
a2d49353 | 501 | *Function Name: wxMultiCellSizer :: Sum |
58580a7e | 502 | * |
a2d49353 WS |
503 | *Parameters: int* pointer to array of ints |
504 | * int Number of cells to sum up | |
58580a7e | 505 | * |
a2d49353 WS |
506 | *Description: This member function sums up all the elements of the array which |
507 | * preceed the specified cell. | |
58580a7e | 508 | * |
a2d49353 | 509 | *Returns: int Sum |
58580a7e JS |
510 | * |
511 | */ | |
512 | ||
513 | int wxMultiCellSizer :: Sum(int *array, int x) | |
514 | { | |
a2d49353 WS |
515 | int sum = 0; |
516 | while (x--) | |
517 | { | |
518 | sum += array[x]; | |
519 | } | |
520 | return sum; | |
58580a7e JS |
521 | } |
522 | //--------------------------------------------------------------------------- | |
523 | /* | |
a2d49353 | 524 | *Function Name: wxMultiCellSizer :: DrawGridLines |
58580a7e | 525 | * |
a2d49353 | 526 | *Parameters: wxDC Device context |
58580a7e | 527 | * |
a2d49353 | 528 | *Description: This function draws the grid lines in the specified device context. |
58580a7e JS |
529 | * |
530 | */ | |
531 | ||
532 | void wxMultiCellSizer :: DrawGridLines(wxDC& dc) | |
533 | { | |
a2d49353 WS |
534 | RecalcSizes(); |
535 | int maxW = Sum(m_maxWidth, m_cell_count.GetWidth()); | |
536 | int maxH = Sum(m_maxHeight, m_cell_count.GetHeight()); | |
537 | int x; | |
538 | ||
539 | // Draw the columns | |
540 | dc.SetPen(* m_pen); | |
541 | for (x = 1; x < m_cell_count.GetWidth(); x++) | |
542 | { | |
543 | int colPos = Sum(m_maxWidth, x) ; | |
544 | dc.DrawLine(colPos, 0, colPos, maxH); | |
545 | } | |
546 | ||
547 | // Draw the rows | |
548 | for (x = 1; x < m_cell_count.GetHeight(); x++) | |
549 | { | |
550 | int rowPos = Sum(m_maxHeight, x); | |
551 | dc.DrawLine(0, rowPos, maxW, rowPos); | |
552 | } | |
58580a7e JS |
553 | } |
554 | //--------------------------------------------------------------------------- | |
555 | // Define the repainting behaviour | |
556 | /* | |
a2d49353 | 557 | *Function Name: wxMultiCellSizer::OnPaint |
58580a7e | 558 | * |
a2d49353 | 559 | *Parameters: wxDC Device context |
58580a7e | 560 | * |
a2d49353 WS |
561 | *Description: This function calls the DrawGridLines() member if a window |
562 | * has been previously specified. This functions MUST be called | |
563 | * from an OnPaint member belonging to the window which the sizer | |
564 | * is attached to. | |
58580a7e JS |
565 | * |
566 | */ | |
567 | ||
568 | void wxMultiCellSizer::OnPaint(wxDC& dc ) | |
569 | { | |
a2d49353 WS |
570 | if (m_win) |
571 | { | |
572 | DrawGridLines(dc); | |
573 | } | |
58580a7e JS |
574 | } |
575 | ||
576 | ||
577 | //--------------------------------------------------------------------------- | |
578 | //--------------------------------------------------------------------------- | |
579 | ||
580 | ||
581 | ||
582 | ||
a2d49353 | 583 | #define CELL_LOC(row, col) ((row) * m_maxCols + col) |
58580a7e JS |
584 | |
585 | //--------------------------------------------------------------------------- | |
586 | // wxCell | |
587 | //--------------------------------------------------------------------------- | |
588 | /* | |
a2d49353 | 589 | *Function Name: wxCell : wxLayoutConstraints |
58580a7e | 590 | * |
a2d49353 | 591 | *Description: This class is used by wxMultiCellCanvas for internal storage |
58580a7e JS |
592 | * |
593 | */ | |
594 | ||
595 | class wxCell : public wxLayoutConstraints | |
596 | { | |
597 | public: | |
a2d49353 WS |
598 | wxCell(wxWindow *win) |
599 | { | |
600 | m_window = win; | |
601 | }; | |
58580a7e | 602 | |
a2d49353 | 603 | wxWindow *m_window; |
58580a7e JS |
604 | }; |
605 | ||
606 | ||
607 | ||
608 | //--------------------------------------------------------------------------- | |
609 | // wxMultiCellCanvas | |
610 | //--------------------------------------------------------------------------- | |
611 | wxMultiCellCanvas :: wxMultiCellCanvas(wxWindow *par, int numRows, int numCols) | |
612 | : wxFlexGridSizer(numRows, numCols, 0, 0) | |
613 | { | |
a2d49353 | 614 | m_cells = (wxCell **)calloc(numRows * numCols, sizeof(wxCell *)); |
58580a7e | 615 | |
a2d49353 WS |
616 | m_parent = par; |
617 | m_maxRows = numRows; | |
618 | m_maxCols = numCols; | |
619 | m_minCellSize = wxSize(5, 5); | |
58580a7e JS |
620 | } |
621 | //--------------------------------------------------------------------------- | |
58580a7e JS |
622 | void wxMultiCellCanvas :: Add(wxWindow *win, unsigned int row, unsigned int col) |
623 | { | |
c3f815fa | 624 | // thanks to unsigned data row and col are always >= 0 |
a2d49353 | 625 | wxASSERT_MSG( /* row >= 0 && */ row < m_maxRows, |
8c7e3f14 | 626 | wxString::Format(_T("Row %d out of bounds (0..%d)"), row, m_maxRows) ); |
a2d49353 | 627 | wxASSERT_MSG( /* col >= 0 && */ col < m_maxCols, |
8c7e3f14 VZ |
628 | wxString::Format(_T("Column %d out of bounds (0..%d)"), col, m_maxCols) ); |
629 | ||
a2d49353 | 630 | wxASSERT_MSG(m_cells[CELL_LOC(row, col)] == NULL, wxT("Cell already occupied")); |
58580a7e | 631 | |
a2d49353 WS |
632 | wxCell *newCell = new wxCell(win); |
633 | m_cells[CELL_LOC(row,col)] = newCell; | |
58580a7e JS |
634 | } |
635 | //--------------------------------------------------------------------------- | |
636 | void wxMultiCellCanvas :: CalculateConstraints() | |
637 | { | |
a2d49353 WS |
638 | unsigned int row, col; |
639 | for (row = 0; row < m_maxRows; row++) | |
640 | { | |
641 | for (col = 0; col < m_maxCols; col++) | |
642 | { | |
643 | if (!m_cells[CELL_LOC(row, col)]) | |
644 | { | |
645 | // Create an empty static text field as a placeholder | |
18c45cd6 | 646 | m_cells[CELL_LOC(row, col)] = new wxCell(new wxStaticText(m_parent, wxID_ANY, wxEmptyString)); |
a2d49353 WS |
647 | } |
648 | wxFlexGridSizer::Add(m_cells[CELL_LOC(row, col)]->m_window); | |
649 | } | |
650 | } | |
58580a7e JS |
651 | } |
652 | ||
653 | /*** End of File ***/ |