]> git.saurik.com Git - wxWidgets.git/blame - src/os2/checklst.cpp
reSWIGged
[wxWidgets.git] / src / os2 / checklst.cpp
CommitLineData
0e320a79
DW
1///////////////////////////////////////////////////////////////////////////////
2// Name: checklst.cpp
3// Purpose: implementation of wxCheckListBox class
37f214d5 4// Author: David Webster
0616b838 5// Modified by:
37f214d5 6// Created: 10/13/99
0e320a79 7// RCS-ID: $Id$
37f214d5 8// Copyright: (c) David Webster
0e320a79
DW
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
37f214d5
DW
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"
1a75e76f 30#include "wx/dcscreen.h"
37f214d5
DW
31#include "wx/os2/checklst.h"
32#include "wx/log.h"
0e320a79 33
37f214d5
DW
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)))
0e320a79
DW
43
44// ============================================================================
1169a919
JS
45// implementation of wxCheckListBoxBase
46// ============================================================================
47
48wxCheckListBoxBase::wxCheckListBoxBase()
49{
50}
51
52// ============================================================================
53// implementation of wxCheckListBox
0e320a79
DW
54// ============================================================================
55
1de4baa3 56IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
0e320a79 57
37f214d5
DW
58// ----------------------------------------------------------------------------
59// declaration and implementation of wxCheckListBoxItem class
60// ----------------------------------------------------------------------------
61
62class wxCheckListBoxItem : public wxOwnerDrawn
63{
1de4baa3 64 friend class wxCheckListBox;
37f214d5 65public:
1de4baa3
DW
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()); }
37f214d5
DW
88
89private:
1de4baa3
DW
90 bool m_bChecked;
91 wxCheckListBox* m_pParent;
92 size_t m_nIndex;
93}; // end of CLASS wxCheckListBoxItem
94
95wxCheckListBoxItem::wxCheckListBoxItem (
96 wxCheckListBox* pParent
97, size_t nIndex
98)
99: wxOwnerDrawn( ""
100 ,TRUE // checkable
101 )
37f214d5 102{
1de4baa3
DW
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
115bool wxCheckListBoxItem::OnDrawItem (
116 wxDC& rDc
117, const wxRect& rRect
118, wxODAction eAct
119, wxODStatus eStat
120)
37f214d5 121{
1de4baa3
DW
122 wxRect vRect = rRect;
123
f5ea767e
DW
124 ::WinQueryWindowRect( m_pParent->GetHWND()
125 ,&rDc.m_vRclPaint
126 );
1de4baa3
DW
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 );
1de4baa3
DW
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;
37f214d5 209 }
1de4baa3
DW
210 return FALSE;
211} // end of wxCheckListBoxItem::OnDrawItem
37f214d5 212
37f214d5 213//
1de4baa3 214// Change the state of the item and redraw it
37f214d5 215//
1de4baa3
DW
216void wxCheckListBoxItem::Check (
217 bool bCheck
218)
37f214d5 219{
1de4baa3 220 m_bChecked = bCheck;
37f214d5 221
1de4baa3
DW
222 //
223 // Index may be chanegd because new items were added/deleted
224 //
225 if (m_pParent->GetItemIndex(this) != (int)m_nIndex)
37f214d5 226 {
1de4baa3
DW
227 //
228 // Update it
229 //
230 int nIndex = m_pParent->GetItemIndex(this);
37f214d5 231
1de4baa3 232 wxASSERT_MSG(nIndex != wxNOT_FOUND, wxT("what does this item do here?"));
37f214d5 233
1de4baa3 234 m_nIndex = (size_t)nIndex;
37f214d5
DW
235 }
236
1de4baa3
DW
237 HWND hWndListbox = (HWND)m_pParent->GetHWND();
238 RECTL rUpdate;
239 MRESULT mRc;
37f214d5 240
1de4baa3
DW
241 wxCommandEvent vEvent( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
242 ,m_pParent->GetId()
243 );
37f214d5 244
1de4baa3
DW
245 vEvent.SetInt(m_nIndex);
246 vEvent.SetEventObject(m_pParent);
247 m_pParent->ProcessCommand(vEvent);
248} // end of wxCheckListBoxItem::Check
37f214d5 249
0e320a79
DW
250// ----------------------------------------------------------------------------
251// implementation of wxCheckListBox class
252// ----------------------------------------------------------------------------
253
254// define event table
255// ------------------
256BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
37f214d5
DW
257 EVT_CHAR(wxCheckListBox::OnChar)
258 EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick)
0e320a79
DW
259END_EVENT_TABLE()
260
1de4baa3
DW
261//
262// Control creation
0e320a79 263// ----------------
1de4baa3 264//
0e320a79 265
1de4baa3
DW
266//
267// Default ctor: use Create() to really create the control
268//
269wxCheckListBox::wxCheckListBox()
270: wxListBox()
0e320a79 271{
1de4baa3 272} // end of wxCheckListBox::wxCheckListBox
0e320a79 273
1de4baa3
DW
274//
275// Ctor which creates the associated control
276//
277wxCheckListBox::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
1de4baa3 285, const wxValidator& rVal
1de4baa3
DW
286, const wxString& rsName
287)
0e320a79
DW
288 : wxListBox()
289{
1de4baa3
DW
290 Create( pParent
291 ,vId
292 ,rPos
293 ,rSize
294 ,nStrings
295 ,asChoices
296 ,lStyle | wxLB_OWNERDRAW
1de4baa3 297 ,rVal
1de4baa3
DW
298 ,rsName
299 );
300} // end of wxCheckListBox::wxCheckListBox
37f214d5 301
1de4baa3
DW
302void wxCheckListBox::Delete(
303 int N
304)
37f214d5 305{
49dc8caa 306 wxCHECK_RET( N >= 0 && N < m_nNumItems,
37f214d5 307 wxT("invalid index in wxListBox::Delete") );
37f214d5
DW
308 wxListBox::Delete(N);
309
1de4baa3
DW
310 //
311 // Free memory
312 //
37f214d5 313 delete m_aItems[N];
893758d5 314 m_aItems.RemoveAt(N);
1de4baa3 315} // end of wxCheckListBox::Delete
37f214d5 316
1de4baa3
DW
317void wxCheckListBox::InsertItems (
318 int nItems
319, const wxString asItems[]
320, int nPos
321)
37f214d5 322{
1de4baa3 323 int i;
37f214d5 324
1de4baa3
DW
325 wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
326 wxT("invalid index in wxCheckListBox::InsertItems") );
37f214d5 327
1de4baa3
DW
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 );
37f214d5 343 }
1de4baa3 344} // end of wxCheckListBox::InsertItems
37f214d5 345
1de4baa3
DW
346bool wxCheckListBox::SetFont (
347 const wxFont& rFont
348)
37f214d5 349{
1de4baa3
DW
350 size_t i;
351
352 for (i = 0; i < m_aItems.GetCount(); i++)
353 m_aItems[i]->SetFont(rFont);
354 wxListBox::SetFont(rFont);
37f214d5 355 return TRUE;
1de4baa3 356} // end of wxCheckListBox::SetFont
37f214d5 357
1de4baa3
DW
358//
359// Create/retrieve item
37f214d5 360// --------------------
1de4baa3 361//
37f214d5 362
1de4baa3
DW
363//
364// Create a check list box item
365//
366wxOwnerDrawn* wxCheckListBox::CreateItem (
367 size_t nIndex
368)
37f214d5 369{
1de4baa3
DW
370 wxCheckListBoxItem* pItem = new wxCheckListBoxItem( this
371 ,nIndex
372 );
373 return pItem;
374} // end of wxCheckListBox::CreateItem
0e320a79 375
1de4baa3
DW
376//
377// Return item size
37f214d5 378// ----------------
1de4baa3 379//
f5ea767e 380long wxCheckListBox::OS2OnMeasure (
1de4baa3
DW
381 WXMEASUREITEMSTRUCT* pItem
382)
37f214d5 383{
1de4baa3
DW
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();
f5ea767e 399 return long(MRFROM2SHORT((USHORT)m_nItemHeight, (USHORT)(pStruct->rclItem.xRight - pStruct->rclItem.xLeft)));
1de4baa3 400 }
f5ea767e 401 return 0L;
1de4baa3 402} // end of wxCheckListBox::CreateItem
37f214d5 403
1de4baa3
DW
404//
405// Check items
0e320a79 406// -----------
1de4baa3
DW
407//
408bool wxCheckListBox::IsChecked (
409 size_t uiIndex
410) const
37f214d5 411{
1de4baa3
DW
412 return GetItem(uiIndex)->IsChecked();
413} // end of wxCheckListBox::IsChecked
37f214d5 414
1de4baa3
DW
415void wxCheckListBox::Check (
416 size_t uiIndex
417, bool bCheck
418)
0e320a79 419{
1de4baa3
DW
420 GetItem(uiIndex)->Check(bCheck);
421} // end of wxCheckListBox::Check
0e320a79 422
1de4baa3
DW
423//
424// Process events
37f214d5 425// --------------
1de4baa3
DW
426//
427void wxCheckListBox::OnChar (
428 wxKeyEvent& rEvent
429)
0e320a79 430{
1de4baa3
DW
431 if (rEvent.KeyCode() == WXK_SPACE)
432 GetItem(GetSelection())->Toggle();
433 else
434 rEvent.Skip();
435} // end of wxCheckListBox::OnChar
436
437void wxCheckListBox::OnLeftClick (
438 wxMouseEvent& rEvent
439)
37f214d5 440{
1de4baa3
DW
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
37f214d5
DW
479
480#endif
0e320a79 481