1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: wx/osx/cocoa/dataview.h 3 // Purpose: wxDataViewCtrl native implementation header for carbon 4 // Author: 5 // Copyright: (c) 2009 6 // Licence: wxWindows licence 7 ///////////////////////////////////////////////////////////////////////////// 8 9 #ifndef _WX_DATAVIEWCTRL_COCOOA_H_ 10 #define _WX_DATAVIEWCTRL_COCOOA_H_ 11 12 #include "wx/defs.h" 13 14 #import <Cocoa/Cocoa.h> 15 16 #include "wx/osx/core/dataview.h" 17 #include "wx/osx/private.h" 18 19 // Forward declaration 20 class wxCocoaDataViewControl; 21 22 /* 23 Dramatis personae: 24 25 [vertical arrows indicate inheritance, horizontal -- aggregation] 26 27 28 wxWindow ---> wxWidgetCocoaImpl wxDataViewWidgetImpl NSOutlineView 29 | \ / | 30 | \ / | 31 | \ / | 32 v \/ \/ v 33 wxDataViewCtrl -------> wxCocoaDataViewControl <-------> wxCocoaOutlineView 34 35 36 The right most classes are Objective-C only and can't be used from (pure) 37 C++ code. 38 */ 39 40 // ============================================================================ 41 // wxPointerObject: simply stores a pointer, without taking its ownership 42 // ============================================================================ 43 44 // Two pointer objects are equal if the containing pointers are equal. This 45 // means also that the hash value of a pointer object depends only on the 46 // stored pointer. 47 48 @interface wxPointerObject : NSObject 49 { 50 void* pointer; 51 } 52 53 -(id) initWithPointer:(void*)initPointer; 54 55 -(void*) pointer; 56 -(void) setPointer:(void*)newPointer; 57 @end 58 59 // ============================================================================ 60 // wxSortDescriptorObject: helper class to use native sorting facilities 61 // ============================================================================ 62 63 @interface wxSortDescriptorObject : NSSortDescriptor<NSCopying> 64 { 65 wxDataViewColumn* columnPtr; // pointer to the sorting column 66 67 wxDataViewModel* modelPtr; // pointer to model 68 } 69 70 -(id) 71 initWithModelPtr:(wxDataViewModel*)initModelPtr 72 sortingColumnPtr:(wxDataViewColumn*)initColumnPtr 73 ascending:(BOOL)sortAscending; 74 75 -(wxDataViewColumn*) columnPtr; 76 -(wxDataViewModel*) modelPtr; 77 78 -(void) setColumnPtr:(wxDataViewColumn*)newColumnPtr; 79 -(void) setModelPtr:(wxDataViewModel*)newModelPtr; 80 @end 81 82 // ============================================================================ 83 // wxDataViewColumnNativeData: extra data for wxDataViewColumn 84 // ============================================================================ 85 86 class wxDataViewColumnNativeData 87 { 88 public: wxDataViewColumnNativeData()89 wxDataViewColumnNativeData() : m_NativeColumnPtr(NULL) 90 { 91 } 92 wxDataViewColumnNativeData(NSTableColumn * initNativeColumnPtr)93 wxDataViewColumnNativeData(NSTableColumn* initNativeColumnPtr) 94 : m_NativeColumnPtr(initNativeColumnPtr) 95 { 96 } 97 GetNativeColumnPtr()98 NSTableColumn* GetNativeColumnPtr() const 99 { 100 return m_NativeColumnPtr; 101 } 102 SetNativeColumnPtr(NSTableColumn * newNativeColumnPtr)103 void SetNativeColumnPtr(NSTableColumn* newNativeColumnPtr) 104 { 105 m_NativeColumnPtr = newNativeColumnPtr; 106 } 107 108 private: 109 // not owned by us 110 NSTableColumn* m_NativeColumnPtr; 111 }; 112 113 // ============================================================================ 114 // wxDataViewRendererNativeData: extra data for wxDataViewRenderer 115 // ============================================================================ 116 117 class wxDataViewRendererNativeData 118 { 119 public: wxDataViewRendererNativeData()120 wxDataViewRendererNativeData() 121 : m_Object(NULL), m_ColumnCell(NULL) 122 { 123 Init(); 124 } 125 wxDataViewRendererNativeData(NSCell * initColumnCell)126 wxDataViewRendererNativeData(NSCell* initColumnCell) 127 : m_Object(NULL), m_ColumnCell([initColumnCell retain]) 128 { 129 Init(); 130 } 131 wxDataViewRendererNativeData(NSCell * initColumnCell,id initObject)132 wxDataViewRendererNativeData(NSCell* initColumnCell, id initObject) 133 : m_Object([initObject retain]), m_ColumnCell([initColumnCell retain]) 134 { 135 Init(); 136 } 137 ~wxDataViewRendererNativeData()138 ~wxDataViewRendererNativeData() 139 { 140 [m_ColumnCell release]; 141 [m_Object release]; 142 143 [m_origFont release]; 144 [m_origTextColour release]; 145 } 146 GetColumnCell()147 NSCell* GetColumnCell() const { return m_ColumnCell; } GetColumnPtr()148 NSTableColumn* GetColumnPtr() const { return m_TableColumnPtr; } GetItem()149 id GetItem() const { return m_Item; } GetItemCell()150 NSCell* GetItemCell() const { return m_ItemCell; } GetObject()151 id GetObject() const { return m_Object; } 152 SetColumnCell(NSCell * newCell)153 void SetColumnCell(NSCell* newCell) 154 { 155 [newCell retain]; 156 [m_ColumnCell release]; 157 m_ColumnCell = newCell; 158 } SetColumnPtr(NSTableColumn * newColumnPtr)159 void SetColumnPtr(NSTableColumn* newColumnPtr) 160 { 161 m_TableColumnPtr = newColumnPtr; 162 } SetItem(id newItem)163 void SetItem(id newItem) 164 { 165 m_Item = newItem; 166 } SetItemCell(NSCell * newCell)167 void SetItemCell(NSCell* newCell) 168 { 169 m_ItemCell = newCell; 170 } SetObject(id newObject)171 void SetObject(id newObject) 172 { 173 [newObject retain]; 174 [m_Object release]; 175 m_Object = newObject; 176 } 177 178 // The original cell font and text colour stored here are NULL by default 179 // and are only initialized to the values retrieved from the cell when we 180 // change them from wxCocoaOutlineView:willDisplayCell:forTableColumn:item: 181 // which calls our SaveOriginalXXX() methods before changing the cell 182 // attributes. 183 // 184 // This allows us to avoid doing anything for the columns without any 185 // attributes but still be able to restore the correct attributes for the 186 // ones that do. GetOriginalFont()187 NSFont *GetOriginalFont() const { return m_origFont; } GetOriginalTextColour()188 NSColor *GetOriginalTextColour() const { return m_origTextColour; } 189 SaveOriginalFont(NSFont * font)190 void SaveOriginalFont(NSFont *font) 191 { 192 m_origFont = [font retain]; 193 } 194 SaveOriginalTextColour(NSColor * textColour)195 void SaveOriginalTextColour(NSColor *textColour) 196 { 197 m_origTextColour = [textColour retain]; 198 } 199 200 // The ellipsization mode which we need to set for each cell being rendered. SetEllipsizeMode(wxEllipsizeMode mode)201 void SetEllipsizeMode(wxEllipsizeMode mode) { m_ellipsizeMode = mode; } GetEllipsizeMode()202 wxEllipsizeMode GetEllipsizeMode() const { return m_ellipsizeMode; } 203 204 // Set the line break mode for the given cell using our m_ellipsizeMode 205 void ApplyLineBreakMode(NSCell *cell); 206 207 private: 208 // common part of all ctors 209 void Init(); 210 211 id m_Item; // item NOT owned by renderer 212 213 // object that can be used by renderer for storing special data (owned by 214 // renderer) 215 id m_Object; 216 217 NSCell* m_ColumnCell; // column's cell is owned by renderer 218 NSCell* m_ItemCell; // item's cell is NOT owned by renderer 219 220 NSTableColumn* m_TableColumnPtr; // column NOT owned by renderer 221 222 // we own those if they're non-NULL 223 NSFont *m_origFont; 224 NSColor *m_origTextColour; 225 226 wxEllipsizeMode m_ellipsizeMode; 227 }; 228 229 // ============================================================================ 230 // wxCocoaOutlineDataSource 231 // ============================================================================ 232 233 // This class implements the data source delegate for the outline view. 234 // As only an informal protocol exists this class inherits from NSObject only. 235 // 236 // As mentioned in the documentation for NSOutlineView the native control does 237 // not own any data. Therefore, it has to be done by the data source. 238 // Unfortunately, wxWidget's data source is a C++ data source but 239 // NSOutlineDataSource requires objects as data. Therefore, the data (or better 240 // the native item objects) have to be stored additionally in the native data 241 // source. 242 // NSOutlineView requires quick access to the item objects and quick linear 243 // access to an item's children. This requires normally a hash type of storage 244 // for the item object itself and an array structure for each item's children. 245 // This means that basically two times the whole structure of wxWidget's model 246 // class has to be stored. 247 // This implementation is using a compromise: all items that are in use by the 248 // control are stored in a set (from there they can be easily retrieved) and 249 // owned by the set. Furthermore, children of the last parent are stored 250 // in a linear list. 251 // 252 @interface wxCocoaOutlineDataSource : NSObject wxOSX_10_6_AND_LATER(<NSOutlineViewDataSource>) 253 { 254 // descriptors specifying the sorting (currently the array only holds one 255 // object only) 256 NSArray* sortDescriptors; 257 258 NSMutableArray* children; // buffered children 259 260 NSMutableSet* items; // stores all items that are in use by the control 261 262 wxCocoaDataViewControl* implementation; 263 264 wxDataViewModel* model; 265 266 // parent of the buffered children; the object is owned 267 wxPointerObject* currentParentItem; 268 } 269 270 // methods of informal protocol: 271 -(BOOL) 272 outlineView:(NSOutlineView*)outlineView 273 acceptDrop:(id<NSDraggingInfo>)info 274 item:(id)item 275 childIndex:(NSInteger)index; 276 277 -(id) 278 outlineView:(NSOutlineView*)outlineView 279 child:(NSInteger)index 280 ofItem:(id)item; 281 282 -(id) 283 outlineView:(NSOutlineView*)outlineView 284 objectValueForTableColumn:(NSTableColumn*)tableColumn 285 byItem:(id)item; 286 287 -(BOOL) 288 outlineView:(NSOutlineView*)outlineView 289 isItemExpandable:(id)item; 290 291 -(NSInteger) 292 outlineView:(NSOutlineView*)outlineView 293 numberOfChildrenOfItem:(id)item; 294 295 -(NSDragOperation) 296 outlineView:(NSOutlineView*)outlineView 297 validateDrop:(id<NSDraggingInfo>)info 298 proposedItem:(id)item 299 proposedChildIndex:(NSInteger)index; 300 301 -(BOOL) 302 outlineView:(NSOutlineView*)outlineView 303 writeItems:(NSArray*)items 304 toPasteboard:(NSPasteboard*)pasteboard; 305 306 // buffer for items handling 307 -(void) addToBuffer:(wxPointerObject*)item; 308 -(void) clearBuffer; 309 // returns the item in the buffer that has got the same pointer as "item", 310 // if such an item does not exist nil is returned 311 -(wxPointerObject*) getDataViewItemFromBuffer:(const wxDataViewItem&)item; 312 -(wxPointerObject*) getItemFromBuffer:(wxPointerObject*)item; 313 -(BOOL) isInBuffer:(wxPointerObject*)item; 314 -(void) removeFromBuffer:(wxPointerObject*)item; 315 316 // buffered children handling 317 -(void) appendChild:(wxPointerObject*)item; 318 -(void) clearChildren; 319 -(wxPointerObject*) getChild:(NSUInteger)index; 320 -(NSUInteger) getChildCount; 321 -(void) removeChild:(NSUInteger)index; 322 323 // buffer handling 324 -(void) clearBuffers; 325 326 // sorting 327 -(NSArray*) sortDescriptors; 328 -(void) setSortDescriptors:(NSArray*)newSortDescriptors; 329 330 // access to wxWidgets variables 331 -(wxPointerObject*) currentParentItem; 332 -(wxCocoaDataViewControl*) implementation; 333 -(wxDataViewModel*) model; 334 -(void) setCurrentParentItem:(wxPointerObject*)newCurrentParentItem; 335 -(void) setImplementation:(wxCocoaDataViewControl*)newImplementation; 336 -(void) setModel:(wxDataViewModel*)newModel; 337 338 // other methods 339 -(void) 340 bufferItem:(wxPointerObject*)parentItem 341 withChildren:(wxDataViewItemArray*)dataViewChildrenPtr; 342 @end 343 344 // ============================================================================ 345 // wxCustomCell: used for custom renderers 346 // ============================================================================ 347 348 @interface wxCustomCell : NSTextFieldCell 349 { 350 } 351 352 -(NSSize) cellSize; 353 @end 354 355 // ============================================================================ 356 // wxImageTextCell 357 // ============================================================================ 358 // 359 // As the native cocoa environment does not have a cell displaying an icon/ 360 // image and text at the same time, it has to be implemented by the user. 361 // This implementation follows the implementation of Chuck Pisula in Apple's 362 // DragNDropOutline sample application. 363 // Although in wxDataViewCtrl icons are used on OSX icons do not exist for 364 // display. Therefore, the cell is also called wxImageTextCell. 365 // Instead of displaying images of any size (which is possible) this cell uses 366 // a fixed size for displaying the image. Larger images are scaled to fit 367 // into their reserved space. Smaller or not existing images use the fixed 368 // reserved size and are scaled if necessary. 369 // 370 @interface wxImageTextCell : NSTextFieldCell 371 { 372 @private 373 CGFloat xImageShift; // shift for the image in x-direction from border 374 CGFloat spaceImageText; // space between image and text 375 376 NSImage* image; // the image itself 377 378 NSSize imageSize; // largest size of the image; default size is (16, 16) 379 380 // the text alignment is used to align the whole cell (image and text) 381 NSTextAlignment cellAlignment; 382 } 383 384 -(NSTextAlignment) alignment; 385 -(void) setAlignment:(NSTextAlignment)newAlignment; 386 387 -(NSImage*) image; 388 -(void) setImage:(NSImage*)newImage; 389 390 -(NSSize) imageSize; 391 -(void) setImageSize:(NSSize) newImageSize; 392 393 -(NSSize) cellSize; 394 @end 395 396 // ============================================================================ 397 // wxCocoaOutlineView 398 // ============================================================================ 399 400 @interface wxCocoaOutlineView : NSOutlineView wxOSX_10_6_AND_LATER(<NSOutlineViewDelegate>) 401 { 402 @private 403 // column and row of the cell being edited or -1 if none 404 int currentlyEditedColumn, 405 currentlyEditedRow; 406 407 wxCocoaDataViewControl* implementation; 408 } 409 410 -(wxCocoaDataViewControl*) implementation; 411 -(void) setImplementation:(wxCocoaDataViewControl*) newImplementation; 412 @end 413 414 // ============================================================================ 415 // wxCocoaDataViewControl 416 // ============================================================================ 417 418 // This is the internal interface class between wxDataViewCtrl (wxWidget) and 419 // the native source view (Mac OS X cocoa). 420 class wxCocoaDataViewControl : public wxWidgetCocoaImpl, 421 public wxDataViewWidgetImpl 422 { 423 public: 424 // constructors / destructor 425 wxCocoaDataViewControl(wxWindow* peer, 426 const wxPoint& pos, 427 const wxSize& size, 428 long style); 429 virtual ~wxCocoaDataViewControl(); 430 GetDataViewCtrl()431 wxDataViewCtrl* GetDataViewCtrl() const 432 { 433 return static_cast<wxDataViewCtrl*>(GetWXPeer()); 434 } 435 436 // column related methods (inherited from wxDataViewWidgetImpl) 437 virtual bool ClearColumns(); 438 virtual bool DeleteColumn(wxDataViewColumn* columnPtr); 439 virtual void DoSetExpanderColumn(wxDataViewColumn const* columnPtr); 440 virtual wxDataViewColumn* GetColumn(unsigned int pos) const; 441 virtual int GetColumnPosition(wxDataViewColumn const* columnPtr) const; 442 virtual bool InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr); 443 virtual void FitColumnWidthToContent(unsigned int pos); 444 445 // item related methods (inherited from wxDataViewWidgetImpl) 446 virtual bool Add(const wxDataViewItem& parent, const wxDataViewItem& item); 447 virtual bool Add(const wxDataViewItem& parent, 448 const wxDataViewItemArray& items); 449 virtual void Collapse(const wxDataViewItem& item); 450 virtual void EnsureVisible(const wxDataViewItem& item, 451 wxDataViewColumn const* columnPtr); 452 virtual void Expand(const wxDataViewItem& item); 453 virtual unsigned int GetCount() const; 454 virtual wxRect GetRectangle(const wxDataViewItem& item, 455 wxDataViewColumn const* columnPtr); 456 virtual bool IsExpanded(const wxDataViewItem& item) const; 457 virtual bool Reload(); 458 virtual bool Remove(const wxDataViewItem& parent, 459 const wxDataViewItem& item); 460 virtual bool Remove(const wxDataViewItem& parent, 461 const wxDataViewItemArray& item); 462 virtual bool Update(const wxDataViewColumn* columnPtr); 463 virtual bool Update(const wxDataViewItem& parent, 464 const wxDataViewItem& item); 465 virtual bool Update(const wxDataViewItem& parent, 466 const wxDataViewItemArray& items); 467 468 // model related methods 469 virtual bool AssociateModel(wxDataViewModel* model); 470 471 // 472 // selection related methods (inherited from wxDataViewWidgetImpl) 473 // 474 virtual wxDataViewItem GetCurrentItem() const; 475 virtual void SetCurrentItem(const wxDataViewItem& item); 476 virtual wxDataViewColumn *GetCurrentColumn() const; 477 virtual int GetSelectedItemsCount() const; 478 virtual int GetSelections(wxDataViewItemArray& sel) const; 479 virtual bool IsSelected(const wxDataViewItem& item) const; 480 virtual void Select(const wxDataViewItem& item); 481 virtual void SelectAll(); 482 virtual void Unselect(const wxDataViewItem& item); 483 virtual void UnselectAll(); 484 485 // 486 // sorting related methods 487 // 488 virtual wxDataViewColumn* GetSortingColumn () const; 489 virtual void Resort(); 490 491 // 492 // other methods (inherited from wxDataViewWidgetImpl) 493 // 494 virtual void DoSetIndent(int indent); 495 virtual void HitTest(const wxPoint& point, 496 wxDataViewItem& item, 497 wxDataViewColumn*& columnPtr) const; 498 virtual void SetRowHeight(const wxDataViewItem& item, unsigned int height); 499 virtual void OnSize(); 500 501 virtual void StartEditor( const wxDataViewItem & item, unsigned int column ); 502 503 // drag & drop helper methods 504 wxDataFormat GetDnDDataFormat(wxDataObjectComposite* dataObjects); 505 wxDataObjectComposite* GetDnDDataObjects(NSData* dataObject) const; 506 507 // Cocoa-specific helpers 508 id GetItemAtRow(int row) const; 509 510 private: 511 void InitOutlineView(long style); 512 513 wxCocoaOutlineDataSource* m_DataSource; 514 515 wxCocoaOutlineView* m_OutlineView; 516 }; 517 518 #endif // _WX_DATAVIEWCTRL_COCOOA_H_ 519