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