]> git.saurik.com Git - wxWidgets.git/blob - src/osx/dataview_osx.cpp
fix memory leak in SetColFormat() if the column already had an attribute (closes...
[wxWidgets.git] / src / osx / dataview_osx.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/dataview_osx.cpp
3 // Purpose: wxDataViewCtrl native mac implementation
4 // Author:
5 // Id: $Id: dataview_osx.cpp 58317 2009-01-27
6 // Copyright: (c) 2009
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if (wxUSE_DATAVIEWCTRL != 0) && (!defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0))
14
15 #include <limits>
16
17 #ifndef WX_PRECOMP
18 #include "wx/timer.h"
19 #include "wx/settings.h"
20 #include "wx/dcclient.h"
21 #include "wx/icon.h"
22 #endif
23
24 #include "wx/osx/core/dataview.h"
25 #include "wx/osx/private.h"
26 #include "wx/renderer.h"
27
28 // ============================================================================
29 // Helper functions for dataviewe implementation on OSX
30 // ============================================================================
31 wxString ConcatenateDataViewItemValues(wxDataViewCtrl const* dataViewCtrlPtr, wxDataViewItem const& dataViewItem)
32 {
33 wxString dataString; // contains the TAB concatenated data
34
35
36 for (size_t i=0; i<dataViewCtrlPtr->GetColumnCount(); i++)
37 {
38 // variable definition:
39 wxVariant dataValue;
40
41 dataViewCtrlPtr->GetModel()->GetValue(dataValue,dataViewItem,dataViewCtrlPtr->GetColumn(i)->GetModelColumn());
42 if (i > 0)
43 dataString << wxT('\t');
44 dataString << dataValue.MakeString();
45 }
46 return dataString;
47 }
48
49 // ============================================================================
50 // wxOSXDataViewModelNotifier
51 // ============================================================================
52 class wxOSXDataViewModelNotifier : public wxDataViewModelNotifier
53 {
54 public:
55 //
56 // constructors / destructor
57 //
58 wxOSXDataViewModelNotifier(wxDataViewCtrl* initDataViewCtrlPtr);
59
60 //
61 // inherited methods from wxDataViewModelNotifier
62 //
63 virtual bool ItemAdded (wxDataViewItem const &parent, wxDataViewItem const &item);
64 virtual bool ItemsAdded (wxDataViewItem const& parent, wxDataViewItemArray const& items);
65 virtual bool ItemChanged (wxDataViewItem const& item);
66 virtual bool ItemsChanged(wxDataViewItemArray const& items);
67 virtual bool ItemDeleted (wxDataViewItem const& parent, wxDataViewItem const& item);
68 virtual bool ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items);
69 virtual bool ValueChanged(wxDataViewItem const& item, unsigned int col);
70 virtual bool Cleared();
71 virtual void Resort();
72
73 protected:
74 // if the dataview control can have a variable row height this method sets the dataview's control row height of
75 // the passed item to the maximum value occupied by the item in all columns
76 void AdjustRowHeight(wxDataViewItem const& item);
77 // ... and the same method for a couple of items:
78 void AdjustRowHeights(wxDataViewItemArray const& items);
79
80 private:
81 wxDataViewCtrl* m_DataViewCtrlPtr;
82 };
83
84 //
85 // constructors / destructor
86 //
87 wxOSXDataViewModelNotifier::wxOSXDataViewModelNotifier(wxDataViewCtrl* initDataViewCtrlPtr)
88 :m_DataViewCtrlPtr(initDataViewCtrlPtr)
89 {
90 if (initDataViewCtrlPtr == NULL)
91 wxFAIL_MSG(_("Pointer to dataview control must not be NULL"));
92 }
93
94 bool wxOSXDataViewModelNotifier::ItemAdded(wxDataViewItem const& parent, wxDataViewItem const& item)
95 {
96 bool noFailureFlag;
97
98
99 wxCHECK_MSG(item.IsOk(),false,_("Added item is invalid."));
100 noFailureFlag = this->m_DataViewCtrlPtr->GetDataViewPeer()->Add(parent,item);
101 this->AdjustRowHeight(item);
102 return noFailureFlag;
103 }
104
105 bool wxOSXDataViewModelNotifier::ItemsAdded(wxDataViewItem const& parent, wxDataViewItemArray const& items)
106 {
107 bool noFailureFlag;
108
109
110 // insert all valid items into control:
111 noFailureFlag = this->m_DataViewCtrlPtr->GetDataViewPeer()->Add(parent,items);
112 // adjust row heights:
113 this->AdjustRowHeights(items);
114 // done:
115 return noFailureFlag;
116 }
117
118 bool wxOSXDataViewModelNotifier::ItemChanged(wxDataViewItem const& item)
119 {
120 wxCHECK_MSG(item.IsOk(), false,_("Changed item is invalid."));
121 wxCHECK_MSG(this->GetOwner() != NULL,false,_("Owner not initialized."));
122 if (this->m_DataViewCtrlPtr->GetDataViewPeer()->Update(this->GetOwner()->GetParent(item),item))
123 {
124 // sent the equivalent wxWidget event:
125 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,this->m_DataViewCtrlPtr->GetId());
126
127 dataViewEvent.SetEventObject(this->m_DataViewCtrlPtr);
128 dataViewEvent.SetItem(item);
129 // sent the equivalent wxWidget event:
130 this->m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
131 // row height may have to be adjusted:
132 this->AdjustRowHeight(item);
133 // done
134 return true;
135 }
136 else
137 return false;
138 }
139
140 bool wxOSXDataViewModelNotifier::ItemsChanged(wxDataViewItemArray const& items)
141 {
142 size_t const noOfItems = items.GetCount();
143
144 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,this->m_DataViewCtrlPtr->GetId());
145
146
147 dataViewEvent.SetEventObject(this->m_DataViewCtrlPtr);
148 for (size_t indexItem=0; indexItem<noOfItems; ++indexItem)
149 if (this->m_DataViewCtrlPtr->GetDataViewPeer()->Update(this->GetOwner()->GetParent(items[indexItem]),items[indexItem]))
150 {
151 // send for all changed items a wxWidget event:
152 dataViewEvent.SetItem(items[indexItem]);
153 this->m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
154 }
155 else
156 return false;
157 // if this location is reached all items have been updated:
158 this->AdjustRowHeights(items);
159 // done:
160 return true;
161 }
162
163 bool wxOSXDataViewModelNotifier::ItemDeleted(wxDataViewItem const& parent, wxDataViewItem const& item)
164 {
165 bool noFailureFlag;
166
167
168 wxCHECK_MSG(item.IsOk(),false,_("To be deleted item is invalid."));
169 // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have
170 // not to be identical because the being edited item might be below the passed item in the hierarchy);
171 // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
172 // has been started and that variables can currently not be updated even when requested by the system:
173 this->m_DataViewCtrlPtr->SetDeleting(true);
174 noFailureFlag = this->m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,item);
175 // enable automatic updating again:
176 this->m_DataViewCtrlPtr->SetDeleting(false);
177 // done:
178 return noFailureFlag;
179 }
180
181 bool wxOSXDataViewModelNotifier::ItemsDeleted(wxDataViewItem const& parent, wxDataViewItemArray const& items)
182 {
183 bool noFailureFlag;
184
185
186 // when this method is called and currently an item is being edited this item may have already been deleted in the model (the passed item and the being edited item have
187 // not to be identical because the being edited item might be below the passed item in the hierarchy);
188 // to prevent the control trying to ask the model to update an already deleted item the control is informed that currently a deleting process
189 // has been started and that variables can currently not be updated even when requested by the system:
190 this->m_DataViewCtrlPtr->SetDeleting(true);
191 // delete all specified items:
192 noFailureFlag = this->m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,items);
193 // enable automatic updating again:
194 this->m_DataViewCtrlPtr->SetDeleting(false);
195 // done:
196 return noFailureFlag;
197 }
198
199 bool wxOSXDataViewModelNotifier::ValueChanged(wxDataViewItem const& item, unsigned int col)
200 {
201 wxCHECK_MSG(item.IsOk(), false,_("Passed item is invalid."));
202 wxCHECK_MSG(this->GetOwner() != NULL,false,_("Owner not initialized."));
203 if (this->m_DataViewCtrlPtr->GetDataViewPeer()->Update(this->GetOwner()->GetParent(item),item))
204 {
205 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,this->m_DataViewCtrlPtr->GetId());
206
207 dataViewEvent.SetEventObject(this->m_DataViewCtrlPtr);
208 dataViewEvent.SetColumn(col);
209 dataViewEvent.SetItem(item);
210 // send the equivalent wxWidget event:
211 this->m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
212 // done
213 return true;
214 }
215 else
216 return false;
217 }
218
219 bool wxOSXDataViewModelNotifier::Cleared()
220 {
221 return this->m_DataViewCtrlPtr->GetDataViewPeer()->Reload();
222 }
223
224 void wxOSXDataViewModelNotifier::Resort()
225 {
226 this->m_DataViewCtrlPtr->GetDataViewPeer()->Resort();
227 }
228
229 void wxOSXDataViewModelNotifier::AdjustRowHeight(wxDataViewItem const& item)
230 {
231 if ((this->m_DataViewCtrlPtr->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) != 0)
232 {
233 wxDataViewModel *model = this->GetOwner();
234
235 int height = 20; // TODO find out standard height
236 unsigned int num = this->m_DataViewCtrlPtr->GetColumnCount();
237 unsigned int col;
238 for (col = 0; col < num; col++)
239 {
240 wxDataViewColumn* column(this->m_DataViewCtrlPtr->GetColumnPtr(col));
241
242 if (!(column->IsHidden()))
243 {
244 wxDataViewCustomRenderer *renderer = dynamic_cast<wxDataViewCustomRenderer*>(column->GetRenderer());
245 if (renderer)
246 {
247 wxVariant value;
248 model->GetValue( value, item, column->GetModelColumn() );
249 renderer->SetValue( value );
250 height = wxMax( height, renderer->GetSize().y );
251 }
252 }
253 }
254 if (height > 20)
255 this->m_DataViewCtrlPtr->GetDataViewPeer()->SetRowHeight(item,height);
256 }
257 }
258
259 void wxOSXDataViewModelNotifier::AdjustRowHeights(wxDataViewItemArray const& items)
260 {
261 if ((this->m_DataViewCtrlPtr->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) != 0)
262 {
263 size_t const noOfItems = items.GetCount();
264
265 wxDataViewModel *model = this->GetOwner();
266
267 for (size_t itemIndex=0; itemIndex<noOfItems; ++itemIndex)
268 {
269 int height = 20; // TODO find out standard height
270 unsigned int num = this->m_DataViewCtrlPtr->GetColumnCount();
271 unsigned int col;
272
273 for (col = 0; col < num; col++)
274 {
275 wxDataViewColumn* column(this->m_DataViewCtrlPtr->GetColumnPtr(col));
276
277 if (!(column->IsHidden()))
278 {
279 wxDataViewCustomRenderer *renderer = dynamic_cast<wxDataViewCustomRenderer*>(column->GetRenderer());
280 if (renderer)
281 {
282 wxVariant value;
283 model->GetValue( value, items[itemIndex], column->GetModelColumn() );
284 renderer->SetValue( value );
285 height = wxMax( height, renderer->GetSize().y );
286 }
287 }
288 }
289 if (height > 20)
290 this->m_DataViewCtrlPtr->GetDataViewPeer()->SetRowHeight(items[itemIndex],height);
291 }
292 }
293 }
294
295 // ---------------------------------------------------------
296 // wxDataViewCustomRenderer
297 // The constructor, the implementation macro and environment
298 // dependent methods can be found in the environment's
299 // source file.
300 // ---------------------------------------------------------
301 wxDataViewCustomRenderer::~wxDataViewCustomRenderer(void)
302 {
303 delete this->m_DCPtr;
304 }
305
306 void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxRect cell, wxDC *dc, int state )
307 {
308 wxDataViewCtrl *view = GetOwner()->GetOwner();
309
310 wxColour col = (state & wxDATAVIEW_CELL_SELECTED) ? *wxWHITE : view->GetForegroundColour();
311 dc->SetTextForeground(col);
312 dc->DrawText( text, cell.x + xoffset, cell.y + ((cell.height - dc->GetCharHeight()) / 2));
313 }
314
315 wxDC* wxDataViewCustomRenderer::GetDC()
316 {
317 if ((this->m_DCPtr == NULL) && (this->GetOwner() != NULL) && (this->GetOwner()->GetOwner() != NULL))
318 this->m_DCPtr = new wxClientDC(this->GetOwner()->GetOwner());
319 return this->m_DCPtr;
320 }
321
322 void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr)
323 {
324 delete m_DCPtr;
325 m_DCPtr = newDCPtr;
326 }
327
328 // ---------------------------------------------------------
329 // wxDataViewTextRendererAttr
330 // ---------------------------------------------------------
331 wxDataViewTextRendererAttr::wxDataViewTextRendererAttr(wxString const& varianttype, wxDataViewCellMode mode, int align)
332 :wxDataViewTextRenderer(varianttype,mode,align)
333 {
334 }
335
336 IMPLEMENT_CLASS(wxDataViewTextRendererAttr,wxDataViewTextRenderer)
337
338 //-----------------------------------------------------------------------------
339 // wxDataViewCtrl
340 //-----------------------------------------------------------------------------
341
342 wxDataViewCtrl::~wxDataViewCtrl()
343 {
344 this->ClearColumns();
345 }
346
347 void wxDataViewCtrl::Init()
348 {
349 m_CustomRendererPtr = NULL;
350 m_Deleting = false;
351 m_macIsUserPane = false;
352 m_cgContext = NULL;
353 }
354
355 bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
356 {
357 if (!(this->wxControl::Create(parent,id,pos,size,style & ~(wxHSCROLL | wxVSCROLL),validator)))
358 return false;
359 m_peer = ::CreateDataView(this,parent,id,pos,size,style,this->GetExtraStyle());
360
361 this->MacPostControlCreate(pos,size);
362
363 return true;
364 }
365
366 bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
367 {
368 wxDataViewWidgetImpl* dataViewWidgetPtr(this->GetDataViewPeer());
369
370
371 wxCHECK_MSG(dataViewWidgetPtr != NULL,false,_("Pointer to native control must not be NULL."));
372 if (wxDataViewCtrlBase::AssociateModel(model) && dataViewWidgetPtr->AssociateModel(model))
373 {
374 if (model != NULL)
375 model->AddNotifier(new wxOSXDataViewModelNotifier(this));
376 return true;
377 }
378 else
379 return false;
380 }
381
382 bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
383 {
384 return wxDataViewCtrl::InsertColumn( GetColumnCount(), columnPtr );
385 }
386
387 bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
388 {
389 return wxDataViewCtrl::InsertColumn( 0, columnPtr );
390 }
391
392 bool wxDataViewCtrl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr)
393 {
394 wxDataViewWidgetImpl* dataViewWidgetPtr(this->GetDataViewPeer());
395
396 // first, some error checking:
397 wxCHECK_MSG(dataViewWidgetPtr != NULL, false,_("Pointer to native control must not be NULL."));
398 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
399 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
400 wxCHECK_MSG(this->GetModel() != NULL, false,_("No model associated with control."));
401 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
402 (columnPtr->GetModelColumn() < this->GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
403
404 // add column to wxWidget's internal structure:
405 if (this->wxDataViewCtrlBase::InsertColumn(pos,columnPtr))
406 {
407 this->m_ColumnPtrs.Add(columnPtr);
408 // if the insertion in the native control is successful the rest can also be initialized:
409 if (dataViewWidgetPtr->InsertColumn(pos,columnPtr))
410 {
411 // make sure that the data is up-to-date...
412 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
413 // otherwise ask the control to 'update' the data in the newly appended column:
414 if (this->GetColumnCount() == 1)
415 this->SetExpanderColumn(columnPtr);
416 // done:
417 return true;
418 }
419 else
420 {
421 // clean-up:
422 this->m_ColumnPtrs.Remove(columnPtr);
423 delete columnPtr;
424 // and send a message in debug mode:
425 wxFAIL_MSG(_("Column could not be added to native control."));
426 // failed:
427 return false;
428 }
429 }
430 else
431 {
432 // clean-up:
433 delete columnPtr;
434 wxFAIL_MSG(_("Could not add column to internal structures."));
435 // failed:
436 return false;
437 }
438 }
439
440 bool wxDataViewCtrl::ClearColumns()
441 {
442 if (this->GetDataViewPeer()->ClearColumns())
443 {
444 WX_CLEAR_ARRAY(this->m_ColumnPtrs);
445 return true;
446 }
447 else
448 return false;
449 }
450
451 bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
452 {
453 if (this->GetDataViewPeer()->DeleteColumn(columnPtr))
454 {
455 this->m_ColumnPtrs.Remove(columnPtr);
456 delete columnPtr;
457 return true;
458 }
459 else
460 return false;
461 }
462
463 wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
464 {
465 return this->GetDataViewPeer()->GetColumn(pos);
466 }
467
468 unsigned int wxDataViewCtrl::GetColumnCount() const
469 {
470 return this->m_ColumnPtrs.GetCount();
471 }
472
473 int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
474 {
475 return this->GetDataViewPeer()->GetColumnPosition(columnPtr);
476 }
477
478 void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
479 {
480 this->GetDataViewPeer()->Collapse(item);
481 }
482
483 void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
484 {
485 if (item.IsOk())
486 {
487 this->ExpandAncestors(item); // make sure that the item exists in the control
488 this->GetDataViewPeer()->EnsureVisible(item,columnPtr);
489 }
490 }
491
492 void wxDataViewCtrl::Expand(wxDataViewItem const& item)
493 {
494 return this->GetDataViewPeer()->Expand(item);
495 }
496
497 bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const
498 {
499 return (item.IsOk() && this->GetDataViewPeer()->IsExpanded(item));
500 }
501
502 wxDataViewColumn* wxDataViewCtrl::GetSortingColumn() const
503 {
504 return this->GetDataViewPeer()->GetSortingColumn();
505 }
506
507 unsigned int wxDataViewCtrl::GetCount() const
508 {
509 return this->GetDataViewPeer()->GetCount();
510 }
511
512 wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
513 {
514 if (item.IsOk() && (columnPtr != NULL))
515 return this->GetDataViewPeer()->GetRectangle(item,columnPtr);
516 else
517 return wxRect();
518 }
519
520 wxDataViewItem wxDataViewCtrl::GetSelection() const
521 {
522 wxDataViewItemArray itemIDs;
523
524
525 if (this->GetDataViewPeer()->GetSelections(itemIDs) > 0)
526 return itemIDs[0];
527 else
528 return wxDataViewItem();
529 }
530
531 int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
532 {
533 return this->GetDataViewPeer()->GetSelections(sel);
534 }
535
536 void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
537 {
538 return this->GetDataViewPeer()->HitTest(point,item,columnPtr);
539 }
540
541 bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
542 {
543 return this->GetDataViewPeer()->IsSelected(item);
544 }
545
546 void wxDataViewCtrl::Select(wxDataViewItem const& item)
547 {
548 if (item.IsOk())
549 {
550 this->ExpandAncestors(item); // make sure that the item exists in the control
551 this->GetDataViewPeer()->Select(item);
552 }
553 }
554
555 void wxDataViewCtrl::SelectAll(void)
556 {
557 this->GetDataViewPeer()->SelectAll();
558 }
559
560 void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
561 {
562 size_t const noOfSelections = sel.GetCount();
563
564 size_t i;
565
566 wxDataViewItem last_parent;
567
568
569 // make sure that all to be selected items are visible in the control:
570 for (i = 0; i < noOfSelections; i++)
571 {
572 wxDataViewItem item = sel[i];
573 wxDataViewItem parent = this->GetModel()->GetParent( item );
574
575 if (parent.IsOk() && (parent != last_parent))
576 this->ExpandAncestors(item);
577 last_parent = parent;
578 }
579
580 // finally select the items:
581 wxDataViewWidgetImpl* dataViewWidgetPtr(this->GetDataViewPeer()); // variable definition for abbreviational purposes
582
583 for (i=0; i<noOfSelections; ++i)
584 dataViewWidgetPtr->Select(sel[i]);
585 }
586
587 void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
588 {
589 if (item.IsOk())
590 this->GetDataViewPeer()->Unselect(item);
591 }
592
593 void wxDataViewCtrl::UnselectAll(void)
594 {
595 this->GetDataViewPeer()->UnselectAll();
596 }
597
598 //
599 // implementation
600 //
601 wxDataViewWidgetImpl* wxDataViewCtrl::GetDataViewPeer(void) const
602 {
603 return dynamic_cast<wxDataViewWidgetImpl*>(this->GetPeer());
604 }
605
606 void wxDataViewCtrl::AddChildren(wxDataViewItem const& parentItem)
607 {
608 int noOfChildren;
609
610 wxDataViewItemArray items;
611
612
613 wxCHECK_RET(this->GetModel() != NULL,_("Model pointer not initialized."));
614 noOfChildren = this->GetModel()->GetChildren(parentItem,items);
615 (void) this->GetModel()->ItemsAdded(parentItem,items);
616 }
617
618 void wxDataViewCtrl::FinishCustomItemEditing(void)
619 {
620 if (this->GetCustomRendererItem().IsOk())
621 {
622 this->GetCustomRendererPtr()->FinishEditing();
623 this->SetCustomRendererItem(wxDataViewItem());
624 this->SetCustomRendererPtr (NULL);
625 }
626 }
627
628 /*static*/
629 wxVisualAttributes wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
630 {
631 wxVisualAttributes attr;
632
633 attr.colFg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
634 attr.colBg = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX );
635 attr.font.CreateSystemFont(wxOSX_SYSTEM_FONT_VIEWS);
636
637 return attr;
638 }
639
640 // inherited methods from wxDataViewCtrlBase
641 void wxDataViewCtrl::DoSetExpanderColumn()
642 {
643 if (this->GetExpanderColumn() != NULL)
644 this->GetDataViewPeer()->DoSetExpanderColumn(this->GetExpanderColumn());
645 }
646
647 void wxDataViewCtrl::DoSetIndent()
648 {
649 this->GetDataViewPeer()->DoSetIndent(this->GetIndent());
650 }
651
652 // event handling:
653 void wxDataViewCtrl::OnSize(wxSizeEvent& event)
654 {
655 unsigned int const noOfColumns = this->GetColumnCount();
656
657
658 // reset DC of all custom renderers because DC has changed:
659 for (unsigned int i=0; i<noOfColumns; ++i)
660 {
661 wxDataViewColumn* dataViewColumnPtr(this->GetColumn(i));
662
663 if (dataViewColumnPtr != NULL)
664 {
665 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
666
667 if (dataViewCustomRendererPtr != NULL)
668 dataViewCustomRendererPtr->SetDC(NULL);
669 }
670 }
671
672 // update the layout of the native control after a size event:
673 this->GetDataViewPeer()->OnSize();
674
675 event.Skip();
676 }
677
678 wxSize wxDataViewCtrl::DoGetBestSize() const
679 {
680 wxSize best = wxControl::DoGetBestSize();
681 best.y = 80;
682
683 return best;
684 }
685
686 void wxDataViewCtrl::OnMouse(wxMouseEvent& event)
687 {
688 event.Skip();
689
690 if (GetModel() == NULL)
691 return;
692
693 #if 0
694 // Doesn't compile anymore
695 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(m_peer));
696
697 int NoOfChildren;
698 wxDataViewItemArray items;
699 NoOfChildren = GetModel()->GetChildren( wxDataViewItem(), items);
700 if (NoOfChildren == 0)
701 return;
702 wxDataViewItem firstChild = items[0];
703
704 UInt16 headerHeight = 0;
705 MacDataViewListCtrlPtr->GetHeaderButtonHeight(&headerHeight);
706
707
708 if (event.GetY() < headerHeight)
709 {
710 unsigned int col_count = GetColumnCount();
711 unsigned int col;
712 for (col = 0; col < col_count; col++)
713 {
714 wxDataViewColumn *column = GetColumn( col );
715 if (column->IsHidden())
716 continue;
717
718 Rect itemrect;
719 ::GetDataBrowserItemPartBounds( MacDataViewListCtrlPtr->GetControlRef(),
720 reinterpret_cast<DataBrowserItemID>(firstChild.GetID()), column->GetPropertyID(),
721 kDataBrowserPropertyEnclosingPart, &itemrect );
722
723 if (abs( event.GetX() - itemrect.right) < 3)
724 {
725 if (column->GetFlags() & wxDATAVIEW_COL_RESIZABLE)
726 SetCursor( wxCursor( wxCURSOR_SIZEWE ) );
727 else
728 SetCursor( *wxSTANDARD_CURSOR );
729 return;
730 }
731 }
732
733 }
734
735 SetCursor( *wxSTANDARD_CURSOR );
736 #endif
737 }
738
739 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
740
741 BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
742 EVT_SIZE(wxDataViewCtrl::OnSize)
743 EVT_MOTION(wxDataViewCtrl::OnMouse)
744 END_EVENT_TABLE()
745
746 #endif // (wxUSE_DATAVIEWCTRL != 0) && (!defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0))
747