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