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