]> git.saurik.com Git - wxWidgets.git/blob - src/os2/checklst.cpp
Clear grid selection more consistently prior clear operations; improved Clear() tests...
[wxWidgets.git] / src / os2 / checklst.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/checklst.cpp
3 // Purpose: implementation of wxCheckListBox class
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #if wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN
20
21 #include "wx/checklst.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/object.h"
25 #include "wx/log.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"
33 #include "wx/font.h"
34 #endif
35
36 #include "wx/os2/dc.h"
37 #include "wx/ownerdrw.h"
38
39 #define INCL_PM
40 #include <os2.h>
41
42 // ----------------------------------------------------------------------------
43 // private functions
44 // ----------------------------------------------------------------------------
45
46 // get item (converted to right type)
47 #define GetItem(n) ((wxCheckListBoxItem *)(GetItem(n)))
48
49 // ============================================================================
50 // implementation
51 // ============================================================================
52
53 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
54
55 // ----------------------------------------------------------------------------
56 // declaration and implementation of wxCheckListBoxItem class
57 // ----------------------------------------------------------------------------
58
59 class wxCheckListBoxItem : public wxOwnerDrawn
60 {
61 friend class wxCheckListBox;
62 public:
63 //
64 // ctor
65 //
66 wxCheckListBoxItem(wxCheckListBox* pParent, size_t nIndex);
67
68 //
69 // Drawing functions
70 //
71 virtual bool OnDrawItem( wxDC& rDc,
72 const wxRect& rRect,
73 wxODAction eAct,
74 wxODStatus eStat
75 );
76
77 //
78 // Simple accessors
79 //
80 bool IsChecked(void) const { return m_bChecked; }
81 void Check(bool bCheck);
82 void Toggle(void) { Check(!IsChecked()); }
83
84 private:
85 bool m_bChecked;
86 wxCheckListBox* m_pParent;
87 size_t m_nIndex;
88 }; // end of CLASS wxCheckListBoxItem
89
90
91
92 wxCheckListBoxItem::wxCheckListBoxItem(wxCheckListBox* pParent, size_t nIndex)
93 :wxOwnerDrawn( wxEmptyString, true /* checkable */ )
94 {
95 m_bChecked = false;
96 m_pParent = pParent;
97 m_nIndex = nIndex;
98
99 //
100 // We don't initialize m_nCheckHeight/Width vars because it's
101 // done in OnMeasure while they are used only in OnDraw and we
102 // know that there will always be OnMeasure before OnDraw
103 //
104 SetMarginWidth(GetDefaultMarginWidth());
105 } // end of wxCheckListBoxItem::wxCheckListBoxItem
106
107
108
109 bool wxCheckListBoxItem::OnDrawItem ( wxDC& rDc,
110 const wxRect& rRect,
111 wxODAction eAct,
112 wxODStatus eStat )
113 {
114 wxRect vRect = rRect;
115
116
117 wxPMDCImpl *impl = (wxPMDCImpl*) rDc.GetImpl();
118 ::WinQueryWindowRect( m_pParent->GetHWND(), &impl->m_vRclPaint );
119 if (IsChecked())
120 eStat = (wxOwnerDrawn::wxODStatus)(eStat | wxOwnerDrawn::wxODChecked);
121
122 //
123 // Unfortunately PM doesn't quite get the text position exact. We need to alter
124 // it down and to the right, just a little bit. The coords in rRect are OS/2
125 // coords not wxWidgets coords.
126 //
127 vRect.x += 5;
128 vRect.y -= 3;
129 if (wxOwnerDrawn::OnDrawItem( rDc, vRect, eAct, eStat))
130 {
131 size_t nCheckWidth = GetDefaultMarginWidth();
132 size_t nCheckHeight = m_pParent->GetItemHeight();
133 int nParentHeight;
134 int nX = rRect.GetX();
135 int nY = rRect.GetY();
136 int nOldY = nY;
137 wxColour vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
138 wxPen vPenBack;
139 wxPen vPenPrev;
140
141 m_pParent->GetSize( NULL, &nParentHeight);
142
143 nY = nParentHeight - nY - nCheckHeight;
144 vPenBack = wxPen(vColour, 1, wxSOLID);
145
146 //
147 // Erase the 1-pixel border
148 //
149 rDc.SetPen(vPenBack);
150 rDc.DrawRectangle( nX, nY, nCheckWidth, nCheckHeight );
151
152 //
153 // Now we draw the smaller rectangle
154 //
155 nY++;
156 nCheckWidth -= 2;
157 nCheckHeight -= 2;
158
159 //
160 // Draw hollow gray rectangle
161 //
162 rDc.SetPen(*wxGREY_PEN);
163 rDc.DrawRectangle( nX, nY, nCheckWidth, nCheckHeight );
164
165 nX++;
166 if (IsChecked())
167 {
168 //
169 // Draw the check by loading the sys standard bitmap and drawing it
170 //
171 HBITMAP hChkBmp = ::WinGetSysBitmap( HWND_DESKTOP, SBMP_MENUCHECK );
172 POINTL vPoint = {nX, nOldY + 3};
173 wxPMDCImpl *impl = (wxPMDCImpl*) rDc.GetImpl();
174 ::WinDrawBitmap( impl->GetHPS(),
175 hChkBmp,
176 NULL,
177 &vPoint,
178 NULL,
179 NULL,
180 DBM_NORMAL
181 );
182 }
183 return true;
184 }
185 return false;
186 } // end of wxCheckListBoxItem::OnDrawItem
187
188 //
189 // Change the state of the item and redraw it
190 //
191 void wxCheckListBoxItem::Check( bool bCheck )
192 {
193 m_bChecked = bCheck;
194
195 //
196 // Index may be chanegd because new items were added/deleted
197 //
198 if (m_pParent->GetItemIndex(this) != (int)m_nIndex)
199 {
200 //
201 // Update it
202 //
203 int nIndex = m_pParent->GetItemIndex(this);
204
205 wxASSERT_MSG(nIndex != wxNOT_FOUND, wxT("what does this item do here?"));
206
207 m_nIndex = (size_t)nIndex;
208 }
209
210
211 wxCommandEvent vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED,m_pParent->GetId());
212
213 vEvent.SetInt(m_nIndex);
214 vEvent.SetEventObject(m_pParent);
215 m_pParent->ProcessCommand(vEvent);
216 } // end of wxCheckListBoxItem::Check
217
218
219 // ----------------------------------------------------------------------------
220 // implementation of wxCheckListBox class
221 // ----------------------------------------------------------------------------
222
223 // define event table
224 // ------------------
225 BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
226 EVT_CHAR(wxCheckListBox::OnChar)
227 EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick)
228 END_EVENT_TABLE()
229
230
231
232 //
233 // Control creation
234 // ----------------
235 //
236
237 //
238 // Default ctor: use Create() to really create the control
239 //
240 wxCheckListBox::wxCheckListBox()
241 :wxCheckListBoxBase()
242 {
243 } // end of wxCheckListBox::wxCheckListBox
244
245 //
246 // Ctor which creates the associated control
247 //
248 wxCheckListBox::wxCheckListBox ( wxWindow* pParent,
249 wxWindowID vId,
250 const wxPoint& rPos,
251 const wxSize& rSize,
252 int nStrings,
253 const wxString asChoices[],
254 long lStyle,
255 const wxValidator& rVal,
256 const wxString& rsName)
257 :wxCheckListBoxBase()
258 {
259 Create( pParent, vId, rPos, rSize, nStrings, asChoices, lStyle | wxLB_OWNERDRAW, rVal, rsName );
260 } // end of wxCheckListBox::wxCheckListBox
261
262 wxCheckListBox::wxCheckListBox ( wxWindow* pParent,
263 wxWindowID vId,
264 const wxPoint& rPos,
265 const wxSize& rSize,
266 const wxArrayString& asChoices,
267 long lStyle,
268 const wxValidator& rVal,
269 const wxString& rsName )
270 :wxCheckListBoxBase()
271 {
272 wxCArrayString chs(asChoices);
273 Create( pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
274 lStyle | wxLB_OWNERDRAW, rVal, rsName );
275 } // end of wxCheckListBox::wxCheckListBox
276
277 void wxCheckListBox::Delete(unsigned int n)
278 {
279 wxCHECK_RET( IsValid(n),
280 wxT("invalid index in wxCheckListBox::Delete") );
281 wxListBox::Delete(n);
282
283 //
284 // Free memory
285 //
286 delete m_aItems[n];
287 m_aItems.RemoveAt(n);
288 } // end of wxCheckListBox::Delete
289
290 bool wxCheckListBox::SetFont ( const wxFont& rFont )
291 {
292 for (unsigned int i = 0; i < m_aItems.GetCount(); i++)
293 m_aItems[i]->SetFont(rFont);
294 wxListBox::SetFont(rFont);
295 return true;
296 } // end of wxCheckListBox::SetFont
297
298
299
300 //
301 // Create/retrieve item
302 // --------------------
303 //
304
305 //
306 // Create a check list box item
307 //
308 wxOwnerDrawn* wxCheckListBox::CreateItem(size_t nIndex)
309 {
310 wxCheckListBoxItem* pItem = new wxCheckListBoxItem( this, nIndex );
311 return pItem;
312 } // end of wxCheckListBox::CreateItem
313
314
315
316 //
317 // Return item size
318 // ----------------
319 //
320 long wxCheckListBox::OS2OnMeasure ( WXMEASUREITEMSTRUCT* pItem )
321 {
322 if (!pItem)
323 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
324 if (wxListBox::OS2OnMeasure(pItem))
325 {
326 POWNERITEM pStruct = (POWNERITEM)pItem;
327
328 //
329 // Save item height
330 //
331 m_nItemHeight = pStruct->rclItem.yTop - pStruct->rclItem.yBottom;
332
333 //
334 // Add place for the check mark
335 //
336 pStruct->rclItem.xRight += wxOwnerDrawn::GetDefaultMarginWidth();
337 return long(MRFROM2SHORT((USHORT)m_nItemHeight, (USHORT)(pStruct->rclItem.xRight - pStruct->rclItem.xLeft)));
338 }
339 return 0L;
340 } // end of wxCheckListBox::CreateItem
341
342
343
344 //
345 // Check items
346 // -----------
347 //
348 bool wxCheckListBox::IsChecked(unsigned int uiIndex) const
349 {
350 return GetItem(uiIndex)->IsChecked();
351 } // end of wxCheckListBox::IsChecked
352
353 void wxCheckListBox::Check(unsigned int uiIndex, bool bCheck)
354 {
355 GetItem(uiIndex)->Check(bCheck);
356 } // end of wxCheckListBox::Check
357
358
359
360 //
361 // Process events
362 // --------------
363 //
364 void wxCheckListBox::OnChar ( wxKeyEvent& rEvent )
365 {
366 if (rEvent.GetKeyCode() == WXK_SPACE)
367 GetItem(GetSelection())->Toggle();
368 else
369 rEvent.Skip();
370 } // end of wxCheckListBox::OnChar
371
372 void wxCheckListBox::OnLeftClick ( wxMouseEvent& rEvent )
373 {
374 //
375 // Clicking on the item selects it, clicking on the checkmark toggles
376 //
377 if (rEvent.GetX() <= wxOwnerDrawn::GetDefaultMarginWidth())
378 {
379 int nParentHeight;
380 wxScreenDC vDc;
381 wxCoord vHeight;
382
383 GetSize( NULL, &nParentHeight );
384 vDc.SetFont(GetFont());
385 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
386
387 //
388 // This, of course, will not work if the LB is scrolled
389 //
390 int nY = rEvent.GetY();
391
392 nY = nParentHeight - (nY + vHeight);
393
394 size_t nItem = (size_t)(nY / vHeight);
395
396 if (nItem < m_nNumItems)
397 GetItem(nItem)->Toggle();
398 //
399 // else: it's not an error, just click outside of client zone
400 //
401 }
402 else
403 {
404 //
405 // Implement default behaviour: clicking on the item selects it
406 //
407 rEvent.Skip();
408 }
409 } // end of wxCheckListBox::OnLeftClick
410
411 #endif // wxUSE_CHECKLISTBOX && wxUSE_OWNER_DRAWN