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 / checklst.cpp < prev    next >
C/C++ Source or Header  |  2002-09-08  |  14KB  |  478 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name:        checklst.cpp
  3. // Purpose:     implementation of wxCheckListBox class
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/13/99
  7. // RCS-ID:      $Id: CHECKLST.CPP,v 1.12 2002/09/08 10:51:49 SN Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // headers & declarations
  14. // ============================================================================
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #if wxUSE_OWNER_DRAWN
  20.  
  21. #include "wx/object.h"
  22. #include "wx/colour.h"
  23. #include "wx/font.h"
  24. #include "wx/bitmap.h"
  25. #include "wx/window.h"
  26. #include "wx/listbox.h"
  27. #include "wx/ownerdrw.h"
  28. #include "wx/settings.h"
  29. #include "wx/dcmemory.h"
  30. #include "wx/dcscreen.h"
  31. #include "wx/os2/checklst.h"
  32. #include "wx/log.h"
  33.  
  34. #define INCL_PM
  35. #include <os2.h>
  36.  
  37. // ----------------------------------------------------------------------------
  38. // private functions
  39. // ----------------------------------------------------------------------------
  40.  
  41. // get item (converted to right type)
  42. #define GetItem(n)    ((wxCheckListBoxItem *)(GetItem(n)))
  43.  
  44. // ============================================================================
  45. // implementation
  46. // ============================================================================
  47.  
  48. IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
  49.  
  50. // ----------------------------------------------------------------------------
  51. // declaration and implementation of wxCheckListBoxItem class
  52. // ----------------------------------------------------------------------------
  53.  
  54. class wxCheckListBoxItem : public wxOwnerDrawn
  55. {
  56.     friend class wxCheckListBox;
  57. public:
  58.     //
  59.     // ctor
  60.     //
  61.     wxCheckListBoxItem( wxCheckListBox* pParent
  62.                        ,size_t          nIndex
  63.                       );
  64.  
  65.     //
  66.     // Drawing functions
  67.     //
  68.     virtual bool OnDrawItem( wxDC&         rDc
  69.                             ,const wxRect& rRect
  70.                             ,wxODAction    eAct
  71.                             ,wxODStatus    eStat
  72.                            );
  73.  
  74.     //
  75.     // Simple accessors
  76.     //
  77.     bool IsChecked(void) const  { return m_bChecked; }
  78.     void Check(bool bCheck);
  79.     void Toggle(void) { Check(!IsChecked()); }
  80.  
  81. private:
  82.     bool                            m_bChecked;
  83.     wxCheckListBox*                 m_pParent;
  84.     size_t                          m_nIndex;
  85. }; // end of CLASS wxCheckListBoxItem
  86.  
  87. wxCheckListBoxItem::wxCheckListBoxItem (
  88.   wxCheckListBox*                   pParent
  89. , size_t                            nIndex
  90. )
  91. : wxOwnerDrawn( ""
  92.                ,TRUE // checkable
  93.               )
  94. {
  95.     m_bChecked = FALSE;
  96.     m_pParent  = pParent;
  97.     m_nIndex   = nIndex;
  98.  
  99.     //
  100.     // We don't initialize m_nCheckHeight/Width vars because it's
  101.     // done in OnMeasure while they are used only in OnDraw and we
  102.     // know that there will always be OnMeasure before OnDraw
  103.     //
  104.     SetMarginWidth(GetDefaultMarginWidth());
  105. } // end of wxCheckListBoxItem::wxCheckListBoxItem
  106.  
  107. bool wxCheckListBoxItem::OnDrawItem (
  108.   wxDC&                             rDc
  109. , const wxRect&                     rRect
  110. , wxODAction                        eAct
  111. , wxODStatus                        eStat
  112. )
  113. {
  114.     wxRect                          vRect = rRect;
  115.  
  116.     ::WinQueryWindowRect( m_pParent->GetHWND()
  117.                          ,&rDc.m_vRclPaint
  118.                         );
  119.     if (IsChecked())
  120.         eStat = (wxOwnerDrawn::wxODStatus)(eStat | wxOwnerDrawn::wxODChecked);
  121.  
  122.     //
  123.     // Unfortunately PM doesn't quite get the text position exact.  We need to alter
  124.     // it down and to the right, just a little bit.  The coords in rRect are OS/2
  125.     // coords not wxWindows coords.
  126.     //
  127.     vRect.x += 5;
  128.     vRect.y -= 3;
  129.     if (wxOwnerDrawn::OnDrawItem( rDc
  130.                                  ,vRect
  131.                                  ,eAct
  132.                                  ,eStat))
  133.     {
  134.         size_t                      nCheckWidth  = GetDefaultMarginWidth();
  135.         size_t                      nCheckHeight = m_pParent->GetItemHeight();
  136.         int                         nParentHeight;
  137.         int                         nX = rRect.GetX();
  138.         int                         nY = rRect.GetY();
  139.         int                         nOldY = nY;
  140.         wxColour                    vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
  141.         wxPen                       vPenBack;
  142.         wxPen                       vPenGray;
  143.         wxPen                       vPenPrev;
  144.  
  145.         m_pParent->GetSize( NULL
  146.                            ,&nParentHeight
  147.                           );
  148.  
  149.         nY = nParentHeight - nY - nCheckHeight;
  150.         vPenBack = wxPen(vColour, 1, wxSOLID);
  151.         vPenGray = wxPen(wxColour(127, 127, 127), 1, wxSOLID);
  152.  
  153.         //
  154.         // Erase the 1-pixel border
  155.         //
  156.         rDc.SetPen(vPenBack);
  157.         rDc.DrawRectangle( nX
  158.                           ,nY
  159.                           ,nCheckWidth
  160.                           ,nCheckHeight
  161.                          );
  162.  
  163.         //
  164.         // Now we draw the smaller rectangle
  165.         //
  166.         nY++;
  167.         nCheckWidth  -= 2;
  168.         nCheckHeight -= 2;
  169.  
  170.         //
  171.         // Draw hollow gray rectangle
  172.         //
  173.         rDc.SetPen(vPenGray);
  174.         rDc.DrawRectangle( nX
  175.                           ,nY
  176.                           ,nCheckWidth
  177.                           ,nCheckHeight
  178.                          );
  179.  
  180.         nX++;
  181.         if (IsChecked())
  182.         {
  183.             //
  184.             // Draw the check by loading the sys standard bitmap and drawing it
  185.             //
  186.             HBITMAP                 hChkBmp = ::WinGetSysBitmap( HWND_DESKTOP
  187.                                                                 ,SBMP_MENUCHECK
  188.                                                                );
  189.             POINTL                  vPoint = {nX, nOldY + 3};
  190.  
  191.             ::WinDrawBitmap( rDc.GetHPS()
  192.                             ,hChkBmp
  193.                             ,NULL
  194.                             ,&vPoint
  195.                             ,NULL
  196.                             ,NULL
  197.                             ,DBM_NORMAL
  198.                            );
  199.         }
  200.         return TRUE;
  201.     }
  202.     return FALSE;
  203. } // end of wxCheckListBoxItem::OnDrawItem
  204.  
  205. //
  206. // Change the state of the item and redraw it
  207. //
  208. void wxCheckListBoxItem::Check (
  209.   bool                              bCheck
  210. )
  211. {
  212.     m_bChecked = bCheck;
  213.  
  214.     //
  215.     // Index may be chanegd because new items were added/deleted
  216.     //
  217.     if (m_pParent->GetItemIndex(this) != (int)m_nIndex)
  218.     {
  219.         //
  220.         // Update it
  221.         //
  222.         int                         nIndex = m_pParent->GetItemIndex(this);
  223.  
  224.         wxASSERT_MSG(nIndex != wxNOT_FOUND, wxT("what does this item do here?"));
  225.  
  226.         m_nIndex = (size_t)nIndex;
  227.     }
  228.  
  229.     HWND                            hWndListbox = (HWND)m_pParent->GetHWND();
  230.     RECTL                           rUpdate;
  231.     MRESULT                         mRc;
  232.  
  233.     wxCommandEvent                  vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
  234.                                            ,m_pParent->GetId()
  235.                                           );
  236.  
  237.     vEvent.SetInt(m_nIndex);
  238.     vEvent.SetEventObject(m_pParent);
  239.     m_pParent->ProcessCommand(vEvent);
  240. } // end of wxCheckListBoxItem::Check
  241.  
  242. // ----------------------------------------------------------------------------
  243. // implementation of wxCheckListBox class
  244. // ----------------------------------------------------------------------------
  245.  
  246. // define event table
  247. // ------------------
  248. BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
  249.   EVT_CHAR(wxCheckListBox::OnChar)
  250.   EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick)
  251. END_EVENT_TABLE()
  252.  
  253. //
  254. // Control creation
  255. // ----------------
  256. //
  257.  
  258. //
  259. // Default ctor: use Create() to really create the control
  260. //
  261. wxCheckListBox::wxCheckListBox()
  262. : wxListBox()
  263. {
  264. } // end of wxCheckListBox::wxCheckListBox
  265.  
  266. //
  267. // Ctor which creates the associated control
  268. //
  269. wxCheckListBox::wxCheckListBox (
  270.   wxWindow*                         pParent
  271. , wxWindowID                        vId
  272. , const wxPoint&                    rPos
  273. , const wxSize&                     rSize
  274. , int                               nStrings
  275. , const wxString                    asChoices[]
  276. , long                              lStyle
  277. #if wxUSE_VALIDATORS
  278. , const wxValidator&                rVal
  279. #endif
  280. , const wxString&                   rsName
  281. )
  282.               : wxListBox()
  283. {
  284.     Create( pParent
  285.            ,vId
  286.            ,rPos
  287.            ,rSize
  288.            ,nStrings
  289.            ,asChoices
  290.            ,lStyle | wxLB_OWNERDRAW
  291. #if wxUSE_VALIDATORS
  292.            ,rVal
  293. #endif
  294.            ,rsName
  295.           );
  296. } // end of wxCheckListBox::wxCheckListBox
  297.  
  298. void wxCheckListBox::Delete(
  299.   int                               N
  300. )
  301. {
  302.     wxCHECK_RET( N >= 0 && N < m_nNumItems,
  303.                  wxT("invalid index in wxListBox::Delete") );
  304.     wxListBox::Delete(N);
  305.  
  306.     //
  307.     // Free memory
  308.     //
  309.     delete m_aItems[N];
  310.     m_aItems.RemoveAt(N);
  311. } // end of wxCheckListBox::Delete
  312.  
  313. void wxCheckListBox::InsertItems (
  314.   int                               nItems
  315. , const wxString                    asItems[]
  316. , int                               nPos
  317. )
  318. {
  319.     int                             i;
  320.  
  321.     wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
  322.                  wxT("invalid index in wxCheckListBox::InsertItems") );
  323.  
  324.     wxListBox::InsertItems( nItems
  325.                            ,asItems
  326.                            ,nPos
  327.                           );
  328.     for (i = 0; i < nItems; i++)
  329.     {
  330.         wxOwnerDrawn*               pNewItem = CreateItem((size_t)(nPos + i));
  331.  
  332.         pNewItem->SetName(asItems[i]);
  333.         m_aItems.Insert(pNewItem, (size_t)(nPos + i));
  334.         ::WinSendMsg( (HWND)GetHWND()
  335.                      ,LM_SETITEMHANDLE
  336.                      ,(MPARAM)(i + nPos)
  337.                      ,MPFROMP(pNewItem)
  338.                     );
  339.     }
  340. } // end of wxCheckListBox::InsertItems
  341.  
  342. bool wxCheckListBox::SetFont (
  343.   const wxFont&                     rFont
  344. )
  345. {
  346.     size_t                          i;
  347.  
  348.     for (i = 0; i < m_aItems.GetCount(); i++)
  349.         m_aItems[i]->SetFont(rFont);
  350.     wxListBox::SetFont(rFont);
  351.     return TRUE;
  352. } // end of wxCheckListBox::SetFont
  353.  
  354. //
  355. // Create/retrieve item
  356. // --------------------
  357. //
  358.  
  359. //
  360. // Create a check list box item
  361. //
  362. wxOwnerDrawn* wxCheckListBox::CreateItem (
  363.   size_t                            nIndex
  364. )
  365. {
  366.     wxCheckListBoxItem*             pItem = new wxCheckListBoxItem( this
  367.                                                                    ,nIndex
  368.                                                                   );
  369.     return pItem;
  370. } // end of wxCheckListBox::CreateItem
  371.  
  372. //
  373. // Return item size
  374. // ----------------
  375. //
  376. long wxCheckListBox::OS2OnMeasure (
  377.   WXMEASUREITEMSTRUCT*             pItem
  378. )
  379. {
  380.     if (!pItem)
  381.         pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
  382.     if (wxListBox::OS2OnMeasure(pItem) )
  383.     {
  384.         POWNERITEM                  pStruct = (POWNERITEM)pItem;
  385.  
  386.         //
  387.         // Save item height
  388.         //
  389.         m_nItemHeight = pStruct->rclItem.yTop - pStruct->rclItem.yBottom;
  390.  
  391.         //
  392.         // Add place for the check mark
  393.         //
  394.         pStruct->rclItem.xRight += wxOwnerDrawn::GetDefaultMarginWidth();
  395.         return long(MRFROM2SHORT((USHORT)m_nItemHeight, (USHORT)(pStruct->rclItem.xRight - pStruct->rclItem.xLeft)));
  396.     }
  397.     return 0L;
  398. } // end of wxCheckListBox::CreateItem
  399.  
  400. //
  401. // Check items
  402. // -----------
  403. //
  404. bool wxCheckListBox::IsChecked (
  405.   size_t                            uiIndex
  406. ) const
  407. {
  408.     return GetItem(uiIndex)->IsChecked();
  409. } // end of wxCheckListBox::IsChecked
  410.  
  411. void wxCheckListBox::Check (
  412.   size_t                            uiIndex
  413. , bool                              bCheck
  414. )
  415. {
  416.     GetItem(uiIndex)->Check(bCheck);
  417. } // end of wxCheckListBox::Check
  418.  
  419. //
  420. // Process events
  421. // --------------
  422. //
  423. void wxCheckListBox::OnChar (
  424.   wxKeyEvent&                       rEvent
  425. )
  426. {
  427.     if (rEvent.KeyCode() == WXK_SPACE)
  428.         GetItem(GetSelection())->Toggle();
  429.     else
  430.         rEvent.Skip();
  431. } // end of wxCheckListBox::OnChar
  432.  
  433. void wxCheckListBox::OnLeftClick (
  434.   wxMouseEvent&                     rEvent
  435. )
  436. {
  437.     //
  438.     // Clicking on the item selects it, clicking on the checkmark toggles
  439.     //
  440.     if (rEvent.GetX() <= wxOwnerDrawn::GetDefaultMarginWidth())
  441.     {
  442.         int                         nParentHeight;
  443.         wxScreenDC                  vDc;
  444.         wxCoord                     vHeight;
  445.  
  446.         GetSize( NULL
  447.                 ,&nParentHeight
  448.                );
  449.         vDc.SetFont(GetFont());
  450.         vHeight = vDc.GetCharHeight() * 2.5;
  451.  
  452.         //
  453.         // This, of course, will not work if the LB is scrolled
  454.         //
  455.         int                         nY = rEvent.GetY();
  456.  
  457.         nY = nParentHeight - (nY + vHeight);
  458.  
  459.         size_t                      nItem = (size_t)(nY / vHeight);
  460.  
  461.         if (nItem < (size_t)m_nNumItems)
  462.             GetItem(nItem)->Toggle();
  463.         //
  464.         // else: it's not an error, just click outside of client zone
  465.         //
  466.     }
  467.     else
  468.     {
  469.         //
  470.         // Implement default behaviour: clicking on the item selects it
  471.         //
  472.         rEvent.Skip();
  473.     }
  474. } // end of wxCheckListBox::OnLeftClick
  475.  
  476. #endif
  477.  
  478.