]>
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 | ||
383 | int m_minWidth = 0; | |
384 | int m_minHeight = 0; | |
385 | ||
386 | GetMinimums(); | |
387 | m_minWidth = Sum(m_maxWidth, m_cell_count.GetWidth()); | |
388 | m_minHeight = Sum(m_maxHeight, m_cell_count.GetHeight()); | |
389 | return wxSize( m_minWidth, m_minHeight ); | |
390 | } | |
391 | //--------------------------------------------------------------------------- | |
392 | void wxMultiCellSizer :: GetMinimums() | |
393 | { | |
394 | // We first initial all the arrays EXCEPT for the m_minsizes array. | |
395 | ||
396 | memset(m_maxHeight, 0, sizeof(int) * m_cell_count.GetHeight()); | |
397 | memset(m_maxWidth, 0, sizeof(int) * m_cell_count.GetWidth()); | |
398 | memset(m_rowStretch, 0, sizeof(int) * m_cell_count.GetHeight()); | |
399 | memset(m_colStretch, 0, sizeof(int) * m_cell_count.GetWidth()); | |
400 | for (int x = 0; x < 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
401 | { | |
402 | m_weights[x]->SetHeight(0); | |
403 | m_weights[x]->SetWidth(0); | |
404 | } | |
405 | ||
12a3f227 | 406 | wxSizerItemList::Node *node = m_children.GetFirst(); |
58580a7e JS |
407 | while (node) |
408 | { | |
12a3f227 | 409 | wxSizerItem *item = node->GetData(); |
58580a7e JS |
410 | wxMultiCellItemHandle *rect; |
411 | if (item != NULL && | |
412 | (rect = (wxMultiCellItemHandle *)item->GetUserData()) != NULL) | |
413 | { | |
414 | int row = rect->GetRow(); | |
415 | int col = rect->GetColumn(); | |
416 | ||
417 | // First make sure that the control knows about the max rows and columns | |
418 | ||
419 | int changed = FALSE; | |
420 | if (row + 1 > m_cell_count.GetHeight()) | |
421 | { | |
422 | changed++; | |
423 | m_maxHeight = (int *)realloc(m_maxHeight, (1 + row) * sizeof(int)); | |
424 | m_rowStretch = (int *)realloc(m_rowStretch, (1 + row) * sizeof(int)); | |
425 | for (int x = m_cell_count.GetHeight(); x < row + 1; x++) | |
426 | { | |
427 | m_maxHeight[x - 1] = 0; | |
428 | m_rowStretch[x - 1] = 0; | |
429 | } | |
430 | m_cell_count.SetHeight(row + 1); | |
431 | } | |
432 | if (col + 1 > m_cell_count.GetWidth()) | |
433 | { | |
434 | changed++; | |
435 | m_maxWidth = (int *)realloc(m_maxWidth, (1 + col) * sizeof(int)); | |
436 | m_colStretch = (int *)realloc(m_colStretch, ( 1 + col) * sizeof(int)); | |
437 | for (int x = m_cell_count.GetWidth(); x < col + 1; x++) | |
438 | { | |
439 | m_maxWidth[x - 1] = 0; | |
440 | m_colStretch[x - 1] = 0; | |
441 | } | |
442 | m_cell_count.SetWidth(col + 1); | |
443 | } | |
444 | if (changed) | |
445 | { | |
446 | m_weights = (wxSize **)realloc(m_weights, (1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth())) * sizeof(wxSize *)); | |
447 | m_minSizes = (wxSize **)realloc(m_minSizes, (1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth())) * sizeof(wxSize *)); | |
448 | for (int x = m_maxWeights; x < 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); x++) | |
449 | { | |
450 | m_weights[x - 1] = new wxSize(0,0); | |
451 | m_minSizes[x - 1] = new wxSize(0,0); | |
452 | } | |
453 | m_maxWeights = 1 + wxMax(m_cell_count.GetHeight(), m_cell_count.GetWidth()); | |
454 | } | |
455 | ||
456 | // Sum the m_weights for each row/column, but only if they are resizable | |
457 | ||
458 | wxSize minSize( item->CalcMin() ); | |
459 | wxSize c_size = rect->GetLocalSize(); | |
460 | if (c_size.GetHeight() != wxDefaultSize.GetHeight() || | |
461 | c_size.GetWidth() != wxDefaultSize.GetWidth()) | |
462 | { | |
463 | minSize.SetHeight(wxMax(minSize.GetHeight(), c_size.GetHeight())); | |
464 | minSize.SetWidth(wxMax(minSize.GetWidth(), c_size.GetWidth())); | |
465 | } | |
466 | ||
467 | // For each row, calculate the max height for those fields which are not | |
468 | // resizable in the vertical pane | |
469 | ||
470 | if (!(rect->GetStyle() & wxVERTICAL_RESIZABLE || m_minSizes[row]->GetHeight() < 0)) | |
471 | { | |
472 | m_maxHeight[row] = wxMax(m_maxHeight[row], minSize.GetHeight() / rect->GetHeight()); | |
473 | } | |
474 | else | |
475 | { | |
476 | m_rowStretch[row] = 1; | |
477 | if (m_minSizes[row]->GetHeight()) | |
478 | { | |
479 | m_maxHeight[row] = abs(m_minSizes[row]->GetHeight()); | |
480 | } | |
481 | else | |
482 | { | |
483 | m_maxHeight[row] = wxMax(m_maxHeight[row], m_defaultCellSize.GetHeight()); | |
484 | } | |
485 | m_weights[row]->SetHeight(wxMax(m_weights[row]->GetHeight(), rect->GetWeight().GetHeight())); | |
486 | } | |
487 | ||
488 | // For each column, calculate the max width for those fields which are not | |
489 | // resizable in the horizontal pane | |
490 | ||
118cc185 | 491 | if (!(rect->GetStyle() & wxHORIZONTAL_RESIZABLE || m_minSizes[col]->GetWidth() < 0)) |
58580a7e JS |
492 | { |
493 | if (m_minSizes[col]->GetWidth()) | |
494 | { | |
495 | m_maxWidth[col] = abs(m_minSizes[col]->GetWidth()); | |
496 | } | |
497 | else | |
498 | { | |
499 | m_maxWidth[col] = wxMax(m_maxWidth[col], minSize.GetWidth() / rect->GetWidth()); | |
500 | } | |
501 | } | |
502 | else | |
503 | { | |
504 | m_colStretch[col] = 1; | |
505 | m_maxWidth[col] = wxMax(m_maxWidth[col], m_defaultCellSize.GetWidth()); | |
506 | m_weights[col]->SetWidth(wxMax(m_weights[col]->GetWidth(), rect->GetWeight().GetWidth())); | |
507 | } | |
12a3f227 | 508 | node = node->GetNext(); |
58580a7e JS |
509 | } |
510 | } | |
511 | } // wxMultiCellSizer :: GetMinimums | |
512 | //--------------------------------------------------------------------------- | |
513 | /* | |
514 | *Function Name: wxMultiCellSizer :: Sum | |
515 | * | |
516 | *Parameters: int * pointer to array of ints | |
517 | * int Number of cells to sum up | |
518 | * | |
519 | *Description: This member function sums up all the elements of the array which | |
520 | * preceed the specified cell. | |
521 | * | |
522 | *Returns: int Sum | |
523 | * | |
524 | */ | |
525 | ||
526 | int wxMultiCellSizer :: Sum(int *array, int x) | |
527 | { | |
528 | int sum = 0; | |
529 | while (x--) | |
530 | { | |
531 | sum += array[x]; | |
532 | } | |
533 | return sum; | |
534 | } | |
535 | //--------------------------------------------------------------------------- | |
536 | /* | |
537 | *Function Name: wxMultiCellSizer :: DrawGridLines | |
538 | * | |
539 | *Parameters: wxDC Device context | |
540 | * | |
541 | *Description: This function draws the grid lines in the specified device context. | |
542 | * | |
543 | */ | |
544 | ||
545 | void wxMultiCellSizer :: DrawGridLines(wxDC& dc) | |
546 | { | |
547 | RecalcSizes(); | |
548 | int maxW = Sum(m_maxWidth, m_cell_count.GetWidth()); | |
549 | int maxH = Sum(m_maxHeight, m_cell_count.GetHeight()); | |
550 | int x; | |
551 | ||
552 | // Draw the columns | |
553 | dc.SetPen(* m_pen); | |
554 | for (x = 1; x < m_cell_count.GetWidth(); x++) | |
555 | { | |
556 | int colPos = Sum(m_maxWidth, x) ; | |
557 | dc.DrawLine(colPos, 0, colPos, maxH); | |
558 | } | |
559 | ||
560 | // Draw the rows | |
561 | for (x = 1; x < m_cell_count.GetHeight(); x++) | |
562 | { | |
563 | int rowPos = Sum(m_maxHeight, x); | |
564 | dc.DrawLine(0, rowPos, maxW, rowPos); | |
565 | } | |
566 | } | |
567 | //--------------------------------------------------------------------------- | |
568 | // Define the repainting behaviour | |
569 | /* | |
570 | *Function Name: wxMultiCellSizer::OnPaint | |
571 | * | |
572 | *Parameters: wxDC Device context | |
573 | * | |
574 | *Description: This function calls the DrawGridLines() member if a window | |
575 | * has been previously specified. This functions MUST be called | |
576 | * from an OnPaint member belonging to the window which the sizer | |
577 | * is attached to. | |
578 | * | |
579 | */ | |
580 | ||
581 | void wxMultiCellSizer::OnPaint(wxDC& dc ) | |
582 | { | |
583 | if (m_win) | |
584 | { | |
585 | DrawGridLines(dc); | |
586 | } | |
587 | } | |
588 | ||
589 | ||
590 | //--------------------------------------------------------------------------- | |
591 | //--------------------------------------------------------------------------- | |
592 | ||
593 | ||
594 | ||
595 | ||
596 | #define CELL_LOC(row, col) ((row) * m_maxCols + col) | |
597 | ||
598 | //--------------------------------------------------------------------------- | |
599 | // wxCell | |
600 | //--------------------------------------------------------------------------- | |
601 | /* | |
602 | *Function Name: wxCell : wxLayoutConstraints | |
603 | * | |
604 | *Description: This class is used by wxMultiCellCanvas for internal storage | |
605 | * | |
606 | */ | |
607 | ||
608 | class wxCell : public wxLayoutConstraints | |
609 | { | |
610 | public: | |
611 | wxCell(wxWindow *win) | |
612 | { | |
613 | m_window = win; | |
614 | }; | |
615 | ||
616 | wxWindow *m_window; | |
617 | }; | |
618 | ||
619 | ||
620 | ||
621 | //--------------------------------------------------------------------------- | |
622 | // wxMultiCellCanvas | |
623 | //--------------------------------------------------------------------------- | |
624 | wxMultiCellCanvas :: wxMultiCellCanvas(wxWindow *par, int numRows, int numCols) | |
625 | : wxFlexGridSizer(numRows, numCols, 0, 0) | |
626 | { | |
627 | m_cells = (wxCell **)calloc(numRows * numCols, sizeof(wxCell *)); | |
628 | ||
629 | m_parent = par; | |
630 | m_maxRows = numRows; | |
631 | m_maxCols = numCols; | |
632 | m_minCellSize = wxSize(5, 5); | |
633 | } | |
634 | //--------------------------------------------------------------------------- | |
635 | wxString itoa(int x) | |
636 | { | |
637 | char bfr[255]; | |
638 | sprintf(bfr, "%d", x); | |
639 | return bfr; | |
640 | } | |
641 | //--------------------------------------------------------------------------- | |
642 | void wxMultiCellCanvas :: Add(wxWindow *win, unsigned int row, unsigned int col) | |
643 | { | |
644 | wxASSERT_MSG(row >= 0 && row < m_maxRows, wxString("Row ") + itoa(row) + " out of bounds (" + itoa(m_maxRows) + ")"); | |
645 | wxASSERT_MSG(col >= 0 && col < m_maxCols, wxString("Column ") + itoa(col) + " out of bounds (" + itoa(m_maxCols) + ")"); | |
d96f6300 | 646 | wxASSERT_MSG(m_cells[CELL_LOC(row, col)] == NULL, wxT("Cell already occupied")); |
58580a7e JS |
647 | |
648 | wxCell *newCell = new wxCell(win); | |
649 | m_cells[CELL_LOC(row,col)] = newCell; | |
650 | } | |
651 | //--------------------------------------------------------------------------- | |
652 | void wxMultiCellCanvas :: CalculateConstraints() | |
653 | { | |
654 | unsigned int row, col; | |
655 | for (row = 0; row < m_maxRows; row++) | |
656 | { | |
657 | for (col = 0; col < m_maxCols; col++) | |
658 | { | |
659 | if (!m_cells[CELL_LOC(row, col)]) | |
660 | { | |
661 | // Create an empty static text field as a placeholder | |
662 | m_cells[CELL_LOC(row, col)] = new wxCell(new wxStaticText(m_parent, -1, "")); | |
663 | } | |
664 | wxFlexGridSizer::Add(m_cells[CELL_LOC(row, col)]->m_window); | |
665 | } | |
666 | } | |
667 | } | |
668 | ||
669 | /*** End of File ***/ |