]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/gizmos/multicell.cpp
Rebaked (build/bakefiles/common.bkl 1.95->1.96 change)
[wxWidgets.git] / contrib / src / gizmos / multicell.cpp
CommitLineData
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__
a2d49353 15 #pragma implementation "multicell.h"
58580a7e
JS
16#endif
17
18// For compilers that support precompilation, includes "wx.h".
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
a2d49353 22 #pragma hdrstop
58580a7e
JS
23#endif
24
25// ----------------------------------------------------------------------------
26// headers
27// ----------------------------------------------------------------------------
28
29#ifndef WX_PRECOMP
a2d49353 30 #include "wx/wx.h"
58580a7e
JS
31#endif
32
a2d49353 33#include "wx/gizmos/multicell.h"
58580a7e
JS
34
35
36
37
38//---------------------------------------------------------------------------
39
40IMPLEMENT_ABSTRACT_CLASS(wxMultiCellSizer, wxSizer);
cd72551c 41IMPLEMENT_ABSTRACT_CLASS(wxMultiCellItemHandle, wxObject);
58580a7e
JS
42
43//---------------------------------------------------------------------------
44// wxMultiCellItemHandle
45//---------------------------------------------------------------------------
46/*
a2d49353 47 *Function Name: wxMultiCellItemHandle :: wxMultiCellItemHandle
58580a7e 48 *
a2d49353
WS
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
58580a7e 57 *
a2d49353 58 *Description: This is the constructor for the class.
58580a7e
JS
59 *
60 */
61
62void wxMultiCellItemHandle :: Initialize( int row, int column, int height, int width, wxSize size, wxResizable Style, wxSize weight, int align)
63{
a2d49353
WS
64 m_column = column;
65 m_row = row;
66 m_width = width;
67 m_height = height;
58580a7e 68
a2d49353
WS
69 m_style = Style;
70 m_fixedSize = size;
71 m_alignment = align;
72 m_weight = weight;
58580a7e
JS
73}
74//---------------------------------------------------------------------------
75wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, int height, int width, wxSize size, wxResizable Style, wxSize weight, int align)
76{
a2d49353 77 Initialize(row, column,height, width, size, Style, weight, align);
58580a7e
JS
78}
79//---------------------------------------------------------------------------
80wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, wxSize size, wxResizable style, wxSize weight, int align)
81{
a2d49353 82 Initialize(row, column,1, 1, size, style, weight, align);
58580a7e
JS
83}
84//---------------------------------------------------------------------------
85wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, wxResizable style, wxSize weight, int align)
86{
a2d49353 87 Initialize(row, column, 1, 1, wxSize(1, 1), style, weight, align);
58580a7e
JS
88}
89//---------------------------------------------------------------------------
90wxMultiCellItemHandle :: wxMultiCellItemHandle( int row, int column, int align)
91{
a2d49353 92 Initialize(row, column, 1, 1, wxSize(1,1), wxNOT_RESIZABLE, wxSize(1, 1), align);
58580a7e
JS
93}
94
95//---------------------------------------------------------------------------
96int wxMultiCellItemHandle::GetColumn()
97{
a2d49353 98 return m_column;
58580a7e
JS
99}
100//---------------------------------------------------------------------------
101int wxMultiCellItemHandle::GetRow()
102{
a2d49353 103 return m_row;
58580a7e
JS
104}
105//---------------------------------------------------------------------------
106int wxMultiCellItemHandle::GetWidth()
107{
a2d49353 108 return m_width;
58580a7e
JS
109}
110//---------------------------------------------------------------------------
111int wxMultiCellItemHandle::GetHeight()
112{
a2d49353 113 return m_height;
58580a7e
JS
114}
115//---------------------------------------------------------------------------
116wxResizable wxMultiCellItemHandle :: GetStyle()
117{
a2d49353 118 return m_style;
58580a7e
JS
119};
120//---------------------------------------------------------------------------
121wxSize wxMultiCellItemHandle :: GetLocalSize()
122{
a2d49353 123 return m_fixedSize;
58580a7e
JS
124};
125//---------------------------------------------------------------------------
126int wxMultiCellItemHandle :: GetAlignment()
127{
a2d49353 128 return m_alignment;
58580a7e
JS
129};
130//---------------------------------------------------------------------------
131wxSize wxMultiCellItemHandle :: GetWeight()
132{
a2d49353 133 return m_weight;
58580a7e
JS
134};
135
136
137
138//---------------------------------------------------------------------------
139
140//---------------------------------------------------------------------------
141// wxMultiCellSizer
142//---------------------------------------------------------------------------
143
144/*
a2d49353 145 *Function Name: wxMultiCellSizer::Initialize
58580a7e 146 *
a2d49353 147 *Parameters: wxsize Initial size of sizer
58580a7e 148 *
a2d49353
WS
149 *Description: This is a common function to initialize all the members of
150 * this class. It is only called from the constructors
58580a7e
JS
151 *
152 */
153
154void wxMultiCellSizer::Initialize( wxSize size )
155{
a2d49353
WS
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;
58580a7e
JS
174}
175//---------------------------------------------------------------------------
176wxMultiCellSizer::wxMultiCellSizer( wxSize & size )
177{
a2d49353 178 Initialize(size);
58580a7e
JS
179}
180//---------------------------------------------------------------------------
181wxMultiCellSizer::wxMultiCellSizer( int rows, int cols)
182{
a2d49353
WS
183 wxSize size(cols, rows);
184 Initialize(size);
58580a7e
JS
185}
186//---------------------------------------------------------------------------
187wxMultiCellSizer::~wxMultiCellSizer()
188{
a2d49353 189 WX_CLEAR_LIST(wxSizerItemList, m_children);
58580a7e 190
a2d49353
WS
191 free(m_maxHeight);
192 free(m_maxWidth);
193 free(m_rowStretch);
194 free(m_colStretch);
58580a7e 195
a2d49353
WS
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);
58580a7e
JS
203}
204//---------------------------------------------------------------------------
205bool wxMultiCellSizer::EnableGridLines(wxWindow *win)
206{
a2d49353
WS
207 m_win = win;
208 return true;
58580a7e
JS
209}
210//---------------------------------------------------------------------------
211bool wxMultiCellSizer::SetGridPen(wxPen *pen)
212{
a2d49353
WS
213 m_pen = pen;
214 return true;
58580a7e
JS
215}
216
217//---------------------------------------------------------------------------
218bool wxMultiCellSizer::SetDefaultCellSize(wxSize size)
219{
a2d49353
WS
220 m_defaultCellSize = size;
221 return true;
58580a7e
JS
222}
223//---------------------------------------------------------------------------
224bool wxMultiCellSizer::SetColumnWidth(int column, int colSize, bool expandable)
225{
a2d49353
WS
226 if (expandable)
227 {
228 m_minSizes[column]->SetWidth(-colSize);
229 }
230 else
231 {
232 m_minSizes[column]->SetWidth(colSize);
233 }
234 return true;
58580a7e
JS
235}
236//---------------------------------------------------------------------------
237bool wxMultiCellSizer::SetRowHeight(int row, int rowSize, bool expandable)
238{
a2d49353
WS
239 if (expandable)
240 {
241 m_minSizes[row]->SetHeight(-rowSize);
242 }
243 else
244 {
245 m_minSizes[row]->SetHeight(rowSize);
246 }
247 return true;
58580a7e
JS
248}
249//---------------------------------------------------------------------------
250void wxMultiCellSizer::RecalcSizes()
251{
a2d49353
WS
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 wxSizerItemList::compatibility_iterator current = m_children.GetFirst();
300 while (current)
301 {
302 wxSizerItem *item = current->GetData();
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() );
422d0ff0
WS
317 if (c_size.GetHeight() != wxDefaultCoord ||
318 c_size.GetWidth() != wxDefaultCoord)
a2d49353
WS
319 {
320 minSize.SetHeight(wxMax(minSize.GetHeight(), c_size.GetHeight()));
321 minSize.SetWidth(wxMax(minSize.GetWidth(), c_size.GetWidth()));
322 }
323 if (rect->GetStyle() & wxHORIZONTAL_RESIZABLE ||
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 }
374 current = current->GetNext();
375 }
58580a7e
JS
376}
377//---------------------------------------------------------------------------
378wxSize wxMultiCellSizer::CalcMin()
379{
a2d49353
WS
380 if (m_children.GetCount() == 0)
381 return wxSize(10,10);
58580a7e 382
a2d49353
WS
383 GetMinimums();
384 int m_minWidth = Sum(m_maxWidth, m_cell_count.GetWidth());
385 int m_minHeight = Sum(m_maxHeight, m_cell_count.GetHeight());
386 return wxSize( m_minWidth, m_minHeight );
58580a7e
JS
387}
388//---------------------------------------------------------------------------
389void wxMultiCellSizer :: GetMinimums()
390{
a2d49353
WS
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
403 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
404 while (node)
405 {
406 wxSizerItem *item = node->GetData();
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();
422d0ff0
WS
457 if (c_size.GetHeight() != wxDefaultCoord ||
458 c_size.GetWidth() != wxDefaultCoord)
a2d49353
WS
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
488 if (!(rect->GetStyle() & wxHORIZONTAL_RESIZABLE || m_minSizes[col]->GetWidth() < 0))
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 }
505 node = node->GetNext();
506 }
507 }
58580a7e
JS
508} // wxMultiCellSizer :: GetMinimums
509//---------------------------------------------------------------------------
510/*
a2d49353 511 *Function Name: wxMultiCellSizer :: Sum
58580a7e 512 *
a2d49353
WS
513 *Parameters: int* pointer to array of ints
514 * int Number of cells to sum up
58580a7e 515 *
a2d49353
WS
516 *Description: This member function sums up all the elements of the array which
517 * preceed the specified cell.
58580a7e 518 *
a2d49353 519 *Returns: int Sum
58580a7e
JS
520 *
521 */
522
523int wxMultiCellSizer :: Sum(int *array, int x)
524{
a2d49353
WS
525 int sum = 0;
526 while (x--)
527 {
528 sum += array[x];
529 }
530 return sum;
58580a7e
JS
531}
532//---------------------------------------------------------------------------
533/*
a2d49353 534 *Function Name: wxMultiCellSizer :: DrawGridLines
58580a7e 535 *
a2d49353 536 *Parameters: wxDC Device context
58580a7e 537 *
a2d49353 538 *Description: This function draws the grid lines in the specified device context.
58580a7e
JS
539 *
540 */
541
542void wxMultiCellSizer :: DrawGridLines(wxDC& dc)
543{
a2d49353
WS
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 }
58580a7e
JS
563}
564//---------------------------------------------------------------------------
565// Define the repainting behaviour
566/*
a2d49353 567 *Function Name: wxMultiCellSizer::OnPaint
58580a7e 568 *
a2d49353 569 *Parameters: wxDC Device context
58580a7e 570 *
a2d49353
WS
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.
58580a7e
JS
575 *
576 */
577
578void wxMultiCellSizer::OnPaint(wxDC& dc )
579{
a2d49353
WS
580 if (m_win)
581 {
582 DrawGridLines(dc);
583 }
58580a7e
JS
584}
585
586
587//---------------------------------------------------------------------------
588//---------------------------------------------------------------------------
589
590
591
592
a2d49353 593#define CELL_LOC(row, col) ((row) * m_maxCols + col)
58580a7e
JS
594
595//---------------------------------------------------------------------------
596// wxCell
597//---------------------------------------------------------------------------
598/*
a2d49353 599 *Function Name: wxCell : wxLayoutConstraints
58580a7e 600 *
a2d49353 601 *Description: This class is used by wxMultiCellCanvas for internal storage
58580a7e
JS
602 *
603 */
604
605class wxCell : public wxLayoutConstraints
606{
607public:
a2d49353
WS
608 wxCell(wxWindow *win)
609 {
610 m_window = win;
611 };
58580a7e 612
a2d49353 613 wxWindow *m_window;
58580a7e
JS
614};
615
616
617
618//---------------------------------------------------------------------------
619// wxMultiCellCanvas
620//---------------------------------------------------------------------------
621wxMultiCellCanvas :: wxMultiCellCanvas(wxWindow *par, int numRows, int numCols)
622 : wxFlexGridSizer(numRows, numCols, 0, 0)
623{
a2d49353 624 m_cells = (wxCell **)calloc(numRows * numCols, sizeof(wxCell *));
58580a7e 625
a2d49353
WS
626 m_parent = par;
627 m_maxRows = numRows;
628 m_maxCols = numCols;
629 m_minCellSize = wxSize(5, 5);
58580a7e
JS
630}
631//---------------------------------------------------------------------------
58580a7e
JS
632void wxMultiCellCanvas :: Add(wxWindow *win, unsigned int row, unsigned int col)
633{
c3f815fa 634 // thanks to unsigned data row and col are always >= 0
a2d49353 635 wxASSERT_MSG( /* row >= 0 && */ row < m_maxRows,
8c7e3f14 636 wxString::Format(_T("Row %d out of bounds (0..%d)"), row, m_maxRows) );
a2d49353 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
a2d49353 640 wxASSERT_MSG(m_cells[CELL_LOC(row, col)] == NULL, wxT("Cell already occupied"));
58580a7e 641
a2d49353
WS
642 wxCell *newCell = new wxCell(win);
643 m_cells[CELL_LOC(row,col)] = newCell;
58580a7e
JS
644}
645//---------------------------------------------------------------------------
646void wxMultiCellCanvas :: CalculateConstraints()
647{
a2d49353
WS
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
656 m_cells[CELL_LOC(row, col)] = new wxCell(new wxStaticText(m_parent, wxID_ANY, wxT("")));
657 }
658 wxFlexGridSizer::Add(m_cells[CELL_LOC(row, col)]->m_window);
659 }
660 }
58580a7e
JS
661}
662
663/*** End of File ***/
8c7e3f14 664