///////////////////////////////////////////////////////////////////////////////
// Name: checklst.cpp
// Purpose: implementation of wxCheckListBox class
-// Author: AUTHOR
-// Modified by:
-// Created: ??/??/98
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
+// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// headers & declarations
// ============================================================================
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "checklst.h"
#endif
-#include "wx/defs.h"
+#include "wx/wxprec.h"
#if wxUSE_CHECKLISTBOX
#include "wx/checklst.h"
+#include "wx/arrstr.h"
#include "wx/mac/uma.h"
-#include "Appearance.h"
+#ifndef __DARWIN__
+#include <Appearance.h>
+#endif
// ============================================================================
// implementation of wxCheckListBox
IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
-const short kwxMacListWithVerticalScrollbar = 128 ;
-const short kwxMacListItemHeight = 14 ;
-const short kwxMacListCheckboxWidth = 14 ;
+BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
+END_EVENT_TABLE()
-#if PRAGMA_STRUCT_ALIGN
- #pragma options align=mac68k
-#elif PRAGMA_STRUCT_PACKPUSH
- #pragma pack(push, 2)
-#elif PRAGMA_STRUCT_PACK
- #pragma pack(2)
-#endif
+const short kTextColumnId = 1024 ;
+const short kCheckboxColumnId = 1025 ;
-typedef struct {
- unsigned short instruction;
- void (*function)();
-} ldefRec, *ldefPtr, **ldefHandle;
-
-#if PRAGMA_STRUCT_ALIGN
- #pragma options align=reset
-#elif PRAGMA_STRUCT_PACKPUSH
- #pragma pack(pop)
-#elif PRAGMA_STRUCT_PACK
- #pragma pack()
-#endif
+// new databrowser based version
-extern "C"
+// Listbox item
+void wxCheckListBox::Init()
{
-static pascal void wxMacCheckListDefinition( short message, Boolean isSelected, Rect *drawRect,
- Cell cell, short dataOffset, short dataLength,
- ListHandle listHandle ) ;
}
-static pascal void wxMacCheckListDefinition( short message, Boolean isSelected, Rect *drawRect,
- Cell cell, short dataOffset, short dataLength,
- ListHandle listHandle )
+bool wxCheckListBox::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ const wxArrayString& choices,
+ long style,
+ const wxValidator& validator,
+ const wxString &name)
{
- GrafPtr savePort;
- GrafPtr grafPtr;
- RgnHandle savedClipRegion;
- SInt32 savedPenMode;
- wxCheckListBox* list;
- GetPort(&savePort);
- SetPort((**listHandle).port);
- grafPtr = (**listHandle).port ;
- // typecast our refCon
- list = (wxCheckListBox*) GetControlReference( (ControlHandle) GetListRefCon(listHandle) );
-
- // Calculate the cell rect.
-
- switch( message ) {
- case lInitMsg:
- break;
+ wxCArrayString chs(choices);
- case lCloseMsg:
- break;
+ return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+ style, validator, name);
+}
- case lDrawMsg:
+#if TARGET_API_MAC_OSX
+static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
+ DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
+#else
+static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
+ DataBrowserItemNotification message)
+#endif
+{
+ long ref = GetControlReference( browser ) ;
+ if ( ref )
+ {
+ wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
+ int i = itemID - 1 ;
+ if (i >= 0 && i < list->GetCount() )
{
- const wxString text = list->m_stringArray[cell.v] ;
- int checked = list->m_checks[cell.v] ;
-
- // Save the current clip region, and set the clip region to the area we are about
- // to draw.
-
- savedClipRegion = NewRgn();
- GetClip( savedClipRegion );
-
- ClipRect( drawRect );
- EraseRect( drawRect );
-
- ::TextFont( kFontIDMonaco ) ;
- ::TextSize( 9 );
- ::TextFace( 0 ) ;
- ThemeButtonDrawInfo info ;
- info.state = kThemeStateActive ;
- info.value = checked ? kThemeButtonOn : kThemeButtonOff ;
- info.adornment = kThemeAdornmentNone ;
- Rect checkRect = *drawRect ;
- checkRect.left +=0 ;
- checkRect.top +=2 ;
- checkRect.right = checkRect.left + 12 ;
- checkRect.bottom = checkRect.top + 10 ;
- DrawThemeButton(&checkRect,kThemeCheckBox,
- &info,NULL,NULL, NULL,0);
-
- MoveTo(drawRect->left + 4 + kwxMacListCheckboxWidth, drawRect->top + 10 );
-
- DrawText(text, 0 , text.Length());
- // If the cell is hilited, do the hilite now. Paint the cell contents with the
- // appropriate QuickDraw transform mode.
-
- if( isSelected ) {
- savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
- SetPortPenMode( (CGrafPtr) grafPtr, hilitetransfermode );
- PaintRect( drawRect );
- SetPortPenMode( (CGrafPtr) grafPtr, savedPenMode );
+ bool trigger = false ;
+ wxCommandEvent event(
+ wxEVT_COMMAND_LISTBOX_SELECTED, list->GetId() );
+ switch( message )
+ {
+ case kDataBrowserItemDeselected :
+ if ( list->HasMultipleSelection() )
+ trigger = true ;
+ break ;
+ case kDataBrowserItemSelected :
+ trigger = true ;
+ break ;
+ case kDataBrowserItemDoubleClicked :
+ event.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) ;
+ trigger = true ;
+ break ;
+ default :
+ break ;
}
-
- // Restore the saved clip region.
-
- SetClip( savedClipRegion );
- DisposeRgn( savedClipRegion );
+
+ if ( trigger )
+ {
+ event.SetEventObject( list );
+ if ( list->HasClientObjectData() )
+ event.SetClientObject( list->GetClientObject(i) );
+ else if ( list->HasClientUntypedData() )
+ event.SetClientData( list->GetClientData(i) );
+ event.SetString( list->GetString(i) );
+ event.SetInt(i) ;
+ event.SetExtraLong( list->HasMultipleSelection() ? message == kDataBrowserItemSelected : TRUE );
+ wxPostEvent( list->GetEventHandler() , event ) ;
+ // direct notification is not always having the listbox GetSelection() having in synch with event
+ // list->GetEventHandler()->ProcessEvent(event) ;
}
- break;
- case lHiliteMsg:
-
- // Hilite or unhilite the cell. Paint the cell contents with the
- // appropriate QuickDraw transform mode.
-
- GetPort( &grafPtr );
- savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
- SetPortPenMode( (CGrafPtr) grafPtr, hilitetransfermode );
- PaintRect( drawRect );
- SetPortPenMode( (CGrafPtr) grafPtr, savedPenMode );
- break;
- default :
- break ;
+ }
}
- SetPort(savePort);
}
-extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
-
-static ListDefUPP macCheckListDefUPP = NULL ;
-
-// ----------------------------------------------------------------------------
-// creation
-// ----------------------------------------------------------------------------
-void wxCheckListBox::Init()
+static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
+ DataBrowserItemID itemID, DataBrowserPropertyID property,
+ DataBrowserItemDataRef itemData, Boolean changeValue)
{
-}
+ OSStatus err = errDataBrowserPropertyNotSupported;
-bool wxCheckListBox::Create(wxWindow *parent,
- wxWindowID id,
- const wxPoint &pos,
- const wxSize &size,
- int n,
- const wxString choices[],
- long style,
- const wxValidator& validator,
- const wxString &name)
-{
- m_noItems = 0 ; // this will be increased by our append command
- m_selected = 0;
-
- Rect bounds ;
- Str255 title ;
-
- MacPreControlCreate( parent , id , "" , pos , size ,style, validator , name , &bounds , title ) ;
-
- ListDefSpec listDef;
- listDef.defType = kListDefUserProcType;
- if ( macCheckListDefUPP == NULL )
+ if ( ! changeValue )
{
- macCheckListDefUPP = NewListDefUPP( wxMacCheckListDefinition );
+ switch (property)
+ {
+
+ case kTextColumnId:
+ {
+ long ref = GetControlReference( browser ) ;
+ if ( ref )
+ {
+ wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
+ int i = itemID - 1 ;
+ if (i >= 0 && i < list->GetCount() )
+ {
+ wxMacCFStringHolder cf( list->GetString(i) , list->GetFont().GetEncoding() ) ;
+ verify_noerr( ::SetDataBrowserItemDataText( itemData , cf ) ) ;
+ err = noErr ;
+ }
+ }
+ }
+ break;
+ case kCheckboxColumnId :
+ {
+ long ref = GetControlReference( browser ) ;
+ if ( ref )
+ {
+ wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
+ int i = itemID - 1 ;
+ if (i >= 0 && i < list->GetCount() )
+ {
+ verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData , list->IsChecked( i ) ? kThemeButtonOn : kThemeButtonOff ) ) ;
+ err = noErr ;
+ }
+ }
+ }
+ break ;
+ case kDataBrowserItemIsEditableProperty:
+ {
+ err = ::SetDataBrowserItemDataBooleanValue(itemData, true);
+ }
+ break;
+
+ default:
+ break;
+ }
}
- listDef.u.userProc = macCheckListDefUPP ;
+ else
+ {
+ switch( property )
+ {
+ case kCheckboxColumnId :
+ {
+ long ref = GetControlReference( browser ) ;
+ if ( ref )
+ {
+ wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
+ int i = itemID - 1 ;
+ if (i >= 0 && i < list->GetCount() )
+ {
+ // we have to change this behind the back, since Check() would be triggering another update round
+ bool newVal = !list->IsChecked( i ) ;
+ verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData , newVal ? kThemeButtonOn : kThemeButtonOff ) ) ;
+ err = noErr ;
+ list->m_checks[ i ] = newVal ;
+
+ wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, list->GetId());
+ event.SetInt(i);
+ event.SetEventObject(list);
+ list->GetEventHandler()->ProcessEvent(event);
+ }
+ }
-#if TARGET_CARBON
- Size asize;
+ }
+ break ;
+ default :
+ break ;
+ }
+ }
- CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, false, true,
- 14, 14, false, &listDef, (ControlRef *)&m_macControl );
+ return err;
+}
+bool wxCheckListBox::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ int n, const wxString choices[],
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ m_macIsUserPane = false ;
- GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag,
- sizeof(ListHandle), (Ptr) &m_macList, &asize);
+ wxASSERT_MSG( !(style & wxLB_MULTIPLE) || !(style & wxLB_EXTENDED),
+ _T("only one of listbox selection modes can be specified") );
- SetControlReference( (ControlHandle) m_macControl, (long) this);
- SetControlVisibility( (ControlHandle) m_macControl, false, false);
+ if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
+ return false;
-#else
+ m_noItems = 0 ; // this will be increased by our append command
+ m_selected = 0;
- long result ;
+ Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
- m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false ,
- kwxMacListWithVerticalScrollbar , 0 , 0,
- kControlListBoxProc , (long) this ) ;
- ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxListHandleTag ,
- sizeof( ListHandle ) , (char*) &m_macList , &result ) ;
+ m_peer = new wxMacControl(this) ;
+ verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, kDataBrowserListView , m_peer->GetControlRefAddr() ) );
- HLock( (Handle) m_macList ) ;
- ldefHandle ldef ;
- ldef = (ldefHandle) NewHandle( sizeof(ldefRec) ) ;
- if ( (**(ListHandle)m_macList).listDefProc != NULL )
- {
- (**ldef).instruction = 0x4EF9; /* JMP instruction */
- (**ldef).function = (void(*)()) listDef.u.userProc;
- (**(ListHandle)m_macList).listDefProc = (Handle) ldef ;
- }
-
- Point pt = (**(ListHandle)m_macList).cellSize ;
- pt.v = 14 ;
- LCellSize( pt , (ListHandle)m_macList ) ;
- LAddColumn( 1 , 0 , (ListHandle)m_macList ) ;
-#endif
- OptionBits options = 0;
+
+ DataBrowserSelectionFlags options = kDataBrowserDragSelect ;
if ( style & wxLB_MULTIPLE )
{
- options += lNoExtend ;
+ options += kDataBrowserAlwaysExtendSelection + kDataBrowserCmdTogglesSelection ;
}
else if ( style & wxLB_EXTENDED )
{
- options += lExtendDrag ;
+ // default behaviour
}
else
{
- options = lOnlyOne ;
+ options += kDataBrowserSelectOnlyOne ;
}
- SetListSelectionFlags((ListHandle)m_macList, options);
-
- MacPostControlCreate() ;
-
+ verify_noerr(m_peer->SetSelectionFlags( options ) );
+
+ DataBrowserListViewColumnDesc columnDesc ;
+ columnDesc.headerBtnDesc.titleOffset = 0;
+ columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
+
+ columnDesc.headerBtnDesc.btnFontStyle.flags =
+ kControlUseFontMask | kControlUseJustMask;
+
+ columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlNoContent;
+ columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault;
+ columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
+ columnDesc.headerBtnDesc.btnFontStyle.style = normal;
+ columnDesc.headerBtnDesc.titleString = NULL ; // CFSTR( "" );
+
+ // check column
+
+ columnDesc.headerBtnDesc.minimumWidth = 30 ;
+ columnDesc.headerBtnDesc.maximumWidth = 30;
+
+ columnDesc.propertyDesc.propertyID = kCheckboxColumnId;
+ columnDesc.propertyDesc.propertyType = kDataBrowserCheckboxType;
+ columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | kDataBrowserTableViewSelectionColumn |
+ kDataBrowserDefaultPropertyFlags;
+ verify_noerr( m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn) ) ;
+
+ // text column
+
+ columnDesc.headerBtnDesc.minimumWidth = 0;
+ columnDesc.headerBtnDesc.maximumWidth = 10000;
+
+ columnDesc.propertyDesc.propertyID = kTextColumnId;
+ columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
+ columnDesc.propertyDesc.propertyFlags = kDataBrowserTableViewSelectionColumn
+#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
+ | kDataBrowserListViewTypeSelectColumn
+#endif
+ ;
+
+
+ verify_noerr( m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn) ) ;
+
+ verify_noerr( m_peer->AutoSizeListViewColumns() ) ;
+ verify_noerr( m_peer->SetHasScrollBars( false , true ) ) ;
+ verify_noerr( m_peer->SetTableViewHiliteStyle( kDataBrowserTableViewFillHilite ) ) ;
+ verify_noerr( m_peer->SetListViewHeaderBtnHeight(0 ) ) ;
+
+ DataBrowserCallbacks callbacks ;
+ callbacks.version = kDataBrowserLatestCallbacks;
+ InitDataBrowserCallbacks(&callbacks);
+ callbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP(ListBoxGetSetItemData);
+ callbacks.u.v1.itemNotificationCallback =
+#if TARGET_API_MAC_OSX
+ (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc) ;
+#else
+ NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc) ;
+#endif
+ m_peer->SetCallbacks( &callbacks);
+
+#if 0
+ // shouldn't be necessary anymore under 10.2
+ m_peer->SetData( kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, (Boolean) false ) ;
+ m_peer->SetNeedsFocusRect( true ) ;
+#endif
+
+ MacPostControlCreate(pos,size) ;
+
for ( int i = 0 ; i < n ; i++ )
{
Append( choices[i] ) ;
}
-
- LSetDrawingMode( true , (ListHandle) m_macList ) ;
- return TRUE;
+ SetBestSize(size); // Needed because it is a wxControlWithItems
+
+ return true;
}
// ----------------------------------------------------------------------------
bool wxCheckListBox::IsChecked(size_t item) const
{
- wxCHECK_MSG( item < m_checks.GetCount(), FALSE,
+ wxCHECK_MSG( item < m_checks.GetCount(), false,
_T("invalid index in wxCheckListBox::IsChecked") );
return m_checks[item] != 0;
wxCHECK_RET( item < m_checks.GetCount(),
_T("invalid index in wxCheckListBox::Check") );
- // intermediate var is needed to avoid compiler warning with VC++
bool isChecked = m_checks[item] != 0;
if ( check != isChecked )
{
m_checks[item] = check;
-
- MacRedrawControl() ;
+ UInt32 id = item + 1 ;
+ verify_noerr( m_peer->UpdateItems(kDataBrowserNoItem , 1 , &id , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
}
}
// ----------------------------------------------------------------------------
-// methods forwarded to wxListBox
+// methods forwarded to wxCheckListBox
// ----------------------------------------------------------------------------
void wxCheckListBox::Delete(int n)
{
- wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
+ wxCHECK_RET( n < GetCount(), _T("invalid index in wxCheckListBox::Delete") );
wxListBox::Delete(n);
int pos = wxListBox::DoAppend(item);
// the item is initially unchecked
- m_checks.Insert(FALSE, pos);
+ m_checks.Insert(false, pos);
return pos;
}
size_t count = items.GetCount();
for ( size_t n = 0; n < count; n++ )
{
- m_checks.Insert(FALSE, pos + n);
+ m_checks.Insert(false, pos + n);
}
}
size_t count = items.GetCount();
for ( size_t n = 0; n < count; n++ )
{
- m_checks.Add(FALSE);
+ m_checks.Add(false);
}
}
m_checks.Empty();
}
-BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
- EVT_CHAR(wxCheckListBox::OnChar)
- EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick)
-END_EVENT_TABLE()
-
-// this will only work as soon as
-
-void wxCheckListBox::OnChar(wxKeyEvent& event)
-{
- if ( event.KeyCode() == WXK_SPACE )
- {
- int index = GetSelection() ;
- if ( index >= 0 )
- {
- Check(index, !IsChecked(index) ) ;
- wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, GetId());
- event.SetInt(index);
- event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event);
- }
- }
- else
- event.Skip();
-}
-
-void wxCheckListBox::OnLeftClick(wxMouseEvent& event)
-{
- // clicking on the item selects it, clicking on the checkmark toggles
- if ( event.GetX() <= 20 /*check width*/ ) {
- int lineheight ;
- int topcell ;
-#if TARGET_CARBON
- Point pt ;
- GetListCellSize( (ListHandle)m_macList , &pt ) ;
- lineheight = pt.v ;
- ListBounds visible ;
- GetListVisibleCells( (ListHandle)m_macList , &visible ) ;
- topcell = visible.top ;
-#else
- lineheight = (**(ListHandle)m_macList).cellSize.v ;
- topcell = (**(ListHandle)m_macList).visible.top ;
-#endif
- size_t nItem = ((size_t)event.GetY()) / lineheight + topcell ;
-
- if ( nItem < (size_t)m_noItems )
- {
- Check(nItem, !IsChecked(nItem) ) ;
- wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, GetId());
- event.SetInt(nItem);
- event.SetEventObject(this);
- GetEventHandler()->ProcessEvent(event);
- }
- //else: it's not an error, just click outside of client zone
- }
- else {
- // implement default behaviour: clicking on the item selects it
- event.Skip();
- }
-}
-
#endif // wxUSE_CHECKLISTBOX