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/object.h"
22 #include "wx/colour.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/checklst.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 // get item (converted to right type)
42 #define GetItem(n) ((wxCheckListBoxItem *)(GetItem(n)))
44 // ============================================================================
46 // ============================================================================
48 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
)
50 // ----------------------------------------------------------------------------
51 // declaration and implementation of wxCheckListBoxItem class
52 // ----------------------------------------------------------------------------
54 class wxCheckListBoxItem
: public wxOwnerDrawn
56 friend class wxCheckListBox
;
61 wxCheckListBoxItem( wxCheckListBox
* pParent
,
68 virtual bool OnDrawItem( wxDC
& rDc
,
77 bool IsChecked(void) const { return m_bChecked
; }
78 void Check(bool bCheck
);
79 void Toggle(void) { Check(!IsChecked()); }
83 wxCheckListBox
* m_pParent
;
85 }; // end of CLASS wxCheckListBoxItem
89 wxCheckListBoxItem::wxCheckListBoxItem ( wxCheckListBox
* pParent
,
91 :wxOwnerDrawn( wxEmptyString
, true /* checkable */ )
98 // We don't initialize m_nCheckHeight/Width vars because it's
99 // done in OnMeasure while they are used only in OnDraw and we
100 // know that there will always be OnMeasure before OnDraw
102 SetMarginWidth(GetDefaultMarginWidth());
103 } // end of wxCheckListBoxItem::wxCheckListBoxItem
107 bool wxCheckListBoxItem::OnDrawItem ( wxDC
& rDc
,
112 wxRect vRect
= rRect
;
114 ::WinQueryWindowRect( m_pParent
->GetHWND(), &rDc
.m_vRclPaint
);
116 eStat
= (wxOwnerDrawn::wxODStatus
)(eStat
| wxOwnerDrawn::wxODChecked
);
119 // Unfortunately PM doesn't quite get the text position exact. We need to alter
120 // it down and to the right, just a little bit. The coords in rRect are OS/2
121 // coords not wxWidgets coords.
125 if (wxOwnerDrawn::OnDrawItem( rDc
, vRect
, eAct
, eStat
))
127 size_t nCheckWidth
= GetDefaultMarginWidth();
128 size_t nCheckHeight
= m_pParent
->GetItemHeight();
130 int nX
= rRect
.GetX();
131 int nY
= rRect
.GetY();
133 wxColour
vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
));
137 m_pParent
->GetSize( NULL
, &nParentHeight
);
139 nY
= nParentHeight
- nY
- nCheckHeight
;
140 vPenBack
= wxPen(vColour
, 1, wxSOLID
);
143 // Erase the 1-pixel border
145 rDc
.SetPen(vPenBack
);
146 rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight
);
149 // Now we draw the smaller rectangle
156 // Draw hollow gray rectangle
158 rDc
.SetPen(*wxGREY_PEN
);
159 rDc
.DrawRectangle( nX
, nY
, nCheckWidth
, nCheckHeight
);
165 // Draw the check by loading the sys standard bitmap and drawing it
167 HBITMAP hChkBmp
= ::WinGetSysBitmap( HWND_DESKTOP
, SBMP_MENUCHECK
);
168 POINTL vPoint
= {nX
, nOldY
+ 3};
170 ::WinDrawBitmap( rDc
.GetHPS(),
182 } // end of wxCheckListBoxItem::OnDrawItem
185 // Change the state of the item and redraw it
187 void wxCheckListBoxItem::Check ( bool bCheck
)
192 // Index may be chanegd because new items were added/deleted
194 if (m_pParent
->GetItemIndex(this) != (int)m_nIndex
)
199 int nIndex
= m_pParent
->GetItemIndex(this);
201 wxASSERT_MSG(nIndex
!= wxNOT_FOUND
, wxT("what does this item do here?"));
203 m_nIndex
= (size_t)nIndex
;
207 wxCommandEvent
vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
,m_pParent
->GetId());
209 vEvent
.SetInt(m_nIndex
);
210 vEvent
.SetEventObject(m_pParent
);
211 m_pParent
->ProcessCommand(vEvent
);
212 } // end of wxCheckListBoxItem::Check
215 // ----------------------------------------------------------------------------
216 // implementation of wxCheckListBox class
217 // ----------------------------------------------------------------------------
219 // define event table
220 // ------------------
221 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
222 EVT_CHAR(wxCheckListBox::OnChar
)
223 EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
)
234 // Default ctor: use Create() to really create the control
236 wxCheckListBox::wxCheckListBox()
237 :wxCheckListBoxBase()
239 } // end of wxCheckListBox::wxCheckListBox
242 // Ctor which creates the associated control
244 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
,
249 const wxString asChoices
[],
251 const wxValidator
& rVal
,
252 const wxString
& rsName
)
253 :wxCheckListBoxBase()
255 Create( pParent
, vId
, rPos
, rSize
, nStrings
, asChoices
, lStyle
| wxLB_OWNERDRAW
, rVal
, rsName
);
256 } // end of wxCheckListBox::wxCheckListBox
258 wxCheckListBox::wxCheckListBox ( wxWindow
* pParent
,
262 const wxArrayString
& asChoices
,
264 const wxValidator
& rVal
,
265 const wxString
& rsName
)
266 :wxCheckListBoxBase()
268 wxCArrayString
chs(asChoices
);
269 Create( pParent
, vId
, rPos
, rSize
, chs
.GetCount(), chs
.GetStrings(),
270 lStyle
| wxLB_OWNERDRAW
, rVal
, rsName
);
271 } // end of wxCheckListBox::wxCheckListBox
273 void wxCheckListBox::Delete( int n
)
275 wxCHECK_RET( n
>= 0 && n
< m_nNumItems
,
276 wxT("invalid index in wxCheckListBox::Delete") );
277 wxListBox::Delete(n
);
283 m_aItems
.RemoveAt(n
);
284 } // end of wxCheckListBox::Delete
286 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
288 // pos is validated in wxListBox
289 wxListBox::DoInsertItems( items
, pos
);
290 int n
= items
.GetCount();
291 for (int i
= 0; i
< n
; i
++)
293 wxOwnerDrawn
* pNewItem
= CreateItem((size_t)(pos
+ i
));
295 pNewItem
->SetName(items
[i
]);
296 m_aItems
.Insert(pNewItem
, (size_t)(pos
+ i
));
297 ::WinSendMsg( (HWND
)GetHWND(),
303 } // end of wxCheckListBox::InsertItems
305 bool wxCheckListBox::SetFont ( const wxFont
& rFont
)
307 for (size_t i
= 0; i
< m_aItems
.GetCount(); i
++)
308 m_aItems
[i
]->SetFont(rFont
);
309 wxListBox::SetFont(rFont
);
311 } // end of wxCheckListBox::SetFont
316 // Create/retrieve item
317 // --------------------
321 // Create a check list box item
323 wxOwnerDrawn
* wxCheckListBox::CreateItem ( size_t nIndex
)
325 wxCheckListBoxItem
* pItem
= new wxCheckListBoxItem( this, nIndex
);
327 } // end of wxCheckListBox::CreateItem
335 long wxCheckListBox::OS2OnMeasure ( WXMEASUREITEMSTRUCT
* pItem
)
338 pItem
= (WXMEASUREITEMSTRUCT
*)new OWNERITEM
;
339 if (wxListBox::OS2OnMeasure(pItem
))
341 POWNERITEM pStruct
= (POWNERITEM
)pItem
;
346 m_nItemHeight
= pStruct
->rclItem
.yTop
- pStruct
->rclItem
.yBottom
;
349 // Add place for the check mark
351 pStruct
->rclItem
.xRight
+= wxOwnerDrawn::GetDefaultMarginWidth();
352 return long(MRFROM2SHORT((USHORT
)m_nItemHeight
, (USHORT
)(pStruct
->rclItem
.xRight
- pStruct
->rclItem
.xLeft
)));
355 } // end of wxCheckListBox::CreateItem
363 bool wxCheckListBox::IsChecked ( size_t uiIndex
) const
365 return GetItem(uiIndex
)->IsChecked();
366 } // end of wxCheckListBox::IsChecked
368 void wxCheckListBox::Check ( size_t uiIndex
, bool bCheck
)
370 GetItem(uiIndex
)->Check(bCheck
);
371 } // end of wxCheckListBox::Check
379 void wxCheckListBox::OnChar ( wxKeyEvent
& rEvent
)
381 if (rEvent
.GetKeyCode() == WXK_SPACE
)
382 GetItem(GetSelection())->Toggle();
385 } // end of wxCheckListBox::OnChar
387 void wxCheckListBox::OnLeftClick ( wxMouseEvent
& rEvent
)
390 // Clicking on the item selects it, clicking on the checkmark toggles
392 if (rEvent
.GetX() <= wxOwnerDrawn::GetDefaultMarginWidth())
398 GetSize( NULL
, &nParentHeight
);
399 vDc
.SetFont(GetFont());
400 vHeight
= (wxCoord
)(vDc
.GetCharHeight() * 2.5);
403 // This, of course, will not work if the LB is scrolled
405 int nY
= rEvent
.GetY();
407 nY
= nParentHeight
- (nY
+ vHeight
);
409 size_t nItem
= (size_t)(nY
/ vHeight
);
411 if (nItem
< (size_t)m_nNumItems
)
412 GetItem(nItem
)->Toggle();
414 // else: it's not an error, just click outside of client zone
420 // Implement default behaviour: clicking on the item selects it
424 } // end of wxCheckListBox::OnLeftClick
426 #endif // wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN