]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/checklst.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/checklst.cpp
3 // Purpose: implementation of wxCheckListBox class
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #if wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN
28 #include "wx/checklst.h"
31 #include "wx/msw/wrapcctl.h"
32 #include "wx/object.h"
33 #include "wx/colour.h"
35 #include "wx/bitmap.h"
36 #include "wx/window.h"
37 #include "wx/listbox.h"
38 #include "wx/dcmemory.h"
39 #include "wx/settings.h"
43 #include "wx/ownerdrw.h"
47 #include "wx/renderer.h"
48 #include "wx/msw/private.h"
49 #include "wx/msw/dc.h"
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 // get item (converted to right type)
56 #define GetItem(n) ((wxCheckListBoxItem *)(GetItem(n)))
60 // space around check mark bitmap in pixels
61 static const int CHECKMARK_EXTRA_SPACE
= 1;
63 // space between check bitmap and text label
64 static const int CHECKMARK_LABEL_SPACE
= 2;
66 } // anonymous namespace
68 // ============================================================================
70 // ============================================================================
72 // ----------------------------------------------------------------------------
73 // declaration and implementation of wxCheckListBoxItem class
74 // ----------------------------------------------------------------------------
76 class wxCheckListBoxItem
: public wxOwnerDrawn
80 wxCheckListBoxItem(wxCheckListBox
*parent
);
83 virtual bool OnDrawItem(wxDC
& dc
, const wxRect
& rc
, wxODAction act
, wxODStatus stat
);
85 // simple accessors and operations
86 wxCheckListBox
*GetParent() const
90 { return m_parent
->GetItemIndex(const_cast<wxCheckListBoxItem
*>(this)); }
92 wxString
GetName() const
93 { return m_parent
->GetString(GetIndex()); }
96 bool IsChecked() const
99 void Check(bool bCheck
)
100 { m_checked
= bCheck
; }
103 { Check(!IsChecked()); }
106 wxCheckListBox
*m_parent
;
109 wxDECLARE_NO_COPY_CLASS(wxCheckListBoxItem
);
112 wxCheckListBoxItem::wxCheckListBoxItem(wxCheckListBox
*parent
)
117 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(parent
);
118 size
.x
+= 2 * CHECKMARK_EXTRA_SPACE
+ CHECKMARK_LABEL_SPACE
;
120 SetMarginWidth(size
.GetWidth());
121 SetBackgroundColour(parent
->GetBackgroundColour());
124 bool wxCheckListBoxItem::OnDrawItem(wxDC
& dc
, const wxRect
& rc
,
125 wxODAction act
, wxODStatus stat
)
127 // first draw the label
128 if ( !wxOwnerDrawn::OnDrawItem(dc
, rc
, act
, stat
) )
131 // now draw the check mark part
132 wxMSWDCImpl
*impl
= (wxMSWDCImpl
*) dc
.GetImpl();
133 HDC hdc
= GetHdcOf(*impl
);
135 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(GetParent());
137 // first create bitmap in a memory DC
138 MemoryHDC
hdcMem(hdc
);
139 CompatibleBitmap
hBmpCheck(hdc
, size
.GetWidth(), size
.GetHeight());
141 // then draw a check mark into it
143 SelectInHDC
selBmp(hdcMem
, hBmpCheck
);
145 int flags
= wxCONTROL_FLAT
;
147 flags
|= wxCONTROL_CHECKED
;
149 wxDCTemp
dcMem(hdcMem
);
150 wxRendererNative::Get().DrawCheckBox(GetParent(), dcMem
, wxRect(size
), flags
);
151 } // select hBmpCheck out of hdcMem
153 // finally draw bitmap to screen
155 // position of check mark bitmap
156 int x
= rc
.GetX() + CHECKMARK_EXTRA_SPACE
;
157 int y
= rc
.GetY() + (rc
.GetHeight() - size
.GetHeight()) / 2;
159 UINT uState
= stat
& wxOwnerDrawn::wxODSelected
? wxDSB_SELECTED
: wxDSB_NORMAL
;
160 wxDrawStateBitmap(hdc
, hBmpCheck
, x
, y
, uState
);
165 // ----------------------------------------------------------------------------
166 // implementation of wxCheckListBox class
167 // ----------------------------------------------------------------------------
169 // define event table
170 // ------------------
171 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
172 EVT_KEY_DOWN(wxCheckListBox::OnKeyDown
)
173 EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
)
179 // def ctor: use Create() to really create the control
180 wxCheckListBox::wxCheckListBox()
184 // ctor which creates the associated control
185 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
186 const wxPoint
& pos
, const wxSize
& size
,
187 int nStrings
, const wxString choices
[],
188 long style
, const wxValidator
& val
,
189 const wxString
& name
)
191 Create(parent
, id
, pos
, size
, nStrings
, choices
, style
, val
, name
);
194 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
195 const wxPoint
& pos
, const wxSize
& size
,
196 const wxArrayString
& choices
,
197 long style
, const wxValidator
& val
,
198 const wxString
& name
)
200 Create(parent
, id
, pos
, size
, choices
, style
, val
, name
);
203 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
204 const wxPoint
& pos
, const wxSize
& size
,
205 int n
, const wxString choices
[],
207 const wxValidator
& validator
, const wxString
& name
)
209 return wxListBox::Create(parent
, id
, pos
, size
, n
, choices
,
210 style
| wxLB_OWNERDRAW
, validator
, name
);
213 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
214 const wxPoint
& pos
, const wxSize
& size
,
215 const wxArrayString
& choices
,
217 const wxValidator
& validator
, const wxString
& name
)
219 return wxListBox::Create(parent
, id
, pos
, size
, choices
,
220 style
| wxLB_OWNERDRAW
, validator
, name
);
223 // create/retrieve item
224 // --------------------
226 // create a check list box item
227 wxOwnerDrawn
*wxCheckListBox::CreateLboxItem(size_t WXUNUSED(n
))
229 wxCheckListBoxItem
*pItem
= new wxCheckListBoxItem(this);
235 bool wxCheckListBox::MSWOnMeasure(WXMEASUREITEMSTRUCT
*item
)
237 if ( wxListBox::MSWOnMeasure(item
) )
239 MEASUREITEMSTRUCT
*pStruct
= (MEASUREITEMSTRUCT
*)item
;
241 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(this);
242 size
.x
+= 2 * CHECKMARK_EXTRA_SPACE
;
243 size
.y
+= 2 * CHECKMARK_EXTRA_SPACE
;
245 // add place for the check mark
246 pStruct
->itemWidth
+= size
.GetWidth();
248 if ( pStruct
->itemHeight
< static_cast<unsigned int>(size
.GetHeight()) )
249 pStruct
->itemHeight
= size
.GetHeight();
260 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const
262 wxCHECK_MSG( IsValid(uiIndex
), false, wxT("bad wxCheckListBox index") );
264 return GetItem(uiIndex
)->IsChecked();
267 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
)
269 wxCHECK_RET( IsValid(uiIndex
), wxT("bad wxCheckListBox index") );
271 GetItem(uiIndex
)->Check(bCheck
);
272 RefreshItem(uiIndex
);
275 void wxCheckListBox::Toggle(unsigned int uiIndex
)
277 wxCHECK_RET( IsValid(uiIndex
), wxT("bad wxCheckListBox index") );
279 GetItem(uiIndex
)->Toggle();
280 RefreshItem(uiIndex
);
286 void wxCheckListBox::OnKeyDown(wxKeyEvent
& event
)
297 switch ( event
.GetKeyCode() )
308 case WXK_NUMPAD_SUBTRACT
:
319 wxArrayInt selections
;
321 if ( HasMultipleSelection() )
323 count
= GetSelections(selections
);
327 int sel
= GetSelection();
335 for ( int i
= 0; i
< count
; i
++ )
337 int nItem
= selections
[i
];
347 Check(nItem
, oper
== SET
);
351 wxFAIL_MSG( wxT("what should this key do?") );
354 // we should send an event as this has been done by the user and
355 // not by the program
359 else // nothing to do
365 void wxCheckListBox::OnLeftClick(wxMouseEvent
& event
)
367 // clicking on the item selects it, clicking on the checkmark toggles
369 int nItem
= HitTest(event
.GetX(), event
.GetY());
371 if ( nItem
!= wxNOT_FOUND
)
374 GetItemRect(nItem
, rect
);
376 // convert item rect to check mark rect
377 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(this);
378 rect
.x
+= CHECKMARK_EXTRA_SPACE
;
379 rect
.y
+= (rect
.GetHeight() - size
.GetHeight()) / 2;
382 if ( rect
.Contains(event
.GetX(), event
.GetY()) )
384 // people expect to get "kill focus" event for the currently
385 // focused control before getting events from the other controls
386 // and, equally importantly, they may prevent the focus change from
387 // taking place at all (e.g. because the old control contents is
388 // invalid and needs to be corrected) in which case we shouldn't
389 // generate this event at all
391 if ( FindFocus() == this )
396 // scroll one item down if the item is the last one
397 // and isn't visible at all
399 GetClientSize(NULL
, &h
);
400 if ( rect
.GetBottom() > h
)
406 // implement default behaviour: clicking on the item selects it
412 // implement default behaviour on click outside of client zone
417 wxSize
wxCheckListBox::DoGetBestClientSize() const
419 wxSize best
= wxListBox::DoGetBestClientSize();
421 // add room for the checkbox
422 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(const_cast<wxCheckListBox
*>(this));
423 size
.x
+= 2 * CHECKMARK_EXTRA_SPACE
;
424 size
.y
+= 2 * CHECKMARK_EXTRA_SPACE
;
426 best
.x
+= size
.GetWidth();
427 if ( best
.y
< size
.GetHeight() )
428 best
.y
= size
.GetHeight();
434 #endif // wxUSE_CHECKLISTBOX