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 // ---------------------------------------------------------------------------- 
  44 // ---------------------------------------------------------------------------- 
  46 // get item (converted to right type) 
  47 #define GetItem(n)    ((wxCheckListBoxItem *)(GetItem(n))) 
  49 // ============================================================================ 
  51 // ============================================================================ 
  53 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
) 
  55 // ---------------------------------------------------------------------------- 
  56 // declaration and implementation of wxCheckListBoxItem class 
  57 // ---------------------------------------------------------------------------- 
  59 class wxCheckListBoxItem 
: public wxOwnerDrawn
 
  61     friend class wxCheckListBox
; 
  66     wxCheckListBoxItem(wxCheckListBox
* pParent
, size_t nIndex
); 
  71     virtual bool OnDrawItem( wxDC
&         rDc
, 
  80     bool IsChecked(void) const  { return m_bChecked
; } 
  81     void Check(bool bCheck
); 
  82     void Toggle(void) { Check(!IsChecked()); } 
  86     wxCheckListBox
* m_pParent
; 
  88 }; // end of CLASS wxCheckListBoxItem 
  92 wxCheckListBoxItem::wxCheckListBoxItem(wxCheckListBox
* pParent
, size_t nIndex
) 
  93                    :wxOwnerDrawn( wxEmptyString
, true /* checkable */ ) 
 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 
 104     SetMarginWidth(GetDefaultMarginWidth()); 
 105 } // end of wxCheckListBoxItem::wxCheckListBoxItem 
 109 bool wxCheckListBoxItem::OnDrawItem ( wxDC
& rDc
, 
 114     wxRect vRect 
= rRect
; 
 117     wxPMDCImpl 
*impl 
= (wxPMDCImpl
*) rDc
.GetImpl(); 
 118     ::WinQueryWindowRect( m_pParent
->GetHWND(), &impl
->m_vRclPaint 
); 
 120         eStat 
= (wxOwnerDrawn::wxODStatus
)(eStat 
| wxOwnerDrawn::wxODChecked
); 
 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 wxWidgets coords. 
 129     if (wxOwnerDrawn::OnDrawItem( rDc
, vRect
, eAct
, eStat
)) 
 131         size_t    nCheckWidth  
= GetDefaultMarginWidth(); 
 132         size_t    nCheckHeight 
= m_pParent
->GetItemHeight(); 
 134         int       nX 
= rRect
.GetX(); 
 135         int       nY 
= rRect
.GetY(); 
 137         wxColour  
vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 141         m_pParent
->GetSize( NULL
, &nParentHeight
); 
 143         nY 
= nParentHeight 
- nY 
- nCheckHeight
; 
 144         vPenBack 
= wxPen(vColour
, 1, wxSOLID
); 
 147         // Erase the 1-pixel border 
 149         rDc
.SetPen(vPenBack
); 
 150         rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight 
); 
 153         // Now we draw the smaller rectangle 
 160         // Draw hollow gray rectangle 
 162         rDc
.SetPen(*wxGREY_PEN
); 
 163         rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight 
); 
 169             // Draw the check by loading the sys standard bitmap and drawing it 
 171             HBITMAP hChkBmp 
= ::WinGetSysBitmap( HWND_DESKTOP
, SBMP_MENUCHECK 
); 
 172             POINTL  vPoint 
= {nX
, nOldY 
+ 3}; 
 173             wxPMDCImpl 
*impl 
= (wxPMDCImpl
*) rDc
.GetImpl(); 
 174             ::WinDrawBitmap( impl
->GetHPS(), 
 186 } // end of wxCheckListBoxItem::OnDrawItem 
 189 // Change the state of the item and redraw it 
 191 void wxCheckListBoxItem::Check( bool bCheck 
) 
 196     // Index may be chanegd because new items were added/deleted 
 198     if (m_pParent
->GetItemIndex(this) != (int)m_nIndex
) 
 203         int nIndex 
= m_pParent
->GetItemIndex(this); 
 205         wxASSERT_MSG(nIndex 
!= wxNOT_FOUND
, wxT("what does this item do here?")); 
 207         m_nIndex 
= (size_t)nIndex
; 
 211     wxCommandEvent 
vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
,m_pParent
->GetId()); 
 213     vEvent
.SetInt(m_nIndex
); 
 214     vEvent
.SetEventObject(m_pParent
); 
 215     m_pParent
->ProcessCommand(vEvent
); 
 216 } // end of wxCheckListBoxItem::Check 
 219 // ---------------------------------------------------------------------------- 
 220 // implementation of wxCheckListBox class 
 221 // ---------------------------------------------------------------------------- 
 223 // define event table 
 224 // ------------------ 
 225 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
) 
 226     EVT_CHAR(wxCheckListBox::OnChar
) 
 227     EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
) 
 238 // Default ctor: use Create() to really create the control 
 240 wxCheckListBox::wxCheckListBox() 
 241                :wxCheckListBoxBase() 
 243 } // end of wxCheckListBox::wxCheckListBox 
 246 // Ctor which creates the associated control 
 248 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
