From ee528046a46d8757cbed9a3a9f8981b175aa15d4 Mon Sep 17 00:00:00 2001 From: David Elliott Date: Mon, 18 Feb 2008 21:13:58 +0000 Subject: [PATCH] Ensure that the NSTableColumn width is that of its largest item to enable horizontal scrolling in wxListBox. Copyright 2008 Software 2000 Ltd. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@51892 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/cocoa/listbox.h | 3 ++ src/cocoa/listbox.mm | 88 +++++++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/include/wx/cocoa/listbox.h b/include/wx/cocoa/listbox.h index 0002435bbc..fac2a73aa4 100644 --- a/include/wx/cocoa/listbox.h +++ b/include/wx/cocoa/listbox.h @@ -76,6 +76,9 @@ protected: WX_NSMutableArray m_cocoaItems; wxArrayPtrVoid m_itemClientData; struct objc_object *m_cocoaDataSource; + inline bool _WxCocoa_GetNeedsUpdate(); + inline void _WxCocoa_SetNeedsUpdate(bool needsUpdate); + void _WxCocoa_OnIdle(wxIdleEvent &event); // ------------------------------------------------------------------------ // Implementation // ------------------------------------------------------------------------ diff --git a/src/cocoa/listbox.mm b/src/cocoa/listbox.mm index aa4c5269c3..25c66be336 100644 --- a/src/cocoa/listbox.mm +++ b/src/cocoa/listbox.mm @@ -31,9 +31,63 @@ #import #import #import +#import + +// ============================================================================ +// @class wxCocoaListBoxNSTableDataSource +// ============================================================================ +// 2.8 hack: We can't add an i-var to wxListBox so we add one here +@interface wxCocoaListBoxNSTableDataSource : wxCocoaNSTableDataSource +{ + BOOL m_needsUpdate; +} + +@end +WX_DECLARE_GET_OBJC_CLASS(wxCocoaListBoxNSTableDataSource,wxCocoaNSTableDataSource) + +@implementation wxCocoaListBoxNSTableDataSource +// No methods +@end +WX_IMPLEMENT_GET_OBJC_CLASS_WITH_UNIQUIFIED_SUPERCLASS(wxCocoaListBoxNSTableDataSource,wxCocoaNSTableDataSource) + + +// ============================================================================ +// helper functions +// ============================================================================ + +static CGFloat _TableColumnMaxWidthForItems(NSTableColumn *tableColumn, NSArray *items) +{ + wxAutoNSAutoreleasePool pool; + + NSCell *dataCell = [[[tableColumn dataCell] copy] autorelease]; + CGFloat width = 0.0f; + NSEnumerator *itemEnum = [items objectEnumerator]; + NSString *item; + while( (item = [itemEnum nextObject]) != nil ) + { + [dataCell setStringValue: item]; + NSSize itemSize = [dataCell cellSize]; + CGFloat itemWidth = itemSize.width; + if(itemWidth > width) + width = itemWidth; + } + return width; +} + +static void _SetWidthOfTableColumnToFitItems(NSTableColumn *tableColumn, NSArray *items) +{ + CGFloat width = _TableColumnMaxWidthForItems(tableColumn, items); + [tableColumn setWidth:width]; + [tableColumn setMinWidth:width]; +} + +// ============================================================================ +// class wxListBox +// ============================================================================ IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl) BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase) + EVT_IDLE(wxListBox::_WxCocoa_OnIdle) END_EVENT_TABLE() WX_IMPLEMENT_COCOA_OWNER(wxListBox,NSTableView,NSControl,NSView) @@ -101,7 +155,7 @@ The listbox contents are sorted in alphabetical order. [GetNSTableView() setHeaderView: nil]; // Set up the data source - m_cocoaDataSource = [[WX_GET_OBJC_CLASS(wxCocoaNSTableDataSource) alloc] init]; + m_cocoaDataSource = [[WX_GET_OBJC_CLASS(wxCocoaListBoxNSTableDataSource) alloc] init]; [GetNSTableView() setDataSource:m_cocoaDataSource]; // Add the single column @@ -133,7 +187,7 @@ The listbox contents are sorted in alphabetical order. [GetNSTableView() setAllowsMultipleSelection:true]; [GetNSTableView() setAllowsColumnSelection:false]; - + _SetWidthOfTableColumnToFitItems(tableColumn, m_cocoaItems); return true; } @@ -146,6 +200,28 @@ wxListBox::~wxListBox() DisassociateNSTableView(GetNSTableView()); } +bool wxListBox::_WxCocoa_GetNeedsUpdate() +{ + return static_cast(m_cocoaDataSource)->m_needsUpdate; +} + +void wxListBox::_WxCocoa_SetNeedsUpdate(bool needsUpdate) +{ + static_cast(m_cocoaDataSource)->m_needsUpdate = needsUpdate; +} + +void wxListBox::_WxCocoa_OnIdle(wxIdleEvent &event) +{ + event.Skip(); + if(_WxCocoa_GetNeedsUpdate()) + { + _SetWidthOfTableColumnToFitItems([[GetNSTableView() tableColumns] objectAtIndex:0], m_cocoaItems); + [GetNSTableView() tile]; + [GetNSTableView() reloadData]; + _WxCocoa_SetNeedsUpdate(false); + } +} + int wxListBox::CocoaDataSource_numberOfRows() { return [m_cocoaItems count]; @@ -192,7 +268,7 @@ void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) atIndex: pos]; m_itemClientData.Insert(NULL,pos); } - [GetNSTableView() reloadData]; + _WxCocoa_SetNeedsUpdate(true); } void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) @@ -208,7 +284,7 @@ void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) [m_cocoaItems addObject: wxNSStringWithWxString(items[i])]; m_itemClientData.Add(clientData[i]); } - [GetNSTableView() reloadData]; + _WxCocoa_SetNeedsUpdate(true); } void wxListBox::DoSetFirstItem(int n) @@ -234,7 +310,7 @@ void wxListBox::Delete(unsigned int n) { [m_cocoaItems removeObjectAtIndex:n]; m_itemClientData.RemoveAt(n); - [GetNSTableView() reloadData]; + _WxCocoa_SetNeedsUpdate(true); } // accessing strings @@ -273,7 +349,7 @@ int wxListBox::DoAppend(const wxString& item) { wxAutoNSAutoreleasePool pool; [m_cocoaItems addObject:wxNSStringWithWxString(item)]; - [GetNSTableView() reloadData]; + _WxCocoa_SetNeedsUpdate(true); m_itemClientData.Add(NULL); return [m_cocoaItems count]; }