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