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