home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / src / gizmos / multicell.cpp < prev    next >
C/C++ Source or Header  |  2002-12-16  |  21KB  |  671 lines

  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. 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() & wxHORIZONTAL_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() & wxHORIZONTAL_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, wxT("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 ***/
  671.