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