]>
Commit | Line | Data |
---|---|---|
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 | ||
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 int GetSelections(wxDataViewItemArray& sel) const; | |
477 | virtual bool IsSelected(const wxDataViewItem& item) const; | |
478 | virtual void Select(const wxDataViewItem& item); | |
479 | virtual void SelectAll(); | |
480 | virtual void Unselect(const wxDataViewItem& item); | |
481 | virtual void UnselectAll(); | |
482 | ||
483 | // | |
484 | // sorting related methods | |
485 | // | |
486 | virtual wxDataViewColumn* GetSortingColumn () const; | |
487 | virtual void Resort(); | |
488 | ||
489 | // | |
490 | // other methods (inherited from wxDataViewWidgetImpl) | |
491 | // | |
492 | virtual void DoSetIndent(int indent); | |
493 | virtual void HitTest(const wxPoint& point, | |
494 | wxDataViewItem& item, | |
495 | wxDataViewColumn*& columnPtr) const; | |
496 | virtual void SetRowHeight(const wxDataViewItem& item, unsigned int height); | |
497 | virtual void OnSize(); | |
498 | ||
499 | // drag & drop helper methods | |
500 | wxDataFormat GetDnDDataFormat(wxDataObjectComposite* dataObjects); | |
501 | wxDataObjectComposite* GetDnDDataObjects(NSData* dataObject) const; | |
502 | ||
503 | // Cocoa-specific helpers | |
504 | id GetItemAtRow(int row) const; | |
505 | ||
506 | private: | |
507 | void InitOutlineView(long style); | |
508 | ||
509 | wxCocoaOutlineDataSource* m_DataSource; | |
510 | ||
511 | wxCocoaOutlineView* m_OutlineView; | |
512 | }; | |
513 | ||
514 | #endif // _WX_DATAVIEWCTRL_COCOOA_H_ |