1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/checklst.cpp 
   3 // Purpose:     implementation of wxCheckListBox class 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  13 // headers & declarations 
  14 // ============================================================================ 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  19 #if wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN 
  21 #include "wx/checklst.h" 
  24     #include "wx/object.h" 
  26     #include "wx/window.h" 
  27     #include "wx/dcmemory.h" 
  28     #include "wx/dcscreen.h" 
  29     #include "wx/settings.h" 
  30     #include "wx/listbox.h" 
  31     #include "wx/bitmap.h" 
  32     #include "wx/colour.h" 
  36 #include "wx/os2/dc.h" 
  37 #include "wx/ownerdrw.h" 
  42 // ---------------------------------------------------------------------------- 
  43 // constants for base class 
  44 // ---------------------------------------------------------------------------- 
  46 static const int CHECK_MARK_WIDTH 
= 15; 
  48 // ---------------------------------------------------------------------------- 
  50 // ---------------------------------------------------------------------------- 
  52 // get item (converted to right type) 
  53 #define GetItem(n)    ((wxCheckListBoxItem *)(GetItem(n))) 
  55 // ============================================================================ 
  57 // ============================================================================ 
  59 // ---------------------------------------------------------------------------- 
  60 // declaration and implementation of wxCheckListBoxItem class 
  61 // ---------------------------------------------------------------------------- 
  63 class wxCheckListBoxItem 
: public wxOwnerDrawn
 
  65     friend class wxCheckListBox
; 
  70     wxCheckListBoxItem(wxCheckListBox
* pParent
, size_t nIndex
); 
  75     virtual bool OnDrawItem( wxDC
&         rDc
, 
  84     bool IsChecked(void) const  { return m_bChecked
; } 
  85     void Check(bool bCheck
); 
  86     void Toggle(void) { Check(!IsChecked()); } 
  88     virtual wxString 
GetName() const { return m_pParent
->GetString(m_nIndex
); } 
  92     wxCheckListBox
* m_pParent
; 
  94 }; // end of CLASS wxCheckListBoxItem 
  98 wxCheckListBoxItem::wxCheckListBoxItem(wxCheckListBox
* pParent
, size_t nIndex
) 
  99                    :wxOwnerDrawn( wxEmptyString
, true /* checkable */ ) 
 106     // We don't initialize m_nCheckHeight/Width vars because it's 
 107     // done in OnMeasure while they are used only in OnDraw and we 
 108     // know that there will always be OnMeasure before OnDraw 
 110     SetMarginWidth(CHECK_MARK_WIDTH
); 
 111 } // end of wxCheckListBoxItem::wxCheckListBoxItem 
 115 bool wxCheckListBoxItem::OnDrawItem ( wxDC
& rDc
, 
 120     wxRect vRect 
= rRect
; 
 123     wxPMDCImpl 
*impl 
= (wxPMDCImpl
*) rDc
.GetImpl(); 
 124     ::WinQueryWindowRect( m_pParent
->GetHWND(), &impl
->m_vRclPaint 
); 
 126         eStat 
= (wxOwnerDrawn::wxODStatus
)(eStat 
| wxOwnerDrawn::wxODChecked
); 
 129     // Unfortunately PM doesn't quite get the text position exact.  We need to alter 
 130     // it down and to the right, just a little bit.  The coords in rRect are OS/2 
 131     // coords not wxWidgets coords. 
 135     if (wxOwnerDrawn::OnDrawItem( rDc
, vRect
, eAct
, eStat
)) 
 137         size_t    nCheckWidth  
= CHECK_MARK_WIDTH
; 
 138         size_t    nCheckHeight 
= m_pParent
->GetItemHeight(); 
 140         int       nX 
= rRect
.GetX(); 
 141         int       nY 
= rRect
.GetY(); 
 143         wxColour  
vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 147         m_pParent
->GetSize( NULL
, &nParentHeight
); 
 149         nY 
= nParentHeight 
- nY 
- nCheckHeight
; 
 150         vPenBack 
= wxPen(vColour
, 1, wxSOLID
); 
 153         // Erase the 1-pixel border 
 155         rDc
.SetPen(vPenBack
); 
 156         rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight 
); 
 159         // Now we draw the smaller rectangle 
 166         // Draw hollow gray rectangle 
 168         rDc
.SetPen(*wxGREY_PEN
); 
 169         rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight 
); 
 175             // Draw the check by loading the sys standard bitmap and drawing it 
 177             HBITMAP hChkBmp 
= ::WinGetSysBitmap( HWND_DESKTOP
, SBMP_MENUCHECK 
); 
 178             POINTL  vPoint 
= {nX
, nOldY 
+ 3}; 
 179             wxPMDCImpl 
*impl 
= (wxPMDCImpl
*) rDc
.GetImpl(); 
 180             ::WinDrawBitmap( impl
->GetHPS(), 
 192 } // end of wxCheckListBoxItem::OnDrawItem 
 195 // Change the state of the item and redraw it 
 197 void wxCheckListBoxItem::Check( bool bCheck 
) 
 202     // Index may be chanegd because new items were added/deleted 
 204     if (m_pParent
->GetItemIndex(this) != (int)m_nIndex
) 
 209         int nIndex 
= m_pParent
->GetItemIndex(this); 
 211         wxASSERT_MSG(nIndex 
!= wxNOT_FOUND
, wxT("what does this item do here?")); 
 213         m_nIndex 
= (size_t)nIndex
; 
 217     wxCommandEvent 
vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
,m_pParent
->GetId()); 
 219     vEvent
.SetInt(m_nIndex
); 
 220     vEvent
.SetEventObject(m_pParent
); 
 221     m_pParent
->ProcessCommand(vEvent
); 
 222 } // end of wxCheckListBoxItem::Check 
 225 // ---------------------------------------------------------------------------- 
 226 // implementation of wxCheckListBox class 
 227 // ---------------------------------------------------------------------------- 
 229 // define event table 
 230 // ------------------ 
 231 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
) 
 232     EVT_CHAR(wxCheckListBox::OnChar
) 
 233     EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
) 
 244 // Default ctor: use Create() to really create the control 
 246 wxCheckListBox::wxCheckListBox() 
 247                :wxCheckListBoxBase() 
 249 } // end of wxCheckListBox::wxCheckListBox 
 252 // Ctor which creates the associated control 
 254 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
, 
 259                                  const wxString asChoices
[], 
 261                                  const wxValidator
& rVal
, 
 262                                  const wxString
& rsName
) 
 263                :wxCheckListBoxBase() 
 265     Create( pParent
, vId
, rPos
, rSize
, nStrings
, asChoices
, lStyle 
| wxLB_OWNERDRAW
, rVal
, rsName 
); 
 266 } // end of wxCheckListBox::wxCheckListBox 
 268 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
, 
 272                                  const wxArrayString
& asChoices
, 
 274                                  const wxValidator
& rVal
, 
 275                                  const wxString
& rsName 
) 
 276                :wxCheckListBoxBase() 
 278     wxCArrayString 
chs(asChoices
); 
 279     Create( pParent
, vId
, rPos
, rSize
, chs
.GetCount(), chs
.GetStrings(), 
 280             lStyle 
| wxLB_OWNERDRAW
, rVal
, rsName 
); 
 281 } // end of wxCheckListBox::wxCheckListBox 
 283 void wxCheckListBox::Delete(unsigned int n
) 
 285     wxCHECK_RET( IsValid(n
), 
 286                  wxT("invalid index in wxCheckListBox::Delete") ); 
 287     wxListBox::Delete(n
); 
 293     m_aItems
.RemoveAt(n
); 
 294 } // end of wxCheckListBox::Delete 
 296 bool wxCheckListBox::SetFont ( const wxFont
& rFont 
) 
 298     for (unsigned int i 
= 0; i 
< m_aItems
.GetCount(); i
++) 
 299         m_aItems
[i
]->SetFont(rFont
); 
 300     wxListBox::SetFont(rFont
); 
 302 } // end of wxCheckListBox::SetFont 
 307 // Create/retrieve item 
 308 // -------------------- 
 312 // Create a check list box item 
 314 wxOwnerDrawn
* wxCheckListBox::CreateItem(size_t nIndex
) 
 316     wxCheckListBoxItem
* pItem 
= new wxCheckListBoxItem( this, nIndex 
); 
 318 } // end of wxCheckListBox::CreateItem 
 326 long wxCheckListBox::OS2OnMeasure ( WXMEASUREITEMSTRUCT
* pItem 
) 
 329         pItem 
= (WXMEASUREITEMSTRUCT
*)new OWNERITEM
; 
 330     if (wxListBox::OS2OnMeasure(pItem
)) 
 332         POWNERITEM pStruct 
= (POWNERITEM
)pItem
; 
 337         m_nItemHeight 
= pStruct
->rclItem
.yTop 
- pStruct
->rclItem
.yBottom
; 
 340         // Add place for the check mark 
 342         pStruct
->rclItem
.xRight 
+= CHECK_MARK_WIDTH
; 
 343         return long(MRFROM2SHORT((USHORT
)m_nItemHeight
, (USHORT
)(pStruct
->rclItem
.xRight 
- pStruct
->rclItem
.xLeft
))); 
 346 } // end of wxCheckListBox::CreateItem 
 354 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const 
 356     return GetItem(uiIndex
)->IsChecked(); 
 357 } // end of wxCheckListBox::IsChecked 
 359 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
) 
 361     GetItem(uiIndex
)->Check(bCheck
); 
 362 } // end of wxCheckListBox::Check 
 370 void wxCheckListBox::OnChar ( wxKeyEvent
& rEvent 
) 
 372     if (rEvent
.GetKeyCode() == WXK_SPACE
) 
 373         GetItem(GetSelection())->Toggle(); 
 376 } // end of wxCheckListBox::OnChar 
 378 void wxCheckListBox::OnLeftClick ( wxMouseEvent
& rEvent 
) 
 381     // Clicking on the item selects it, clicking on the checkmark toggles 
 383     if (rEvent
.GetX() <= CHECK_MARK_WIDTH
) 
 389         GetSize( NULL
, &nParentHeight 
); 
 390         vDc
.SetFont(GetFont()); 
 391         vHeight 
= (wxCoord
)(vDc
.GetCharHeight() * 2.5); 
 394         // This, of course, will not work if the LB is scrolled 
 396         int nY 
= rEvent
.GetY(); 
 398         nY 
= nParentHeight 
- (nY 
+ vHeight
); 
 400         size_t nItem 
= (size_t)(nY 
/ vHeight
); 
 402         if (nItem 
< m_nNumItems
) 
 403             GetItem(nItem
)->Toggle(); 
 405         // else: it's not an error, just click outside of client zone 
 411         // Implement default behaviour: clicking on the item selects it 
 415 } // end of wxCheckListBox::OnLeftClick 
 417 #endif // wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN