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/ownerdrw.h" 
  41 // ---------------------------------------------------------------------------- 
  43 // ---------------------------------------------------------------------------- 
  45 // get item (converted to right type) 
  46 #define GetItem(n)    ((wxCheckListBoxItem *)(GetItem(n))) 
  48 // ============================================================================ 
  50 // ============================================================================ 
  52 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
) 
  54 // ---------------------------------------------------------------------------- 
  55 // declaration and implementation of wxCheckListBoxItem class 
  56 // ---------------------------------------------------------------------------- 
  58 class wxCheckListBoxItem 
: public wxOwnerDrawn
 
  60     friend class wxCheckListBox
; 
  65     wxCheckListBoxItem(wxCheckListBox
* pParent
, size_t nIndex
); 
  70     virtual bool OnDrawItem( wxDC
&         rDc
, 
  79     bool IsChecked(void) const  { return m_bChecked
; } 
  80     void Check(bool bCheck
); 
  81     void Toggle(void) { Check(!IsChecked()); } 
  85     wxCheckListBox
* m_pParent
; 
  87 }; // end of CLASS wxCheckListBoxItem 
  91 wxCheckListBoxItem::wxCheckListBoxItem(wxCheckListBox
* pParent
, size_t nIndex
) 
  92                    :wxOwnerDrawn( wxEmptyString
, true /* checkable */ ) 
  99     // We don't initialize m_nCheckHeight/Width vars because it's 
 100     // done in OnMeasure while they are used only in OnDraw and we 
 101     // know that there will always be OnMeasure before OnDraw 
 103     SetMarginWidth(GetDefaultMarginWidth()); 
 104 } // end of wxCheckListBoxItem::wxCheckListBoxItem 
 108 bool wxCheckListBoxItem::OnDrawItem ( wxDC
& rDc
, 
 113     wxRect vRect 
= rRect
; 
 115     ::WinQueryWindowRect( m_pParent
->GetHWND(), &rDc
.m_vRclPaint 
); 
 117         eStat 
= (wxOwnerDrawn::wxODStatus
)(eStat 
| wxOwnerDrawn::wxODChecked
); 
 120     // Unfortunately PM doesn't quite get the text position exact.  We need to alter 
 121     // it down and to the right, just a little bit.  The coords in rRect are OS/2 
 122     // coords not wxWidgets coords. 
 126     if (wxOwnerDrawn::OnDrawItem( rDc
, vRect
, eAct
, eStat
)) 
 128         size_t    nCheckWidth  
= GetDefaultMarginWidth(); 
 129         size_t    nCheckHeight 
= m_pParent
->GetItemHeight(); 
 131         int       nX 
= rRect
.GetX(); 
 132         int       nY 
= rRect
.GetY(); 
 134         wxColour  
vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 138         m_pParent
->GetSize( NULL
, &nParentHeight
); 
 140         nY 
= nParentHeight 
- nY 
- nCheckHeight
; 
 141         vPenBack 
= wxPen(vColour
, 1, wxSOLID
); 
 144         // Erase the 1-pixel border 
 146         rDc
.SetPen(vPenBack
); 
 147         rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight 
); 
 150         // Now we draw the smaller rectangle 
 157         // Draw hollow gray rectangle 
 159         rDc
.SetPen(*wxGREY_PEN
); 
 160         rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight 
); 
 166             // Draw the check by loading the sys standard bitmap and drawing it 
 168             HBITMAP hChkBmp 
= ::WinGetSysBitmap( HWND_DESKTOP
, SBMP_MENUCHECK 
); 
 169             POINTL  vPoint 
= {nX
, nOldY 
+ 3}; 
 171             ::WinDrawBitmap( rDc
.GetHPS(), 
 183 } // end of wxCheckListBoxItem::OnDrawItem 
 186 // Change the state of the item and redraw it 
 188 void wxCheckListBoxItem::Check( bool bCheck 
) 
 193     // Index may be chanegd because new items were added/deleted 
 195     if (m_pParent
->GetItemIndex(this) != (int)m_nIndex
) 
 200         int nIndex 
= m_pParent
->GetItemIndex(this); 
 202         wxASSERT_MSG(nIndex 
!= wxNOT_FOUND
, wxT("what does this item do here?")); 
 204         m_nIndex 
= (size_t)nIndex
; 
 208     wxCommandEvent 
vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
,m_pParent
->GetId()); 
 210     vEvent
.SetInt(m_nIndex
); 
 211     vEvent
.SetEventObject(m_pParent
); 
 212     m_pParent
->ProcessCommand(vEvent
); 
 213 } // end of wxCheckListBoxItem::Check 
 216 // ---------------------------------------------------------------------------- 
 217 // implementation of wxCheckListBox class 
 218 // ---------------------------------------------------------------------------- 
 220 // define event table 
 221 // ------------------ 
 222 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
) 
 223     EVT_CHAR(wxCheckListBox::OnChar
) 
 224     EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
) 
 235 // Default ctor: use Create() to really create the control 
 237 wxCheckListBox::wxCheckListBox() 
 238                :wxCheckListBoxBase() 
 240 } // end of wxCheckListBox::wxCheckListBox 
 243 // Ctor which creates the associated control 
 245 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
, 
 250                                  const wxString asChoices
[], 
 252                                  const wxValidator
& rVal
, 
 253                                  const wxString
& rsName
) 
 254                :wxCheckListBoxBase() 
 256     Create( pParent
, vId
, rPos
, rSize
, nStrings
, asChoices
, lStyle 
| wxLB_OWNERDRAW
, rVal
, rsName 
); 
 257 } // end of wxCheckListBox::wxCheckListBox 
 259 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
, 
 263                                  const wxArrayString
& asChoices
, 
 265                                  const wxValidator
& rVal
, 
 266                                  const wxString
& rsName 
) 
 267                :wxCheckListBoxBase() 
 269     wxCArrayString 
chs(asChoices
); 
 270     Create( pParent
, vId
, rPos
, rSize
, chs
.GetCount(), chs
.GetStrings(), 
 271             lStyle 
| wxLB_OWNERDRAW
, rVal
, rsName 
); 
 272 } // end of wxCheckListBox::wxCheckListBox 
 274 void wxCheckListBox::Delete(unsigned int n
) 
 276     wxCHECK_RET( IsValid(n
), 
 277                  wxT("invalid index in wxCheckListBox::Delete") ); 
 278     wxListBox::Delete(n
); 
 284     m_aItems
.RemoveAt(n
); 
 285 } // end of wxCheckListBox::Delete 
 287 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, unsigned int pos
) 
 289     // pos is validated in wxListBox 
 290     wxListBox::DoInsertItems( items
, pos 
); 
 291     unsigned int n 
= items
.GetCount(); 
 292     for (unsigned int i 
= 0; i 
< n
; i
++) 
 294         wxOwnerDrawn
* pNewItem 
= CreateItem((size_t)(pos 
+ i
)); 
 296         pNewItem
->SetName(items
[i
]); 
 297         m_aItems
.Insert(pNewItem
, (size_t)(pos 
+ i
)); 
 298         ::WinSendMsg( (HWND
)GetHWND(), 
 304 } // end of wxCheckListBox::InsertItems 
 306 bool wxCheckListBox::SetFont ( const wxFont
& rFont 
) 
 308     for (unsigned int i 
= 0; i 
< m_aItems
.GetCount(); i
++) 
 309         m_aItems
[i
]->SetFont(rFont
); 
 310     wxListBox::SetFont(rFont
); 
 312 } // end of wxCheckListBox::SetFont 
 317 // Create/retrieve item 
 318 // -------------------- 
 322 // Create a check list box item 
 324 wxOwnerDrawn
* wxCheckListBox::CreateItem(size_t nIndex
) 
 326     wxCheckListBoxItem
* pItem 
= new wxCheckListBoxItem( this, nIndex 
); 
 328 } // end of wxCheckListBox::CreateItem 
 336 long wxCheckListBox::OS2OnMeasure ( WXMEASUREITEMSTRUCT
* pItem 
) 
 339         pItem 
= (WXMEASUREITEMSTRUCT
*)new OWNERITEM
; 
 340     if (wxListBox::OS2OnMeasure(pItem
)) 
 342         POWNERITEM pStruct 
= (POWNERITEM
)pItem
; 
 347         m_nItemHeight 
= pStruct
->rclItem
.yTop 
- pStruct
->rclItem
.yBottom
; 
 350         // Add place for the check mark 
 352         pStruct
->rclItem
.xRight 
+= wxOwnerDrawn::GetDefaultMarginWidth(); 
 353         return long(MRFROM2SHORT((USHORT
)m_nItemHeight
, (USHORT
)(pStruct
->rclItem
.xRight 
- pStruct
->rclItem
.xLeft
))); 
 356 } // end of wxCheckListBox::CreateItem 
 364 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const 
 366     return GetItem(uiIndex
)->IsChecked(); 
 367 } // end of wxCheckListBox::IsChecked 
 369 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
) 
 371     GetItem(uiIndex
)->Check(bCheck
); 
 372 } // end of wxCheckListBox::Check 
 380 void wxCheckListBox::OnChar ( wxKeyEvent
& rEvent 
) 
 382     if (rEvent
.GetKeyCode() == WXK_SPACE
) 
 383         GetItem(GetSelection())->Toggle(); 
 386 } // end of wxCheckListBox::OnChar 
 388 void wxCheckListBox::OnLeftClick ( wxMouseEvent
& rEvent 
) 
 391     // Clicking on the item selects it, clicking on the checkmark toggles 
 393     if (rEvent
.GetX() <= wxOwnerDrawn::GetDefaultMarginWidth()) 
 399         GetSize( NULL
, &nParentHeight 
); 
 400         vDc
.SetFont(GetFont()); 
 401         vHeight 
= (wxCoord
)(vDc
.GetCharHeight() * 2.5); 
 404         // This, of course, will not work if the LB is scrolled 
 406         int nY 
= rEvent
.GetY(); 
 408         nY 
= nParentHeight 
- (nY 
+ vHeight
); 
 410         size_t nItem 
= (size_t)(nY 
/ vHeight
); 
 412         if (nItem 
< m_nNumItems
) 
 413             GetItem(nItem
)->Toggle(); 
 415         // else: it's not an error, just click outside of client zone 
 421         // Implement default behaviour: clicking on the item selects it 
 425 } // end of wxCheckListBox::OnLeftClick 
 427 #endif // wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN