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