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 int wxCheckListBox::DoInsertItems(const wxArrayStringsAdapter
& items
,
290 wxClientDataType type
)
292 // pos is validated in wxListBox
293 int result
= wxListBox::DoInsertItems( items
, pos
, clientData
, type
);
294 unsigned int n
= items
.GetCount();
295 for (unsigned int i
= 0; i
< n
; i
++)
297 wxOwnerDrawn
* pNewItem
= CreateItem((size_t)(pos
+ i
));
299 pNewItem
->SetName(items
[i
]);
300 m_aItems
.Insert(pNewItem
, (size_t)(pos
+ i
));
301 ::WinSendMsg( (HWND
)GetHWND(),
308 } // end of wxCheckListBox::DoInsertItems
310 bool wxCheckListBox::SetFont ( const wxFont
& rFont
)
312 for (unsigned int i
= 0; i
< m_aItems
.GetCount(); i
++)
313 m_aItems
[i
]->SetFont(rFont
);
314 wxListBox::SetFont(rFont
);
316 } // end of wxCheckListBox::SetFont
321 // Create/retrieve item
322 // --------------------
326 // Create a check list box item
328 wxOwnerDrawn
* wxCheckListBox::CreateItem(size_t nIndex
)
330 wxCheckListBoxItem
* pItem
= new wxCheckListBoxItem( this, nIndex
);
332 } // end of wxCheckListBox::CreateItem
340 long wxCheckListBox::OS2OnMeasure ( WXMEASUREITEMSTRUCT
* pItem
)
343 pItem
= (WXMEASUREITEMSTRUCT
*)new OWNERITEM
;
344 if (wxListBox::OS2OnMeasure(pItem
))
346 POWNERITEM pStruct
= (POWNERITEM
)pItem
;
351 m_nItemHeight
= pStruct
->rclItem
.yTop
- pStruct
->rclItem
.yBottom
;
354 // Add place for the check mark
356 pStruct
->rclItem
.xRight
+= wxOwnerDrawn::GetDefaultMarginWidth();
357 return long(MRFROM2SHORT((USHORT
)m_nItemHeight
, (USHORT
)(pStruct
->rclItem
.xRight
- pStruct
->rclItem
.xLeft
)));
360 } // end of wxCheckListBox::CreateItem
368 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const
370 return GetItem(uiIndex
)->IsChecked();
371 } // end of wxCheckListBox::IsChecked
373 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
)
375 GetItem(uiIndex
)->Check(bCheck
);
376 } // end of wxCheckListBox::Check
384 void wxCheckListBox::OnChar ( wxKeyEvent
& rEvent
)
386 if (rEvent
.GetKeyCode() == WXK_SPACE
)
387 GetItem(GetSelection())->Toggle();
390 } // end of wxCheckListBox::OnChar
392 void wxCheckListBox::OnLeftClick ( wxMouseEvent
& rEvent
)
395 // Clicking on the item selects it, clicking on the checkmark toggles
397 if (rEvent
.GetX() <= wxOwnerDrawn::GetDefaultMarginWidth())
403 GetSize( NULL
, &nParentHeight
);
404 vDc
.SetFont(GetFont());
405 vHeight
= (wxCoord
)(vDc
.GetCharHeight() * 2.5);
408 // This, of course, will not work if the LB is scrolled
410 int nY
= rEvent
.GetY();
412 nY
= nParentHeight
- (nY
+ vHeight
);
414 size_t nItem
= (size_t)(nY
/ vHeight
);
416 if (nItem
< m_nNumItems
)
417 GetItem(nItem
)->Toggle();
419 // else: it's not an error, just click outside of client zone
425 // Implement default behaviour: clicking on the item selects it
429 } // end of wxCheckListBox::OnLeftClick
431 #endif // wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN