]>
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
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #if wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN
29 #include "wx/checklst.h"
32 #include "wx/msw/wrapcctl.h"
33 #include "wx/object.h"
34 #include "wx/colour.h"
36 #include "wx/bitmap.h"
37 #include "wx/window.h"
38 #include "wx/listbox.h"
39 #include "wx/dcmemory.h"
40 #include "wx/settings.h"
44 #include "wx/ownerdrw.h"
48 #include "wx/renderer.h"
49 #include "wx/msw/private.h"
50 #include "wx/msw/dc.h"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 // get item (converted to right type)
57 #define GetItem(n) ((wxCheckListBoxItem *)(GetItem(n)))
61 // space around check mark bitmap in pixels
62 static const int CHECKMARK_EXTRA_SPACE
= 1;
64 // space between check bitmap and text label
65 static const int CHECKMARK_LABEL_SPACE
= 2;
67 } // anonymous namespace
69 // ============================================================================
71 // ============================================================================
73 // ----------------------------------------------------------------------------
74 // declaration and implementation of wxCheckListBoxItem class
75 // ----------------------------------------------------------------------------
77 class wxCheckListBoxItem
: public wxOwnerDrawn
81 wxCheckListBoxItem(wxCheckListBox
*parent
);
84 virtual bool OnDrawItem(wxDC
& dc
, const wxRect
& rc
, wxODAction act
, wxODStatus stat
);
86 // simple accessors and operations
87 wxCheckListBox
*GetParent() const
91 { return m_parent
->GetItemIndex(const_cast<wxCheckListBoxItem
*>(this)); }
93 wxString
GetName() const
94 { return m_parent
->GetString(GetIndex()); }
97 bool IsChecked() const
100 void Check(bool bCheck
)
101 { m_checked
= bCheck
; }
104 { Check(!IsChecked()); }
107 wxCheckListBox
*m_parent
;
110 wxDECLARE_NO_COPY_CLASS(wxCheckListBoxItem
);
113 wxCheckListBoxItem::wxCheckListBoxItem(wxCheckListBox
*parent
)
118 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(parent
);
119 size
.x
+= 2 * CHECKMARK_EXTRA_SPACE
+ CHECKMARK_LABEL_SPACE
;
121 SetMarginWidth(size
.GetWidth());
122 SetBackgroundColour(parent
->GetBackgroundColour());
125 bool wxCheckListBoxItem::OnDrawItem(wxDC
& dc
, const wxRect
& rc
,
126 wxODAction act
, wxODStatus stat
)
128 // first draw the label
129 if ( !wxOwnerDrawn::OnDrawItem(dc
, rc
, act
, stat
) )
132 // now draw the check mark part
133 wxMSWDCImpl
*impl
= (wxMSWDCImpl
*) dc
.GetImpl();
134 HDC hdc
= GetHdcOf(*impl
);
136 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(GetParent());
138 // first create bitmap in a memory DC
139 MemoryHDC
hdcMem(hdc
);
140 CompatibleBitmap
hBmpCheck(hdc
, size
.GetWidth(), size
.GetHeight());
142 // then draw a check mark into it
144 SelectInHDC
selBmp(hdcMem
, hBmpCheck
);
146 int flags
= wxCONTROL_FLAT
;
148 flags
|= wxCONTROL_CHECKED
;
150 wxDCTemp
dcMem(hdcMem
);
151 wxRendererNative::Get().DrawCheckBox(GetParent(), dcMem
, wxRect(size
), flags
);
152 } // select hBmpCheck out of hdcMem
154 // finally draw bitmap to screen
156 // position of check mark bitmap
157 int x
= rc
.GetX() + CHECKMARK_EXTRA_SPACE
;
158 int y
= rc
.GetY() + (rc
.GetHeight() - size
.GetHeight()) / 2;
160 UINT uState
= stat
& wxOwnerDrawn::wxODSelected
? wxDSB_SELECTED
: wxDSB_NORMAL
;
161 wxDrawStateBitmap(hdc
, hBmpCheck
, x
, y
, uState
);
166 // ----------------------------------------------------------------------------
167 // implementation of wxCheckListBox class
168 // ----------------------------------------------------------------------------
170 // define event table
171 // ------------------
172 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
173 EVT_KEY_DOWN(wxCheckListBox::OnKeyDown
)
174 EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
)
180 // def ctor: use Create() to really create the control
181 wxCheckListBox::wxCheckListBox()
185 // ctor which creates the associated control
186 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
187 const wxPoint
& pos
, const wxSize
& size
,
188 int nStrings
, const wxString choices
[],
189 long style
, const wxValidator
& val
,
190 const wxString
& name
)
192 Create(parent
, id
, pos
, size
, nStrings
, choices
, style
, val
, name
);
195 wxCheckListBox::wxCheckListBox(wxWindow
*parent
, wxWindowID id
,
196 const wxPoint
& pos
, const wxSize
& size
,
197 const wxArrayString
& choices
,
198 long style
, const wxValidator
& val
,
199 const wxString
& name
)
201 Create(parent
, id
, pos
, size
, choices
, style
, val
, name
);
204 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
205 const wxPoint
& pos
, const wxSize
& size
,
206 int n
, const wxString choices
[],
208 const wxValidator
& validator
, const wxString
& name
)
210 return wxListBox::Create(parent
, id
, pos
, size
, n
, choices
,
211 style
| wxLB_OWNERDRAW
, validator
, name
);
214 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
215 const wxPoint
& pos
, const wxSize
& size
,
216 const wxArrayString
& choices
,
218 const wxValidator
& validator
, const wxString
& name
)
220 return wxListBox::Create(parent
, id
, pos
, size
, choices
,
221 style
| wxLB_OWNERDRAW
, validator
, name
);
224 // create/retrieve item
225 // --------------------
227 // create a check list box item
228 wxOwnerDrawn
*wxCheckListBox::CreateLboxItem(size_t WXUNUSED(n
))
230 wxCheckListBoxItem
*pItem
= new wxCheckListBoxItem(this);
236 bool wxCheckListBox::MSWOnMeasure(WXMEASUREITEMSTRUCT
*item
)
238 if ( wxListBox::MSWOnMeasure(item
) )
240 MEASUREITEMSTRUCT
*pStruct
= (MEASUREITEMSTRUCT
*)item
;
242 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(this);
243 size
.x
+= 2 * CHECKMARK_EXTRA_SPACE
;
244 size
.y
+= 2 * CHECKMARK_EXTRA_SPACE
;
246 // add place for the check mark
247 pStruct
->itemWidth
+= size
.GetWidth();
249 if ( pStruct
->itemHeight
< static_cast<unsigned int>(size
.GetHeight()) )
250 pStruct
->itemHeight
= size
.GetHeight();
261 bool wxCheckListBox::IsChecked(unsigned int uiIndex
) const
263 wxCHECK_MSG( IsValid(uiIndex
), false, wxT("bad wxCheckListBox index") );
265 return GetItem(uiIndex
)->IsChecked();
268 void wxCheckListBox::Check(unsigned int uiIndex
, bool bCheck
)
270 wxCHECK_RET( IsValid(uiIndex
), wxT("bad wxCheckListBox index") );
272 GetItem(uiIndex
)->Check(bCheck
);
273 RefreshItem(uiIndex
);
276 void wxCheckListBox::Toggle(unsigned int uiIndex
)
278 wxCHECK_RET( IsValid(uiIndex
), wxT("bad wxCheckListBox index") );
280 GetItem(uiIndex
)->Toggle();
281 RefreshItem(uiIndex
);
287 void wxCheckListBox::OnKeyDown(wxKeyEvent
& event
)
298 switch ( event
.GetKeyCode() )
309 case WXK_NUMPAD_SUBTRACT
:
320 wxArrayInt selections
;
322 if ( HasMultipleSelection() )
324 count
= GetSelections(selections
);
328 int sel
= GetSelection();
336 for ( int i
= 0; i
< count
; i
++ )
338 int nItem
= selections
[i
];
348 Check(nItem
, oper
== SET
);
352 wxFAIL_MSG( wxT("what should this key do?") );
355 // we should send an event as this has been done by the user and
356 // not by the program
360 else // nothing to do
366 void wxCheckListBox::OnLeftClick(wxMouseEvent
& event
)
368 // clicking on the item selects it, clicking on the checkmark toggles
370 int nItem
= HitTest(event
.GetX(), event
.GetY());
372 if ( nItem
!= wxNOT_FOUND
)
375 GetItemRect(nItem
, rect
);
377 // convert item rect to check mark rect
378 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(this);
379 rect
.x
+= CHECKMARK_EXTRA_SPACE
;
380 rect
.y
+= (rect
.GetHeight() - size
.GetHeight()) / 2;
383 if ( rect
.Contains(event
.GetX(), event
.GetY()) )
385 // people expect to get "kill focus" event for the currently
386 // focused control before getting events from the other controls
387 // and, equally importantly, they may prevent the focus change from
388 // taking place at all (e.g. because the old control contents is
389 // invalid and needs to be corrected) in which case we shouldn't
390 // generate this event at all
392 if ( FindFocus() == this )
397 // scroll one item down if the item is the last one
398 // and isn't visible at all
400 GetClientSize(NULL
, &h
);
401 if ( rect
.GetBottom() > h
)
407 // implement default behaviour: clicking on the item selects it
413 // implement default behaviour on click outside of client zone
418 wxSize
wxCheckListBox::DoGetBestClientSize() const
420 wxSize best
= wxListBox::DoGetBestClientSize();
422 // add room for the checkbox
423 wxSize size
= wxRendererNative::Get().GetCheckBoxSize(const_cast<wxCheckListBox
*>(this));
424 size
.x
+= 2 * CHECKMARK_EXTRA_SPACE
;
425 size
.y
+= 2 * CHECKMARK_EXTRA_SPACE
;
427 best
.x
+= size
.GetWidth();
428 if ( best
.y
< size
.GetHeight() )
429 best
.y
= size
.GetHeight();
435 #endif // wxUSE_CHECKLISTBOX