1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: implementation of wxCheckListBox class
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
17 #pragma implementation "checklst.h"
22 #if wxUSE_CHECKLISTBOX
24 #include "wx/checklst.h"
26 #include "wx/mac/uma.h"
27 #include "Appearance.h"
29 // ============================================================================
30 // implementation of wxCheckListBox
31 // ============================================================================
33 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
)
35 const short kwxMacListWithVerticalScrollbar
= 128 ;
36 const short kwxMacListItemHeight
= 14 ;
37 const short kwxMacListCheckboxWidth
= 14 ;
40 unsigned short instruction
;
42 } ldefRec
, *ldefPtr
, **ldefHandle
;
46 static pascal void wxMacCheckListDefinition( short message
, Boolean isSelected
, Rect
*drawRect
,
47 Cell cell
, short dataOffset
, short dataLength
,
48 ListHandle listHandle
) ;
51 static pascal void wxMacCheckListDefinition( short message
, Boolean isSelected
, Rect
*drawRect
,
52 Cell cell
, short dataOffset
, short dataLength
,
53 ListHandle listHandle
)
58 RgnHandle savedClipRegion
;
62 SetPort((**listHandle
).port
);
63 grafPtr
= (**listHandle
).port
;
64 // typecast our refCon
65 list
= (wxCheckListBox
*) GetControlReference( (ControlHandle
) GetListRefCon(listHandle
) );
67 // Calculate the cell rect.
78 const wxString text
= list
->m_stringArray
[cell
.v
] ;
79 int checked
= list
->m_checks
[cell
.v
] ;
81 // Save the current clip region, and set the clip region to the area we are about
84 savedClipRegion
= NewRgn();
85 GetClip( savedClipRegion
);
88 EraseRect( drawRect
);
90 ::TextFont( kFontIDMonaco
) ;
93 ThemeButtonDrawInfo info
;
94 info
.state
= kThemeStateActive
;
95 info
.value
= checked
? kThemeButtonOn
: kThemeButtonOff
;
96 info
.adornment
= kThemeAdornmentNone
;
97 Rect checkRect
= *drawRect
;
100 checkRect
.right
= checkRect
.left
+ 12 ;
101 checkRect
.bottom
= checkRect
.top
+ 10 ;
102 DrawThemeButton(&checkRect
,kThemeCheckBox
,
103 &info
,NULL
,NULL
, NULL
,0);
105 MoveTo(drawRect
->left
+ 4 + kwxMacListCheckboxWidth
, drawRect
->top
+ 10 );
107 DrawText(text
, 0 , text
.Length());
108 // If the cell is hilited, do the hilite now. Paint the cell contents with the
109 // appropriate QuickDraw transform mode.
112 savedPenMode
= GetPortPenMode( (CGrafPtr
) grafPtr
);
113 SetPortPenMode( (CGrafPtr
) grafPtr
, hilitetransfermode
);
114 PaintRect( drawRect
);
115 SetPortPenMode( (CGrafPtr
) grafPtr
, savedPenMode
);
118 // Restore the saved clip region.
120 SetClip( savedClipRegion
);
121 DisposeRgn( savedClipRegion
);
126 // Hilite or unhilite the cell. Paint the cell contents with the
127 // appropriate QuickDraw transform mode.
130 savedPenMode
= GetPortPenMode( (CGrafPtr
) grafPtr
);
131 SetPortPenMode( (CGrafPtr
) grafPtr
, hilitetransfermode
);
132 PaintRect( drawRect
);
133 SetPortPenMode( (CGrafPtr
) grafPtr
, savedPenMode
);
141 extern "C" void MacDrawStringCell(Rect
*cellRect
, Cell lCell
, ListHandle theList
, long refCon
) ;
143 static ListDefUPP macCheckListDefUPP
= NULL
;
145 // ----------------------------------------------------------------------------
147 // ----------------------------------------------------------------------------
149 void wxCheckListBox::Init()
153 bool wxCheckListBox::Create(wxWindow
*parent
,
158 const wxString choices
[],
160 const wxValidator
& validator
,
161 const wxString
&name
)
163 m_noItems
= 0 ; // this will be increased by our append command
169 MacPreControlCreate( parent
, id
, "" , pos
, size
,style
, validator
, name
, &bounds
, title
) ;
172 listDef
.defType
= kListDefUserProcType
;
173 if ( macCheckListDefUPP
== NULL
)
175 macCheckListDefUPP
= NewListDefUPP( wxMacCheckListDefinition
);
177 listDef
.u
.userProc
= macCheckListDefUPP
;
183 CreateListBoxControl( parent
->MacGetRootWindow(), &bounds
, false, 0, 1, false, true,
184 14, 14, false, &listDef
, &m_macControl
);
186 GetControlData( (ControlHandle
) m_macControl
, kControlNoPart
, kControlListBoxListHandleTag
,
187 sizeof(ListHandle
), (Ptr
) &m_macList
, &asize
);
189 SetControlReference( (ControlHandle
) m_macControl
, (long) this);
190 SetControlVisibility( (ControlHandle
) m_macControl
, false, false);
196 m_macControl
= ::NewControl( MAC_WXHWND(parent
->MacGetRootWindow()) , &bounds
, title
, false ,
197 kwxMacListWithVerticalScrollbar
, 0 , 0,
198 kControlListBoxProc
, (long) this ) ;
199 ::GetControlData( (ControlHandle
) m_macControl
, kControlNoPart
, kControlListBoxListHandleTag
,
200 sizeof( ListHandle
) , (char*) &m_macList
, &result
) ;
202 HLock( (Handle
) m_macList
) ;
204 ldef
= (ldefHandle
) NewHandle( sizeof(ldefRec
) ) ;
205 if ( (**(ListHandle
)m_macList
).listDefProc
!= NULL
)
207 (**ldef
).instruction
= 0x4EF9; /* JMP instruction */
208 (**ldef
).function
= (void(*)()) listDef
.u
.userProc
;
209 (**(ListHandle
)m_macList
).listDefProc
= (Handle
) ldef
;
212 Point pt
= (**(ListHandle
)m_macList
).cellSize
;
214 LCellSize( pt
, (ListHandle
)m_macList
) ;
215 LAddColumn( 1 , 0 , (ListHandle
)m_macList
) ;
217 OptionBits options
= 0;
218 if ( style
& wxLB_MULTIPLE
)
220 options
+= lNoExtend
;
222 else if ( style
& wxLB_EXTENDED
)
224 options
+= lExtendDrag
;
230 SetListSelectionFlags((ListHandle
)m_macList
, options
);
232 MacPostControlCreate() ;
234 for ( int i
= 0 ; i
< n
; i
++ )
236 Append( choices
[i
] ) ;
239 LSetDrawingMode( true , (ListHandle
) m_macList
) ;
244 // ----------------------------------------------------------------------------
245 // wxCheckListBox functions
246 // ----------------------------------------------------------------------------
248 bool wxCheckListBox::IsChecked(size_t item
) const
250 wxCHECK_MSG( item
< m_checks
.GetCount(), FALSE
,
251 _T("invalid index in wxCheckListBox::IsChecked") );
253 return m_checks
[item
] != 0;
256 void wxCheckListBox::Check(size_t item
, bool check
)
258 wxCHECK_RET( item
< m_checks
.GetCount(),
259 _T("invalid index in wxCheckListBox::Check") );
261 // intermediate var is needed to avoid compiler warning with VC++
262 bool isChecked
= m_checks
[item
] != 0;
263 if ( check
!= isChecked
)
265 m_checks
[item
] = check
;
271 // ----------------------------------------------------------------------------
272 // methods forwarded to wxListBox
273 // ----------------------------------------------------------------------------
275 void wxCheckListBox::Delete(int n
)
277 wxCHECK_RET( n
< GetCount(), _T("invalid index in wxListBox::Delete") );
279 wxListBox::Delete(n
);
281 m_checks
.RemoveAt(n
);
284 int wxCheckListBox::DoAppend(const wxString
& item
)
286 int pos
= wxListBox::DoAppend(item
);
288 // the item is initially unchecked
289 m_checks
.Insert(FALSE
, pos
);
294 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
296 wxListBox::DoInsertItems(items
, pos
);
298 size_t count
= items
.GetCount();
299 for ( size_t n
= 0; n
< count
; n
++ )
301 m_checks
.Insert(FALSE
, pos
+ n
);
305 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
307 // call it first as it does DoClear()
308 wxListBox::DoSetItems(items
, clientData
);
310 size_t count
= items
.GetCount();
311 for ( size_t n
= 0; n
< count
; n
++ )
317 void wxCheckListBox::DoClear()
322 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
323 EVT_CHAR(wxCheckListBox::OnChar
)
324 EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick
)
327 // this will only work as soon as
329 void wxCheckListBox::OnChar(wxKeyEvent
& event
)
331 if ( event
.KeyCode() == WXK_SPACE
)
333 int index
= GetSelection() ;
336 Check(index
, !IsChecked(index
) ) ;
337 wxCommandEvent
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, GetId());
339 event
.SetEventObject(this);
340 GetEventHandler()->ProcessEvent(event
);
347 void wxCheckListBox::OnLeftClick(wxMouseEvent
& event
)
349 // clicking on the item selects it, clicking on the checkmark toggles
350 if ( event
.GetX() <= 20 /*check width*/ ) {
355 GetListCellSize( m_macList
, &pt
) ;
358 GetListVisibleCells( m_macList
, &visible
) ;
359 topcell
= visible
.top
;
361 lineheight
= (**(ListHandle
)m_macList
).cellSize
.v
;
362 topcell
= (**(ListHandle
)m_macList
).visible
.top
;
364 size_t nItem
= ((size_t)event
.GetY()) / lineheight
+ topcell
;
366 if ( nItem
< (size_t)m_noItems
)
368 Check(nItem
, !IsChecked(nItem
) ) ;
369 wxCommandEvent
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, GetId());
371 event
.SetEventObject(this);
372 GetEventHandler()->ProcessEvent(event
);
374 //else: it's not an error, just click outside of client zone
377 // implement default behaviour: clicking on the item selects it
382 #endif // wxUSE_CHECKLISTBOX