, 
 253                                  const wxString asChoices
[], 
 255                                  const wxValidator
& rVal
, 
 256                                  const wxString
& rsName
) 
 257                :wxCheckListBoxBase() 
 259     Create( pParent
, vId
, rPos
, rSize
, nStrings
, asChoices
, lStyle 
| wxLB_OWNERDRAW
, rVal
, rsName 
); 
 260 } // end of wxCheckListBox::wxCheckListBox 
 262 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
, 
 266                                  const wxArrayString
& asChoices
, 
 268                                  const wxValidator
& rVal
, 
 269                                  const wxString
& rsName 
) 
 270                :wxCheckListBoxBase() 
 272     wxCArrayString 
chs(asChoices
); 
 273     Create( pParent
, vId
, rPos
, rSize
, chs
.GetCount(), chs
.GetStrings(), 
 274             lStyle 
| wxLB_OWNERDRAW
, rVal
, rsName 
); 
 275 } // end of wxCheckListBox::wxCheckListBox 
 277 void wxCheckListBox::Delete(unsigned int n
) 
 279     wxCHECK_RET( IsValid(n
), 
 280                  wxT("invalid index in wxCheckListBox::Delete") ); 
 281     wxListBox::Delete(n
); 
 287     m_aItems
.RemoveAt(n
); 
 288 } // end of wxCheckListBox::Delete 
 290 bool wxCheckListBox::SetFont ( const wxFont
& rFont 
) 
 292     for (unsigned int i 
= 0; i 
< m_aItems
.GetCount(); i
++) 
 293         m_aItems
[i
]->SetFont(rFont
); 
 294     wxListBox::SetFont(rFont
); 
 296 } // end of wxCheckListBox::SetFont 
 301 // Create/retrieve item 
 302 // -------------------- 
 306 // Create a check list box item 
 308 wxOwnerDrawn
* wxCheckListBox::CreateItem(size_t nIndex
) 
 310     wxCheckListBoxItem
* pItem 
= new wxCheckListBoxItem( this, nIndex 
); 
 312 } // end of wxCheckListBox::CreateItem 
 320 long wxCheckListBox::OS2OnMeasure ( WXMEASUREITEMSTRUCT
* pItem 
) 
 323         pItem 
= (WXMEASUREITEMSTRUCT
*)new OWNERITEM
; 
 324     if (wxListBox::OS2OnMeasure(pItem
)) 
 326         POWNERITEM pStruct 
= (POWNERITEM
)pItem
; 
 331         m_nItemHeight 
= pStruct
->rclItem
.yTop 
- pStruct
->rclItem
.yBottom
; 
 334         // Add place for the check mark 
 336         pStruct
->rclItem
.xRight 
+= wxOwnerDrawn::GetDefaultMarginWidth(); 
 337         return long(MRFROM2SHORT((USHORT
)m_nItemHeight
, (USHORT
)(pStruct
->rclItem
.xRight 
- pStruct
->rclItem
.xLeft
))); 
 340 } // end of wxCheckListBox::CreateItem 
 348 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const 
 350     return GetItem(uiIndex
)->IsChecked(); 
 351 } // end of wxCheckListBox::IsChecked 
 353 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
) 
 355     GetItem(uiIndex
)->Check(bCheck
); 
 356 } // end of wxCheckListBox::Check 
 364 void wxCheckListBox::OnChar ( wxKeyEvent
& rEvent 
) 
 366     if (rEvent
.GetKeyCode() == WXK_SPACE
) 
 367         GetItem(GetSelection())->Toggle(); 
 370 } // end of wxCheckListBox::OnChar 
 372 void wxCheckListBox::OnLeftClick ( wxMouseEvent
& rEvent 
) 
 375     // Clicking on the item selects it, clicking on the checkmark toggles 
 377     if (rEvent
.GetX() <= wxOwnerDrawn::GetDefaultMarginWidth()) 
 383         GetSize( NULL
, &nParentHeight 
); 
 384         vDc
.SetFont(GetFont()); 
 385         vHeight 
= (wxCoord
)(vDc
.GetCharHeight() * 2.5); 
 388         // This, of course, will not work if the LB is scrolled 
 390         int nY 
= rEvent
.GetY(); 
 392         nY 
= nParentHeight 
- (nY 
+ vHeight
); 
 394         size_t nItem 
= (size_t)(nY 
/ vHeight
); 
 396         if (nItem 
< m_nNumItems
) 
 397             GetItem(nItem
)->Toggle(); 
 399         // else: it's not an error, just click outside of client zone 
 405         // Implement default behaviour: clicking on the item selects it 
 409 } // end of wxCheckListBox::OnLeftClick 
 411 #endif // wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN