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