// 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"
+#include <Appearance.h>
// ============================================================================
// implementation of wxCheckListBox
IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
-const short kwxMacListWithVerticalScrollbar = 128 ;
-const short kwxMacListItemHeight = 14 ;
-const short kwxMacListCheckboxWidth = 14 ;
-
-#if PRAGMA_STRUCT_ALIGN
- #pragma options align=mac68k
-#elif PRAGMA_STRUCT_PACKPUSH
- #pragma pack(push, 2)
-#elif PRAGMA_STRUCT_PACK
- #pragma pack(2)
-#endif
-
-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
-
-extern "C"
-{
-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 )
-{
- 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;
-
- case lCloseMsg:
- break;
-
- case lDrawMsg:
- {
- 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 );
-
- wxFontRefData * font = (wxFontRefData*) (list->GetFont().GetRefData()) ;
-
- if ( font )
- {
- ::TextFont( font->m_macFontNum ) ;
- ::TextSize( font->m_macFontSize) ;
- ::TextFace( font->m_macFontStyle ) ;
- }
-
- ThemeButtonDrawInfo info ;
- info.state = kThemeStateActive ;
- info.value = checked ? kThemeButtonOn : kThemeButtonOff ;
- info.adornment = kThemeAdornmentNone ;
- Rect checkRect = *drawRect ;
-
-
- checkRect.left +=0 ;
- checkRect.top +=0 ;
- checkRect.right = checkRect.left + list->m_checkBoxWidth ;
- checkRect.bottom = checkRect.top + list->m_checkBoxHeight ;
- DrawThemeButton(&checkRect,kThemeCheckBox,
- &info,NULL,NULL, NULL,0);
-
- MoveTo(drawRect->left + 2 + list->m_checkBoxWidth+2, drawRect->top + list->m_TextBaseLineOffset );
-
- 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 );
- }
-
- // Restore the saved clip region.
-
- SetClip( savedClipRegion );
- DisposeRgn( savedClipRegion );
- }
- 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) ;
+BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
+END_EVENT_TABLE()
-static ListDefUPP macCheckListDefUPP = NULL ;
+const short kTextColumnId = 1024 ;
+const short kCheckboxColumnId = 1025 ;
-// ----------------------------------------------------------------------------
-// creation
-// ----------------------------------------------------------------------------
+// new databrowser based version
+// Listbox item
void wxCheckListBox::Init()
{
}
wxWindowID id,
const wxPoint &pos,
const wxSize &size,
- int n,
- const wxString choices[],
+ const wxArrayString& choices,
long style,
const wxValidator& validator,
const wxString &name)
{
- m_noItems = 0 ; // this will be increased by our append command
- m_selected = 0;
-
- m_checkBoxWidth = 12;
- m_checkBoxHeight= 10;
-
- long h = m_checkBoxHeight ;
-#if TARGET_CARBON
- GetThemeMetric(kThemeMetricCheckBoxWidth,(long *)&m_checkBoxWidth);
- GetThemeMetric(kThemeMetricCheckBoxHeight,&h);
-#endif
- wxFontRefData * font = (wxFontRefData*) (GetFont().GetRefData()) ;
+ wxCArrayString chs(choices);
- FontInfo finfo;
- FetchFontInfo(font->m_macFontNum,short(font->m_macFontSize),font->m_macFontStyle,&finfo);
-
- m_TextBaseLineOffset= finfo.leading+finfo.ascent;
- m_checkBoxHeight= finfo.leading+finfo.ascent+finfo.descent;
-
- if (m_checkBoxHeight<h)
- {
- m_TextBaseLineOffset+= (h-m_checkBoxHeight)/2;
- m_checkBoxHeight= h;
- }
-
- Rect bounds ;
- Str255 title ;
-
- MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ;
+ return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+ style, validator, name);
+}
- ListDefSpec listDef;
- listDef.defType = kListDefUserProcType;
- if ( macCheckListDefUPP == NULL )
+#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 )
{
- macCheckListDefUPP = NewListDefUPP( wxMacCheckListDefinition );
- }
- listDef.u.userProc = macCheckListDefUPP ;
-
-#if TARGET_CARBON
- Size asize;
+ wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
+ int i = itemID - 1 ;
+ if (i >= 0 && i < list->GetCount() )
+ {
+ 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 ;
+ }
+ 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) ;
+ }
+ }
+ }
+}
- CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, false, true,
- m_checkBoxHeight+2, 14, false, &listDef, (ControlRef *)&m_macControl );
- GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag,
- sizeof(ListHandle), (Ptr) &m_macList, &asize);
+static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
+ DataBrowserItemID itemID, DataBrowserPropertyID property,
+ DataBrowserItemDataRef itemData, Boolean changeValue)
+{
+ OSStatus err = errDataBrowserPropertyNotSupported;
+
+ if ( ! changeValue )
+ {
+ 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;
+ }
+ }
+ 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);
+ }
+ }
+
+ }
+ break ;
+
+ default :
+ break ;
+ }
+ }
+
+ 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 ;
- SetControlReference( (ControlHandle) m_macControl, (long) this);
- SetControlVisibility( (ControlHandle) m_macControl, false, false);
+ wxASSERT_MSG( !(style & wxLB_MULTIPLE) || !(style & wxLB_EXTENDED),
+ _T("only one of listbox selection modes can be specified") );
+
+ 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 ) ;
- wxStAppResource resload ;
- 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() ;
+ 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 = (OptionBits) 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);
+
+ MacPostControlCreate(pos,size) ;
+
for ( int i = 0 ; i < n ; i++ )
{
Append( choices[i] ) ;
}
-
- LSetDrawingMode( true , (ListHandle) m_macList ) ;
+ SetBestSize(size); // Needed because it is a wxControlWithItems
+
return TRUE;
}
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 wxCheckListBox::DoAppend(const wxString& item)
{
- LSetDrawingMode( false , (ListHandle) m_macList ) ;
int pos = wxListBox::DoAppend(item);
// the item is initially unchecked
m_checks.Insert(FALSE, pos);
- LSetDrawingMode( true , (ListHandle) m_macList ) ;
return pos;
}
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.GetKeyCode() == 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