home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / radiobox.cpp < prev    next >
C/C++ Source or Header  |  2002-08-30  |  39KB  |  1,234 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        radiobox.cpp
  3. // Purpose:     wxRadioBox
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/12/99
  7. // RCS-ID:      $Id: RADIOBOX.CPP,v 1.16 2002/08/30 13:37:08 DW Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // For compilers that support precompilation, includes "wx.h".
  13. #include "wx/wxprec.h"
  14.  
  15. #ifndef WX_PRECOMP
  16.     #include <stdio.h>
  17.     #include "wx/setup.h"
  18.     #include "wx/wxchar.h"
  19.     #include "wx/string.h"
  20.     #include "wx/bitmap.h"
  21.     #include "wx/brush.h"
  22.     #include "wx/radiobox.h"
  23. #endif
  24.  
  25. #include "wx/os2/private.h"
  26.  
  27. IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
  28.  
  29. // ---------------------------------------------------------------------------
  30. // private functions
  31. // ---------------------------------------------------------------------------
  32.  
  33. // wnd proc for radio buttons
  34. MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
  35.                                    ,UINT uMessage
  36.                                    ,MPARAM wParam
  37.                                    ,MPARAM lParam
  38.                                   );
  39. MRESULT EXPENTRY wxRadioBoxWndProc( HWND   hWnd
  40.                                    ,UINT   uMessage
  41.                                    ,MPARAM wParam
  42.                                    ,MPARAM lParam
  43.                                   );
  44.  
  45. // ---------------------------------------------------------------------------
  46. // global vars
  47. // ---------------------------------------------------------------------------
  48.  
  49. // the pointer to standard radio button wnd proc
  50. extern void  wxAssociateWinWithHandle( HWND         hWnd
  51.                                       ,wxWindowOS2* pWin
  52.                                      );
  53. static WXFARPROC                    fnWndProcRadioBtn = NULL;
  54. static WXFARPROC                    fnWndProcRadioBox = NULL;
  55.  
  56. // ===========================================================================
  57. // implementation
  58. // ===========================================================================
  59.  
  60. // ---------------------------------------------------------------------------
  61. // wxRadioBox
  62. // ---------------------------------------------------------------------------
  63.  
  64. // Radio box item
  65. wxRadioBox::wxRadioBox()
  66. {
  67.     m_nSelectedButton = -1;
  68.     m_nNoItems = 0;
  69.     m_nNoRowsOrCols = 0;
  70.     m_ahRadioButtons = NULL;
  71.     m_nMajorDim = 0;
  72.     m_pnRadioWidth = NULL;
  73.     m_pnRadioHeight = NULL;
  74. } // end of wxRadioBox::wxRadioBox
  75.  
  76. wxRadioBox::~wxRadioBox()
  77. {
  78.     m_isBeingDeleted = TRUE;
  79.  
  80.     if (m_ahRadioButtons)
  81.     {
  82.         int                         i;
  83.         for (i = 0; i < m_nNoItems; i++)
  84.             ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
  85.         delete[] m_ahRadioButtons;
  86.     }
  87.     if (m_pnRadioWidth)
  88.         delete[] m_pnRadioWidth;
  89.     if (m_pnRadioHeight)
  90.         delete[] m_pnRadioHeight;
  91. } // end of wxRadioBox::~wxRadioBox
  92.  
  93. void wxRadioBox::AdjustButtons(
  94.   int                               nX
  95. , int                               nY
  96. , int                               nWidth
  97. , int                               nHeight
  98. , int                               nSizeFlags
  99. )
  100. {
  101.     wxSize                          vMaxSize;
  102.     int                             nXOffset = nX;
  103.     int                             nYOffset = nY + nHeight;
  104.     int                             nCx1;
  105.     int                             nCy1;
  106.     int                             nStartX;
  107.     int                             nStartY;
  108.     int                             nMaxWidth;
  109.     int                             nMaxHeight;
  110.     int                             nTotWidth;
  111.     int                             nTotHeight;
  112.  
  113.     wxGetCharSize( m_hWnd
  114.                   ,&nCx1
  115.                   ,&nCy1
  116.                   ,&GetFont()
  117.                  );
  118.     vMaxSize   = GetMaxButtonSize();
  119.     nMaxWidth  = vMaxSize.x;
  120.     nMaxHeight = vMaxSize.y;
  121.  
  122.     nXOffset += nCx1;
  123.     nYOffset -= (nMaxHeight + ((3*nCy1)/2));
  124.  
  125.     nStartX = nXOffset;
  126.     nStartY = nYOffset;
  127.  
  128.     for (int i = 0; i < m_nNoItems; i++)
  129.     {
  130.         //
  131.         // The last button in the row may be wider than the other ones as the
  132.         // radiobox may be wider than the sum of the button widths (as it
  133.         // happens, for example, when the radiobox label is very long)
  134.         //
  135.         bool                        bIsLastInTheRow;
  136.  
  137.         if (m_windowStyle & wxRA_SPECIFY_COLS)
  138.         {
  139.             //
  140.             // Item is the last in its row if it is a multiple of the number of
  141.             // columns or if it is just the last item
  142.             //
  143.             int                     n = i + 1;
  144.  
  145.             bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
  146.         }
  147.         else // winRA_SPECIFY_ROWS
  148.         {
  149.             //
  150.             // Item is the last in the row if it is in the last columns
  151.             //
  152.             bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
  153.         }
  154.  
  155.         //
  156.         // Is this the start of new row/column?
  157.         //
  158.         if (i && (i % m_nMajorDim == 0))
  159.         {
  160.             if (m_windowStyle & wxRA_SPECIFY_ROWS)
  161.             {
  162.  
  163.                 //
  164.                 // Start of new column
  165.                 //
  166.                 nYOffset = nStartY;
  167.                 nXOffset += nMaxWidth + nCx1;
  168.             }
  169.             else // start of new row
  170.             {
  171.                 nXOffset = nStartX;
  172.                 nYOffset -= nMaxHeight;
  173.                 if (m_pnRadioWidth[0] > 0L)
  174.                     nYOffset -= nCy1/2;
  175.             }
  176.         }
  177.  
  178.         int                         nWidthBtn;
  179.  
  180.         if (bIsLastInTheRow)
  181.         {
  182.             //
  183.             // Make the button go to the end of radio box
  184.             //
  185.             nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
  186.             if (nWidthBtn < nMaxWidth)
  187.                 nWidthBtn = nMaxWidth;
  188.         }
  189.         else
  190.         {
  191.             //
  192.             // Normal button, always of the same size
  193.             //
  194.             nWidthBtn = nMaxWidth;
  195.         }
  196.  
  197.         //
  198.         // Make all buttons of the same, maximal size - like this they
  199.         // cover the radiobox entirely and the radiobox tooltips are always
  200.         // shown (otherwise they are not when the mouse pointer is in the
  201.         // radiobox part not beYInt32ing to any radiobutton)
  202.         //
  203.         ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
  204.                           ,HWND_TOP
  205.                           ,(LONG)nXOffset
  206.                           ,(LONG)nYOffset
  207.                           ,(LONG)nWidthBtn
  208.                           ,(LONG)nMaxHeight
  209.                           ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
  210.                          );
  211.         //
  212.         // Where do we put the next button?
  213.         //
  214.         if (m_windowStyle & wxRA_SPECIFY_ROWS)
  215.         {
  216.             //
  217.             // Below this one
  218.             //
  219.             nYOffset -= nMaxHeight;
  220.             if (m_pnRadioWidth[0] > 0)
  221.                 nYOffset -= nCy1/2;
  222.         }
  223.         else
  224.         {
  225.             //
  226.             // To the right of this one
  227.             //
  228.             nXOffset += nWidthBtn + nCx1;
  229.         }
  230.     }
  231. } // end of wxRadioBox::AdjustButtons
  232.  
  233. void wxRadioBox::Command (
  234.   wxCommandEvent&                   rEvent
  235. )
  236. {
  237.     SetSelection (rEvent.GetInt());
  238.     ProcessCommand(rEvent);
  239. } // end of wxRadioBox::Command
  240.  
  241. bool wxRadioBox::ContainsHWND(
  242.   WXHWND                            hWnd
  243. ) const
  244. {
  245.     size_t                          nCount = GetCount();
  246.     size_t                          i;
  247.  
  248.     for (i = 0; i < nCount; i++)
  249.     {
  250.         if (GetRadioButtons()[i] == hWnd)
  251.             return TRUE;
  252.     }
  253.     return FALSE;
  254. } // end of wxRadioBox::ContainsHWND
  255.  
  256. bool wxRadioBox::Create(
  257.   wxWindow*                         pParent
  258. , wxWindowID                        vId
  259. , const wxString&                   rsTitle
  260. , const wxPoint&                    rPos
  261. , const wxSize&                     rSize
  262. , int                               nNum
  263. , const wxString                    asChoices[]
  264. , int                               nMajorDim
  265. , long                              lStyle
  266. #if wxUSE_VALIDATORS
  267. , const wxValidator&                rVal
  268. #endif
  269. , const wxString&                   rsName
  270. )
  271. {
  272.     wxColour                        vColour;
  273.     LONG                            lColor;
  274.  
  275.     vColour.Set(wxString("BLACK"));
  276.     m_backgroundColour = pParent->GetBackgroundColour();
  277.     m_nSelectedButton = -1;
  278.     m_nNoItems = 0;
  279.  
  280.     m_nMajorDim     = nMajorDim == 0 ? nNum : nMajorDim;
  281.     m_nNoRowsOrCols = nMajorDim;
  282.  
  283.     //
  284.     // Common initialization
  285.     //
  286.     if (!CreateControl( pParent
  287.                        ,vId
  288.                        ,rPos
  289.                        ,rSize
  290.                        ,lStyle
  291. #if wxUSE_VALIDATORS
  292.                        ,rVal
  293. #endif
  294.                        ,rsName
  295.                       ))
  296.         return FALSE;
  297.     if (!OS2CreateControl( "STATIC"
  298.                           ,SS_GROUPBOX
  299.                           ,rPos
  300.                           ,rSize
  301.                           ,rsTitle
  302.                          ))
  303.         return FALSE;
  304.  
  305.     wxAssociateWinWithHandle(m_hWnd, this);
  306. #if RADIOBTN_PARENT_IS_RADIOBOX
  307.     HWND                            hWndParent = GetHwnd();
  308. #else
  309.     HWND                            hWndParent = GetHwndOf(pParent);
  310. #endif
  311.     HFONT                           hFont;
  312.  
  313.     //
  314.     // Some radio boxes test consecutive id.
  315.     //
  316.     m_nNoItems = nNum;
  317.     (void)NewControlId();
  318.     m_ahRadioButtons = new WXHWND[nNum];
  319.     m_pnRadioWidth   = new int[nNum];
  320.     m_pnRadioHeight  = new int[nNum];
  321.  
  322.     for (int i = 0; i < nNum; i++)
  323.     {
  324.         m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
  325.  
  326.         long                        lStyleBtn = BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE;
  327.         int                         nNewId = NewControlId();
  328.  
  329.         if (i == 0 && lStyle == 0)
  330.             lStyleBtn |= WS_GROUP;
  331.  
  332.         HWND                        hWndBtn = (WXHWND)::WinCreateWindow ( GetHwndOf(pParent)
  333.                                                                          ,WC_BUTTON
  334.                                                                          ,asChoices[i]
  335.                                                                          ,lStyleBtn
  336.                                                                          ,0, 0, 0, 0
  337.                                                                          ,GetWinHwnd(pParent)
  338.                                                                          ,HWND_TOP
  339.                                                                          ,(HMENU)nNewId
  340.                                                                          ,NULL
  341.                                                                          ,NULL
  342.                                                                         );
  343.         lColor = (LONG)vColour.GetPixel();
  344.         ::WinSetPresParam( hWndBtn
  345.                           ,PP_FOREGROUNDCOLOR
  346.                           ,sizeof(LONG)
  347.                           ,(PVOID)&lColor
  348.                          );
  349.         lColor = (LONG)m_backgroundColour.GetPixel();
  350.  
  351.         ::WinSetPresParam( hWndBtn
  352.                           ,PP_BACKGROUNDCOLOR
  353.                           ,sizeof(LONG)
  354.                           ,(PVOID)&lColor
  355.                          );
  356.         if (!hWndBtn)
  357.         {
  358.             return FALSE;
  359.         }
  360.         m_ahRadioButtons[i] = (WXHWND)hWndBtn;
  361.         SubclassRadioButton((WXHWND)hWndBtn);
  362.         wxAssociateWinWithHandle(hWndBtn, this);
  363.         wxOS2SetFont( hWndBtn
  364.                      ,*wxSMALL_FONT
  365.                     );
  366.         ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
  367.         m_aSubControls.Add(nNewId);
  368.     }
  369.  
  370.     //
  371.     // Create a dummy radio control to end the group.
  372.     //
  373.     (void)::WinCreateWindow ( GetHwndOf(pParent)
  374.                              ,WC_BUTTON
  375.                              ,""
  376.                              ,WS_GROUP | BS_AUTORADIOBUTTON
  377.                              ,0, 0, 0, 0
  378.                              ,GetWinHwnd(pParent)
  379.                              ,HWND_TOP
  380.                              ,(HMENU)NewControlId()
  381.                              ,NULL
  382.                              ,NULL
  383.                             );
  384.     SetFont(*wxSMALL_FONT);
  385.     fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
  386.                                                        ,(PFNWP)wxRadioBoxWndProc
  387.                                                       );
  388.     ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
  389.     lColor = (LONG)vColour.GetPixel();
  390.     ::WinSetPresParam( m_hWnd
  391.                       ,PP_FOREGROUNDCOLOR
  392.                       ,sizeof(LONG)
  393.                       ,(PVOID)&lColor
  394.                      );
  395.     ::WinSetPresParam( m_hWnd
  396.                       ,PP_BORDERDARKCOLOR
  397.                       ,sizeof(LONG)
  398.                       ,(PVOID)&lColor
  399.                      );
  400.     lColor = (LONG)m_backgroundColour.GetPixel();
  401.  
  402.     ::WinSetPresParam( m_hWnd
  403.                       ,PP_BACKGROUNDCOLOR
  404.                       ,sizeof(LONG)
  405.                       ,(PVOID)&lColor
  406.                      );
  407.     ::WinSetPresParam( m_hWnd
  408.                       ,PP_BORDERLIGHTCOLOR
  409.                       ,sizeof(LONG)
  410.                       ,(PVOID)&lColor
  411.                      );
  412.     SetXComp(0);
  413.     SetYComp(0);
  414.     SetSelection(0);
  415.     SetSize( rPos.x
  416.             ,rPos.y
  417.             ,rSize.x
  418.             ,rSize.y
  419.            );
  420.     return TRUE;
  421. } // end of wxRadioBox::Create
  422.  
  423. wxSize wxRadioBox::DoGetBestSize() const
  424. {
  425.     return (GetTotalButtonSize(GetMaxButtonSize()));
  426. } // end of WinGuiBase_CRadioBox::DoGetBestSize
  427.  
  428. void wxRadioBox::DoSetSize(
  429.   int                               nX
  430. , int                               nY
  431. , int                               nWidth
  432. , int                               nHeight
  433. , int                               nSizeFlags
  434. )
  435. {
  436.     int                             nCurrentX;
  437.     int                             nCurrentY;
  438.     int                             nWidthOld;
  439.     int                             nHeightOld;
  440.     int                             nXx = nX;
  441.     int                             nYy = nY;
  442. #if RADIOBTN_PARENT_IS_RADIOBOX
  443.     int                             nXOffset = 0;
  444.     int                             nYOffset = 0;
  445. #else
  446.     int                             nXOffset = nXx;
  447.     int                             nYOffset = nYy;
  448. #endif
  449.     int                             nCx1;
  450.     int                             nCy1;
  451.     wxSize                          vMaxSize = GetMaxButtonSize();
  452.     int                             nMaxWidth;
  453.     int                             nMaxHeight;
  454.     wxSize                          vTotSize;
  455.     int                             nTotWidth;
  456.     int                             nTotHeight;
  457.     int                             nStartX;
  458.     int                             nStartY;
  459.  
  460.     m_nSizeFlags = nSizeFlags;
  461.     GetPosition( &nCurrentX
  462.                 ,&nCurrentY
  463.                );
  464.     GetSize( &nWidthOld
  465.             ,&nHeightOld
  466.            );
  467.  
  468.     if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
  469.         nXx = nCurrentX;
  470.     if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
  471.         nYy = nCurrentY;
  472.     if (nYy < 0)
  473.         nYy = 0;
  474.     if (nXx < 0)
  475.         nXx = 0;
  476.  
  477.     wxGetCharSize( m_hWnd
  478.                   ,&nCx1
  479.                   ,&nCy1
  480.                   ,&GetFont()
  481.                  );
  482.  
  483.     //
  484.     // Attempt to have a look coherent with other platforms: We compute the
  485.     // biggest toggle dim, then we align all items according this value.
  486.     //
  487.     vMaxSize   = GetMaxButtonSize();
  488.     nMaxWidth  = vMaxSize.x;
  489.     nMaxHeight = vMaxSize.y;
  490.  
  491.     vTotSize   = GetTotalButtonSize(vMaxSize);
  492.     nTotWidth  = vTotSize.x;
  493.     nTotHeight = vTotSize.y;
  494.  
  495.     //
  496.     // Only change our width/height if asked for
  497.     //
  498.     if (nWidth == -1)
  499.     {
  500.         if (nSizeFlags & wxSIZE_AUTO_WIDTH )
  501.             nWidth = nTotWidth;
  502.         else
  503.             nWidth = nWidthOld;
  504.     }
  505.  
  506.     if (nHeight == -1)
  507.     {
  508.         if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
  509.             nHeight = nTotHeight;
  510.         else
  511.             nHeight = nHeightOld;
  512.     }
  513.  
  514.     wxWindowOS2*                    pParent = (wxWindowOS2*)GetParent();
  515.  
  516.     if (pParent)
  517.     {
  518.         int                         nOS2Height = GetOS2ParentHeight(pParent);
  519.  
  520.         nYy = nOS2Height - (nYy + nHeight);
  521.         nYOffset = nYy + nHeight;
  522.     }
  523.     else
  524.     {
  525.         RECTL                       vRect;
  526.  
  527.         ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
  528.         nYy = vRect.yTop - (nYy + nHeight);
  529.     }
  530.     ::WinSetWindowPos( GetHwnd()
  531.                       ,HWND_TOP
  532.                       ,(LONG)nXx
  533.                       ,(LONG)nYy
  534.                       ,(LONG)nWidth
  535.                       ,(LONG)nHeight
  536.                       ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
  537.                      );
  538.  
  539.     //
  540.     // Now position all the buttons: the current button will be put at
  541.     // wxPoint(x_offset, y_offset) and the new row/column will start at
  542.     // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
  543.     // maxHeight) except for the buttons in the last column which should extend
  544.     // to the right border of radiobox and thus can be wider than this.
  545.     //
  546.     // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
  547.     // left to right order and m_majorDim is the number of columns while
  548.     // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
  549.     // m_majorDim is the number of rows.
  550.     //
  551.     nXOffset += nCx1;
  552.     nYOffset -= (nMaxHeight + ((3*nCy1)/2));
  553.  
  554.     nStartX = nXOffset;
  555.     nStartY = nYOffset;
  556.  
  557.     for (int i = 0; i < m_nNoItems; i++)
  558.     {
  559.         //
  560.         // The last button in the row may be wider than the other ones as the
  561.         // radiobox may be wider than the sum of the button widths (as it
  562.         // happens, for example, when the radiobox label is very long)
  563.         //
  564.         bool                        bIsLastInTheRow;
  565.  
  566.         if (m_windowStyle & wxRA_SPECIFY_COLS)
  567.         {
  568.             //
  569.             // Item is the last in its row if it is a multiple of the number of
  570.             // columns or if it is just the last item
  571.             //
  572.             int                  n = i + 1;
  573.  
  574.             bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
  575.         }
  576.         else // winRA_SPECIFY_ROWS
  577.         {
  578.             //
  579.             // Item is the last in the row if it is in the last columns
  580.             //
  581.             bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
  582.         }
  583.  
  584.         //
  585.         // Is this the start of new row/column?
  586.         //
  587.         if (i && (i % m_nMajorDim == 0))
  588.         {
  589.             if (m_windowStyle & wxRA_SPECIFY_ROWS)
  590.             {
  591.  
  592.                 //
  593.                 // Start of new column
  594.                 //
  595.                 nYOffset = nStartY;
  596.                 nXOffset += nMaxWidth + nCx1;
  597.             }
  598.             else // start of new row
  599.             {
  600.                 nXOffset = nStartX;
  601.                 nYOffset -= nMaxHeight;
  602.                 if (m_pnRadioWidth[0] > 0L)
  603.                     nYOffset -= nCy1/2;
  604.             }
  605.         }
  606.  
  607.         int                      nWidthBtn;
  608.  
  609.         if (bIsLastInTheRow)
  610.         {
  611.             //
  612.             // Make the button go to the end of radio box
  613.             //
  614.             nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
  615.             if (nWidthBtn < nMaxWidth)
  616.                 nWidthBtn = nMaxWidth;
  617.         }
  618.         else
  619.         {
  620.             //
  621.             // Normal button, always of the same size
  622.             //
  623.             nWidthBtn = nMaxWidth;
  624.         }
  625.  
  626.         //
  627.         // Make all buttons of the same, maximal size - like this they
  628.         // cover the radiobox entirely and the radiobox tooltips are always
  629.         // shown (otherwise they are not when the mouse pointer is in the
  630.         // radiobox part not beinting to any radiobutton)
  631.         //
  632.         ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
  633.                           ,HWND_TOP
  634.                           ,(LONG)nXOffset
  635.                           ,(LONG)nYOffset
  636.                           ,(LONG)nWidthBtn
  637.                           ,(LONG)nMaxHeight
  638.                           ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
  639.                          );
  640.         GetParent()->Refresh();
  641.         //
  642.         // Where do we put the next button?
  643.         //
  644.         if (m_windowStyle & wxRA_SPECIFY_ROWS)
  645.         {
  646.             //
  647.             // Below this one
  648.             //
  649.             nYOffset -= nMaxHeight;
  650.             if (m_pnRadioWidth[0] > 0)
  651.                 nYOffset -= nCy1/2;
  652.         }
  653.         else
  654.         {
  655.             //
  656.             // To the right of this one
  657.             //
  658.             nXOffset += nWidthBtn + nCx1;
  659.         }
  660.     }
  661. } // end of wxRadioBox::DoSetSize
  662.  
  663. void wxRadioBox::Enable(
  664.   int                               nItem
  665. , bool                              bEnable
  666. )
  667. {
  668.     wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
  669.                  wxT("invalid item in wxRadioBox::Enable()") );
  670.  
  671.     ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
  672. } // end of wxRadioBox::Enable
  673.  
  674. bool wxRadioBox::Enable(
  675.   bool                              bEnable
  676. )
  677. {
  678.     if ( !wxControl::Enable(bEnable) )
  679.         return FALSE;
  680.     for (int i = 0; i < m_nNoItems; i++)
  681.         ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
  682.     return TRUE;
  683. } // end of wxRadioBox::Enable
  684.  
  685. int wxRadioBox::FindString(
  686.   const wxString&                   rsStr
  687. ) const
  688. {
  689.     for (int i = 0; i < m_nNoItems; i++)
  690.     {
  691.         if (rsStr == wxGetWindowText(m_ahRadioButtons[i]) )
  692.             return i;
  693.     }
  694.     return wxNOT_FOUND;
  695. } // end of wxRadioBox::FindString
  696.  
  697. int wxRadioBox::GetColumnCount() const
  698. {
  699.     return GetNumHor();
  700. } // end of wxRadioBox::GetColumnCount
  701.  
  702. int wxRadioBox::GetCount() const
  703. {
  704.     return m_nNoItems;
  705. } // end of wxRadioBox::GetCount
  706.  
  707. wxString wxRadioBox::GetLabel(
  708.   int                               nItem
  709. ) const
  710. {
  711.     wxCHECK_MSG(nItem >= 0 && nItem < m_nNoItems, wxT(""), wxT("invalid radiobox index") );
  712.  
  713.     return wxGetWindowText(m_ahRadioButtons[nItem]);
  714. } // end of wxRadioBox::GetLabel
  715.  
  716. wxSize wxRadioBox::GetMaxButtonSize() const
  717. {
  718.     int                             nWidthMax = 0;
  719.     int                             nHeightMax = 0;
  720.  
  721.     for (int i = 0 ; i < m_nNoItems; i++)
  722.     {
  723.         int                         nWidth;
  724.         int                         nHeight;
  725.  
  726.         if (m_pnRadioWidth[i] < 0L)
  727.         {
  728.             GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
  729.                           ,&nWidth
  730.                           ,&nHeight
  731.                          );
  732.  
  733.             //
  734.             // Adjust the size to take into account the radio box itself
  735.             // FIXME this is totally bogus!
  736.             //
  737.             nWidth  += RADIO_SIZE;
  738.             nHeight *= 3;
  739.             nHeight /= 2;
  740.         }
  741.         else
  742.         {
  743.             nWidth  = m_pnRadioWidth[i];
  744.             nHeight = m_pnRadioHeight[i];
  745.         }
  746.         if (nWidthMax < nWidth )
  747.             nWidthMax = nWidth;
  748.         if (nHeightMax < nHeight )
  749.             nHeightMax = nHeight;
  750.     }
  751.     return(wxSize( nWidthMax
  752.                   ,nHeightMax
  753.                  )
  754.           );
  755. } // end of wxRadioBox::GetMaxButtonSize
  756.  
  757. int wxRadioBox::GetNumHor() const
  758. {
  759.     if ( m_windowStyle & wxRA_SPECIFY_ROWS )
  760.     {
  761.         return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
  762.     }
  763.     else
  764.     {
  765.         return m_nMajorDim;
  766.     }
  767. } // end of wxRadioBox::GetNumHor
  768.  
  769. int wxRadioBox::GetNumVer() const
  770. {
  771.     if ( m_windowStyle & wxRA_SPECIFY_ROWS )
  772.     {
  773.         return m_nMajorDim;
  774.     }
  775.     else
  776.     {
  777.         return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
  778.     }
  779. } // end of wxRadioBox::GetNumVer
  780.  
  781. void wxRadioBox::GetPosition(
  782.   int*                              pnX
  783. , int*                              pnY
  784. ) const
  785. {
  786.     wxWindowOS2*                    pParent = GetParent();
  787.     RECT                            vRect = { -1, -1, -1, -1 };;
  788.     POINTL                          vPoint;
  789.     int                             i;
  790.  
  791.     for (i = 0; i < m_nNoItems; i++)
  792.         wxFindMaxSize( m_ahRadioButtons[i]
  793.                       ,&vRect
  794.                      );
  795.     if (m_hWnd)
  796.         wxFindMaxSize( m_hWnd
  797.                       ,&vRect
  798.                      );
  799.  
  800.     //
  801.     // Since we now have the absolute screen coords, if there's a parent we
  802.     // must subtract its top left corner
  803.     //
  804.     vPoint.x = vRect.xLeft;
  805.     vPoint.y = vRect.yTop;
  806.     if (pParent)
  807.     {
  808.         SWP                             vSwp;
  809.  
  810.         ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
  811.         vPoint.x = vSwp.x;
  812.         vPoint.y = vSwp.y;
  813.     }
  814.  
  815.     //
  816.     // We may be faking the client origin. So a window that's really at (0, 30)
  817.     // may appear (to wxWin apps) to be at (0, 0).
  818.     //
  819.     if (GetParent())
  820.     {
  821.         wxPoint                     vPt(GetParent()->GetClientAreaOrigin());
  822.  
  823.         vPoint.x = vPt.x;
  824.         vPoint.y = vPt.y;
  825.     }
  826.     *pnX = vPoint.x;
  827.     *pnX = vPoint.y;
  828. } // end of wxRadioBox::GetPosition
  829.  
  830. int wxRadioBox::GetRowCount() const
  831. {
  832.     return GetNumVer();
  833. } // end of wxRadioBox::GetRowCount
  834.  
  835. // Get single selection, for single choice list items
  836. int wxRadioBox::GetSelection() const
  837. {
  838.     return m_nSelectedButton;
  839. } // end of wxRadioBox::GetSelection
  840.  
  841. void wxRadioBox::GetSize(
  842.   int*                              pnWidth
  843. , int*                              pnHeight
  844. ) const
  845. {
  846.     RECT                            vRect;
  847.     int                             i;
  848.  
  849.     vRect.xLeft   = -1;
  850.     vRect.xRight  = -1;
  851.     vRect.yTop    = -1;
  852.     vRect.yBottom = -1;
  853.  
  854.     if (m_hWnd)
  855.         wxFindMaxSize( m_hWnd
  856.                       ,&vRect
  857.                      );
  858.  
  859.     for (i = 0; i < m_nNoItems; i++)
  860.         wxFindMaxSize( m_ahRadioButtons[i]
  861.                       ,&vRect
  862.                      );
  863.  
  864.     *pnWidth  = vRect.xRight - vRect.xLeft;
  865.     *pnHeight = vRect.yBottom - vRect.yTop;
  866. } // end of wxRadioBox::GetSize
  867.  
  868. // Find string for position
  869. wxString wxRadioBox::GetString(
  870.   int                               nNum
  871. ) const
  872. {
  873.     return wxGetWindowText(m_ahRadioButtons[nNum]);
  874. } // end of wxRadioBox::GetString
  875.  
  876. // For single selection items only
  877. wxString wxRadioBox::GetStringSelection() const
  878. {
  879.     wxString                        sResult;
  880.     int                             nSel = GetSelection();
  881.  
  882.     if (nSel > -1)
  883.         sResult = GetString(nSel);
  884.     return sResult;
  885. } // end of wxRadioBox::GetStringSelection
  886.  
  887. wxSize wxRadioBox::GetTotalButtonSize(
  888.   const wxSize&                     rSizeBtn
  889. ) const
  890. {
  891.     int                             nCx1;
  892.     int                             nCy1;
  893.     int                             nExtraHeight;
  894.     int                             nHeight;
  895.     int                             nWidth;
  896.     int                             nWidthLabel;
  897.  
  898.     wxGetCharSize( m_hWnd
  899.                   ,&nCx1
  900.                   ,&nCy1
  901.                   ,(wxFont*)&GetFont()
  902.                  );
  903.     nExtraHeight = nCy1;
  904.  
  905.     nHeight = GetNumVer() * rSizeBtn.y + (2 * nCy1);
  906.     nWidth  = GetNumHor() * (rSizeBtn.x + nCx1) + nCx1;
  907.  
  908.     //
  909.     // And also wide enough for its label
  910.     //
  911.     GetTextExtent( GetTitle()
  912.                   ,&nWidthLabel
  913.                   ,NULL
  914.                  );
  915.     nWidthLabel += RADIO_SIZE;
  916.     if (nWidthLabel > nWidth)
  917.         nWidth = nWidthLabel;
  918.  
  919.     return(wxSize( nWidth
  920.                   ,nHeight
  921.                  )
  922.           );
  923. } // end of wxRadioBox::GetTotalButtonSize
  924.  
  925. WXHBRUSH wxRadioBox::OnCtlColor(
  926.   WXHDC                             hwinDC
  927. , WXHWND                            hWnd
  928. , WXUINT                            uCtlColor
  929. , WXUINT                            uMessage
  930. , WXWPARAM                          wParam
  931. , WXLPARAM                          lParam
  932. )
  933. {
  934.     HPS                             hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
  935.  
  936.     if (GetParent()->GetTransparentBackground())
  937.         ::GpiSetBackMix(hPS, BM_LEAVEALONE);
  938.     else
  939.         ::GpiSetBackMix(hPS, BM_OVERPAINT);
  940.  
  941.     wxColour                        vColBack = GetBackgroundColour();
  942.  
  943.     ::GpiSetBackColor(hPS, vColBack.GetPixel());
  944.     ::GpiSetColor(hPS, vColBack.GetPixel());
  945.  
  946.  
  947.     wxBrush*                        pBrush = wxTheBrushList->FindOrCreateBrush( vColBack
  948.                                                                                ,wxSOLID
  949.                                                                               );
  950.     return ((WXHBRUSH)pBrush->GetResourceHandle());
  951. } // end of wxRadioBox::OnCtlColor
  952.  
  953. bool wxRadioBox::OS2Command(
  954.   WXUINT                            uCmd
  955. , WXWORD                            wId
  956. )
  957. {
  958.     int                             nSelectedButton = -1;
  959.  
  960.     if (uCmd == BN_CLICKED)
  961.     {
  962.         if (wId == GetId())
  963.             return TRUE;
  964.  
  965.  
  966.         for (int i = 0; i < m_nNoItems; i++)
  967.         {
  968.             if (wId == wxGetWindowId(m_ahRadioButtons[i]))
  969.             {
  970.                 nSelectedButton = i;
  971.                 break;
  972.             }
  973.         }
  974.         if (nSelectedButton == -1)
  975.         {
  976.             //
  977.             // Just ignore it
  978.             //
  979.             return FALSE;
  980.         }
  981.         if (nSelectedButton != m_nSelectedButton)
  982.         {
  983.             m_nSelectedButton = nSelectedButton;
  984.             SendNotificationEvent();
  985.         }
  986.         return TRUE;
  987.     }
  988.     else
  989.         return FALSE;
  990. } // end of wxRadioBox::OS2Command
  991.  
  992. void wxRadioBox::SendNotificationEvent()
  993. {
  994.     wxCommandEvent                  vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
  995.                                            ,m_windowId
  996.                                           );
  997.  
  998.     vEvent.SetInt( m_nSelectedButton );
  999.     vEvent.SetString( GetString(m_nSelectedButton) );
  1000.     vEvent.SetEventObject(this);
  1001.     ProcessCommand(vEvent);
  1002. } // end of wxRadioBox::SendNotificationEvent
  1003.  
  1004. void wxRadioBox::SetFocus()
  1005. {
  1006.     if (m_nNoItems > 0)
  1007.     {
  1008.         if (m_nSelectedButton == -1)
  1009.             ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
  1010.         else
  1011.             ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
  1012.     }
  1013. } // end of wxRadioBox::SetFocus
  1014.  
  1015. bool wxRadioBox::SetFont(
  1016.   const wxFont&                     rFont
  1017. )
  1018. {
  1019.     if (!wxControl::SetFont(rFont))
  1020.     {
  1021.         //
  1022.         // Nothing to do
  1023.         //
  1024.         return FALSE;
  1025.     }
  1026.     //
  1027.     // Also set the font of our radio buttons
  1028.     //
  1029.     WXHFONT                         hFont = wxFont(rFont).GetResourceHandle();
  1030.  
  1031.     for (int n = 0; n < (int)m_nNoItems; n++)
  1032.     {
  1033.         HWND                        hWndBtn = (HWND)m_ahRadioButtons[n];
  1034.  
  1035.         wxOS2SetFont( hWndBtn
  1036.                      ,rFont
  1037.                     );
  1038.         ::WinInvalidateRect(hWndBtn, NULL, FALSE);
  1039.     }
  1040.     return TRUE;
  1041. } // end of wxRadioBox::SetFont
  1042.  
  1043. void wxRadioBox::SetSelection(
  1044.   int                               nNum
  1045. )
  1046. {
  1047.     wxCHECK_RET( (nNum >= 0) && (nNum < m_nNoItems), wxT("invalid radiobox index") );
  1048.  
  1049.     if (m_nSelectedButton >= 0 && m_nSelectedButton < m_nNoItems)
  1050.         ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
  1051.  
  1052.     ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
  1053.     ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
  1054.     m_nSelectedButton = nNum;
  1055. } // end of wxRadioBox::SetSelection
  1056.  
  1057. void wxRadioBox::SetString(
  1058.   int                               nItem
  1059. , const wxString&                   rsLabel
  1060. )
  1061. {
  1062.     wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, wxT("invalid radiobox index") );
  1063.  
  1064.     m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
  1065.     ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
  1066. } // end of wxRadioBox::SetString
  1067.  
  1068. bool wxRadioBox::SetStringSelection(
  1069.   const wxString&                   rsStr
  1070. )
  1071. {
  1072.     int                             nSel = FindString(rsStr);
  1073.  
  1074.     if (nSel > -1)
  1075.     {
  1076.         SetSelection(nSel);
  1077.         return TRUE;
  1078.     }
  1079.     else
  1080.         return FALSE;
  1081. } // end of wxRadioBox::SetStringSelection
  1082.  
  1083. bool wxRadioBox::Show(
  1084.   bool                              bShow
  1085. )
  1086. {
  1087.     int                             nCmdShow = 0;
  1088.  
  1089.     if (!wxControl::Show(bShow))
  1090.         return FALSE;
  1091.  
  1092.     for (int i = 0; i < m_nNoItems; i++)
  1093.     {
  1094.         ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
  1095.     }
  1096.     return TRUE;
  1097. } // end of wxRadioBox::Show
  1098.  
  1099. // Show a specific button
  1100. void wxRadioBox::Show(
  1101.   int                               nItem
  1102. , bool                              bShow
  1103. )
  1104. {
  1105.     wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
  1106.                  wxT("invalid item in wxRadioBox::Show()") );
  1107.  
  1108.     ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
  1109. } // end of wxRadioBox::Show
  1110.  
  1111. void wxRadioBox::SubclassRadioButton(
  1112.   WXHWND                            hWndBtn
  1113. )
  1114. {
  1115.     HWND                            hwndBtn = (HWND)hWndBtn;
  1116.  
  1117.     fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
  1118. } // end of wxRadioBox::SubclassRadioButton
  1119.  
  1120. MRESULT wxRadioBox::WindowProc(
  1121.   WXUINT                            uMsg
  1122. , WXWPARAM                          wParam
  1123. , WXLPARAM                          lParam
  1124. )
  1125. {
  1126.     return (wxControl::OS2WindowProc( uMsg
  1127.                                      ,wParam
  1128.                                      ,lParam
  1129.                                     ));
  1130. } // end of wxRadioBox::WindowProc
  1131.  
  1132. // ---------------------------------------------------------------------------
  1133. // window proc for radio buttons
  1134. // ---------------------------------------------------------------------------
  1135.  
  1136. MRESULT wxRadioBtnWndProc(
  1137.   HWND                              hWnd
  1138. , UINT                              uMessage
  1139. , MPARAM                            wParam
  1140. , MPARAM                            lParam
  1141. )
  1142. {
  1143.     switch (uMessage)
  1144.     {
  1145.         case WM_CHAR:
  1146.             {
  1147.                 USHORT                  uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
  1148.  
  1149.                 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
  1150.                 {
  1151.                     if (uKeyFlags & KC_VIRTUALKEY)
  1152.                     {
  1153.                         wxRadioBox*             pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
  1154.                                                                                                 ,QWL_USER
  1155.                                                                                                );
  1156.                         USHORT                  uVk = SHORT2FROMMP((MPARAM)lParam);
  1157.                         bool                    bProcessed = TRUE;
  1158.                         wxDirection             eDir;
  1159.  
  1160.                         switch(uVk)
  1161.                         {
  1162.                             case VK_LEFT:
  1163.                                 eDir = wxDOWN;
  1164.                                 break;
  1165.  
  1166.                             case VK_RIGHT:
  1167.                                 eDir = wxDOWN;
  1168.                                 break;
  1169.  
  1170.                             case VK_DOWN:
  1171.                                 eDir = wxDOWN;
  1172.                                 break;
  1173.  
  1174.                             case VK_UP:
  1175.                                 eDir = wxUP;
  1176.                                 break;
  1177.  
  1178.                             default:
  1179.                                 bProcessed = FALSE;
  1180.  
  1181.                                 //
  1182.                                 // Just to suppress the compiler warning
  1183.                                 //
  1184.                                 eDir = wxALL;
  1185.                         }
  1186.  
  1187.                         if (bProcessed)
  1188.                         {
  1189.                             int             nSelOld = pRadiobox->GetSelection();
  1190.                             int             nSelNew = pRadiobox->GetNextItem( nSelOld
  1191.                                                                              ,eDir
  1192.                                                                              ,pRadiobox->GetWindowStyleFlag()
  1193.                                                                             );
  1194.  
  1195.                             if (nSelNew != nSelOld)
  1196.                             {
  1197.                                 pRadiobox->SetSelection(nSelNew);
  1198.  
  1199.                                 //
  1200.                                 // Emulate the button click
  1201.                                 //
  1202.                                 pRadiobox->SendNotificationEvent();
  1203.                                 return 0;
  1204.                             }
  1205.                         }
  1206.                     }
  1207.                 }
  1208.             }
  1209.             break;
  1210.     }
  1211.  
  1212.     return fnWndProcRadioBtn( hWnd
  1213.                              ,(ULONG)uMessage
  1214.                              ,(MPARAM)wParam
  1215.                              ,(MPARAM)lParam
  1216.                             );
  1217. } // end of wxRadioBtnWndProc
  1218.  
  1219. MRESULT EXPENTRY wxRadioBoxWndProc(
  1220.   HWND                              hWnd
  1221. , UINT                              uMessage
  1222. , MPARAM                            wParam
  1223. , MPARAM                            lParam
  1224. )
  1225. {
  1226.     return (fnWndProcRadioBox( hWnd
  1227.                               ,(ULONG)uMessage
  1228.                               ,(MPARAM)wParam
  1229.                               ,(MPARAM)lParam
  1230.                              )
  1231.            );
  1232. } // end of wxRadioBoxWndProc
  1233.  
  1234.