using statically allocated font objects for speedup
[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 = m_DataViewCtrlPtr->GetDataViewPeer()->Add(parent,item);
101 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 = m_DataViewCtrlPtr->GetDataViewPeer()->Add(parent,items);
112 // adjust row heights:
113 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(GetOwner() != NULL,false,_("Owner not initialized."));
122 if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(item),item))
123 {
124 // sent the equivalent wxWidget event:
125 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,m_DataViewCtrlPtr->GetId());
126
127 dataViewEvent.SetEventObject(m_DataViewCtrlPtr);
128 dataViewEvent.SetItem(item);
129 // sent the equivalent wxWidget event:
130 m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
131 // row height may have to be adjusted:
132 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,m_DataViewCtrlPtr->GetId());
145
146
147 dataViewEvent.SetEventObject(m_DataViewCtrlPtr);
148 for (size_t indexItem=0; indexItem<noOfItems; ++indexItem)
149 if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(items[indexItem]),items[indexItem]))
150 {
151 // send for all changed items a wxWidget event:
152 dataViewEvent.SetItem(items[indexItem]);
153 m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
154 }
155 else
156 return false;
157 // if this location is reached all items have been updated:
158 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 m_DataViewCtrlPtr->SetDeleting(true);
174 noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,item);
175 // enable automatic updating again:
176 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 m_DataViewCtrlPtr->SetDeleting(true);
191 // delete all specified items:
192 noFailureFlag = m_DataViewCtrlPtr->GetDataViewPeer()->Remove(parent,items);
193 // enable automatic updating again:
194 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(GetOwner() != NULL,false,_("Owner not initialized."));
203 if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(item),item))
204 {
205 wxDataViewEvent dataViewEvent(wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED,m_DataViewCtrlPtr->GetId());
206
207 dataViewEvent.SetEventObject(m_DataViewCtrlPtr);
208 dataViewEvent.SetColumn(col);
209 dataViewEvent.SetItem(item);
210 // send the equivalent wxWidget event:
211 m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent);
212 // done
213 return true;
214 }
215 else
216 return false;
217 }
218
219 bool wxOSXDataViewModelNotifier::Cleared()
220 {
221 return m_DataViewCtrlPtr->GetDataViewPeer()->Reload();
222 }
223
224 void wxOSXDataViewModelNotifier::Resort()
225 {
226 m_DataViewCtrlPtr->GetDataViewPeer()->Resort();
227 }
228
229 void wxOSXDataViewModelNotifier::AdjustRowHeight(wxDataViewItem const& item)
230 {
231 if ((m_DataViewCtrlPtr->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) != 0)
232 {
233 wxDataViewModel *model = GetOwner();
234
235 int height = 20; // TODO find out standard height
236 unsigned int num = m_DataViewCtrlPtr->GetColumnCount();
237 unsigned int col;
238 for (col = 0; col < num; col++)
239 {
240 wxDataViewColumn* column(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 m_DataViewCtrlPtr->GetDataViewPeer()->SetRowHeight(item,height);
256 }
257 }
258
259 void wxOSXDataViewModelNotifier::AdjustRowHeights(wxDataViewItemArray const& items)
260 {
261 if ((m_DataViewCtrlPtr->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) != 0)
262 {
263 size_t const noOfItems = items.GetCount();
264
265 wxDataViewModel *model = 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 = m_DataViewCtrlPtr->GetColumnCount();
271 unsigned int col;
272
273 for (col = 0; col < num; col++)
274 {
275 wxDataViewColumn* column(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 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()
302 {
303 delete m_DCPtr;
304 }
305
306 wxDC* wxDataViewCustomRenderer::GetDC()
307 {
308 if ((m_DCPtr == NULL) && (GetOwner() != NULL) && (GetOwner()->GetOwner() != NULL))
309 m_DCPtr = new wxClientDC(GetOwner()->GetOwner());
310 return m_DCPtr;
311 }
312
313 void wxDataViewCustomRenderer::SetDC(wxDC* newDCPtr)
314 {
315 delete m_DCPtr;
316 m_DCPtr = newDCPtr;
317 }
318
319 //-----------------------------------------------------------------------------
320 // wxDataViewCtrl
321 //-----------------------------------------------------------------------------
322
323 wxDataViewCtrl::~wxDataViewCtrl()
324 {
325 ClearColumns();
326 }
327
328 void wxDataViewCtrl::Init()
329 {
330 m_CustomRendererPtr = NULL;
331 m_Deleting = false;
332 m_macIsUserPane = false;
333 m_cgContext = NULL;
334 }
335
336 bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator )
337 {
338 if (!(wxControl::Create(parent,id,pos,size,style & ~(wxHSCROLL | wxVSCROLL),validator)))
339 return false;
340 m_peer = ::CreateDataView(this,parent,id,pos,size,style,GetExtraStyle());
341
342 MacPostControlCreate(pos,size);
343
344 return true;
345 }
346
347 bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
348 {
349 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer());
350
351
352 wxCHECK_MSG(dataViewWidgetPtr != NULL,false,_("Pointer to native control must not be NULL."));
353 if (wxDataViewCtrlBase::AssociateModel(model) && dataViewWidgetPtr->AssociateModel(model))
354 {
355 if (model != NULL)
356 model->AddNotifier(new wxOSXDataViewModelNotifier(this));
357 return true;
358 }
359 else
360 return false;
361 }
362
363 bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
364 {
365 return wxDataViewCtrl::InsertColumn( GetColumnCount(), columnPtr );
366 }
367
368 bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
369 {
370 return wxDataViewCtrl::InsertColumn( 0, columnPtr );
371 }
372
373 bool wxDataViewCtrl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr)
374 {
375 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer());
376
377 // first, some error checking:
378 wxCHECK_MSG(dataViewWidgetPtr != NULL, false,_("Pointer to native control must not be NULL."));
379 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
380 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
381 wxCHECK_MSG(GetModel() != NULL, false,_("No model associated with control."));
382 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
383 (columnPtr->GetModelColumn() < GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
384
385 // add column to wxWidget's internal structure:
386 if (wxDataViewCtrlBase::InsertColumn(pos,columnPtr))
387 {
388 m_ColumnPtrs.Add(columnPtr);
389 // if the insertion in the native control is successful the rest can also be initialized:
390 if (dataViewWidgetPtr->InsertColumn(pos,columnPtr))
391 {
392 // make sure that the data is up-to-date...
393 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
394 // otherwise ask the control to 'update' the data in the newly appended column:
395 if (GetColumnCount() == 1)
396 SetExpanderColumn(columnPtr);
397 // done:
398 return true;
399 }
400 else
401 {
402 // clean-up:
403 m_ColumnPtrs.Remove(columnPtr);
404 delete columnPtr;
405 // and send a message in debug mode:
406 wxFAIL_MSG(_("Column could not be added to native control."));
407 // failed:
408 return false;
409 }
410 }
411 else
412 {
413 // clean-up:
414 delete columnPtr;
415 wxFAIL_MSG(_("Could not add column to internal structures."));
416 // failed:
417 return false;
418 }
419 }
420
421 bool wxDataViewCtrl::ClearColumns()
422 {
423 if (GetDataViewPeer()->ClearColumns())
424 {
425 WX_CLEAR_ARRAY(m_ColumnPtrs);
426 return true;
427 }
428 else
429 return false;
430 }
431
432 bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
433 {
434 if (GetDataViewPeer()->DeleteColumn(columnPtr))
435 {
436 m_ColumnPtrs.Remove(columnPtr);
437 delete columnPtr;
438 return true;
439 }
440 else
441 return false;
442 }
443
444 wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
445 {
446 return GetDataViewPeer()->GetColumn(pos);
447 }
448
449 unsigned int wxDataViewCtrl::GetColumnCount() const
450 {
451 return m_ColumnPtrs.GetCount();
452 }
453
454 int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
455 {
456 return GetDataViewPeer()->GetColumnPosition(columnPtr);
457 }
458
459 void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
460 {
461 GetDataViewPeer()->Collapse(item);
462 }
463
464 void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
465 {
466 if (item.IsOk())
467 {
468 ExpandAncestors(item); // make sure that the item exists in the control
469 GetDataViewPeer()->EnsureVisible(item,columnPtr);
470 }
471 }
472
473 void wxDataViewCtrl::Expand(wxDataViewItem const& item)
474 {
475 return GetDataViewPeer()->Expand(item);
476 }
477
478 bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const
479 {
480 return (item.IsOk() && GetDataViewPeer()->IsExpanded(item));
481 }
482
483 wxDataViewColumn* wxDataViewCtrl::GetSortingColumn() const
484 {
485 return GetDataViewPeer()->GetSortingColumn();
486 }
487
488 unsigned int wxDataViewCtrl::GetCount() const
489 {
490 return GetDataViewPeer()->GetCount();
491 }
492
493 wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
494 {
495 if (item.IsOk() && (columnPtr != NULL))
496 return GetDataViewPeer()->GetRectangle(item,columnPtr);
497 else
498 return wxRect();
499 }
500
501 wxDataViewItem wxDataViewCtrl::GetSelection() const
502 {
503 wxDataViewItemArray itemIDs;
504
505
506 if (GetDataViewPeer()->GetSelections(itemIDs) > 0)
507 return itemIDs[0];
508 else
509 return wxDataViewItem();
510 }
511
512 int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
513 {
514 return GetDataViewPeer()->GetSelections(sel);
515 }
516
517 void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
518 {
519 return GetDataViewPeer()->HitTest(point,item,columnPtr);
520 }
521
522 bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
523 {
524 return GetDataViewPeer()->IsSelected(item);
525 }
526
527 void wxDataViewCtrl::Select(wxDataViewItem const& item)
528 {
529 if (item.IsOk())
530 {
531 ExpandAncestors(item); // make sure that the item exists in the control
532 GetDataViewPeer()->Select(item);
533 }
534 }
535
536 void wxDataViewCtrl::SelectAll()
537 {
538 GetDataViewPeer()->SelectAll();
539 }
540
541 void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
542 {
543 size_t const noOfSelections = sel.GetCount();
544
545 size_t i;
546
547 wxDataViewItem last_parent;
548
549
550 // make sure that all to be selected items are visible in the control:
551 for (i = 0; i < noOfSelections; i++)
552 {
553 wxDataViewItem item = sel[i];
554 wxDataViewItem parent = GetModel()->GetParent( item );
555
556 if (parent.IsOk() && (parent != last_parent))
557 ExpandAncestors(item);
558 last_parent = parent;
559 }
560
561 // finally select the items:
562 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer()); // variable definition for abbreviational purposes
563
564 for (i=0; i<noOfSelections; ++i)
565 dataViewWidgetPtr->Select(sel[i]);
566 }
567
568 void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
569 {
570 if (item.IsOk())
571 GetDataViewPeer()->Unselect(item);
572 }
573
574 void wxDataViewCtrl::UnselectAll()
575 {
576 GetDataViewPeer()->UnselectAll();
577 }
578
579 //
580 // implementation
581 //
582 wxDataViewWidgetImpl* wxDataViewCtrl::GetDataViewPeer() const
583 {
584 return dynamic_cast<wxDataViewWidgetImpl*>(GetPeer());
585 }
586
587 void wxDataViewCtrl::AddChildren(wxDataViewItem const& parentItem)
588 {
589 int noOfChildren;
590
591 wxDataViewItemArray items;
592
593
594 wxCHECK_RET(GetModel() != NULL,_("Model pointer not initialized."));
595 noOfChildren = GetModel()->GetChildren(parentItem,items);
596 (void) GetModel()->ItemsAdded(parentItem,items);
597 }
598
599 void wxDataViewCtrl::FinishCustomItemEditing()
600 {
601 if (GetCustomRendererItem().IsOk())
602 {
603 GetCustomRendererPtr()->FinishEditing();
604 SetCustomRendererItem(wxDataViewItem());
605 SetCustomRendererPtr (NULL);
606 }
607 }
608
609 /*static*/
610 wxVisualAttributes
611 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
612 {
613 wxVisualAttributes attr;
614
615 attr.colFg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
616 attr.colBg = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX );
617 static wxFont font = wxFont(wxOSX_SYSTEM_FONT_VIEWS);
618 attr.font = font;
619
620 return attr;
621 }
622
623 // inherited methods from wxDataViewCtrlBase
624 void wxDataViewCtrl::DoSetExpanderColumn()
625 {
626 if (GetExpanderColumn() != NULL)
627 GetDataViewPeer()->DoSetExpanderColumn(GetExpanderColumn());
628 }
629
630 void wxDataViewCtrl::DoSetIndent()
631 {
632 GetDataViewPeer()->DoSetIndent(GetIndent());
633 }
634
635 // event handling:
636 void wxDataViewCtrl::OnSize(wxSizeEvent& event)
637 {
638 unsigned int const noOfColumns = GetColumnCount();
639
640
641 // reset DC of all custom renderers because DC has changed:
642 for (unsigned int i=0; i<noOfColumns; ++i)
643 {
644 wxDataViewColumn* dataViewColumnPtr(GetColumn(i));
645
646 if (dataViewColumnPtr != NULL)
647 {
648 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
649
650 if (dataViewCustomRendererPtr != NULL)
651 dataViewCustomRendererPtr->SetDC(NULL);
652 }
653 }
654
655 // update the layout of the native control after a size event:
656 GetDataViewPeer()->OnSize();
657
658 event.Skip();
659 }
660
661 wxSize wxDataViewCtrl::DoGetBestSize() const
662 {
663 wxSize best = wxControl::DoGetBestSize();
664 best.y = 80;
665
666 return best;
667 }
668
669 void wxDataViewCtrl::OnMouse(wxMouseEvent& event)
670 {
671 event.Skip();
672
673 if (GetModel() == NULL)
674 return;
675
676 #if 0
677 // Doesn't compile anymore
678 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(m_peer));
679
680 int NoOfChildren;
681 wxDataViewItemArray items;
682 NoOfChildren = GetModel()->GetChildren( wxDataViewItem(), items);
683 if (NoOfChildren == 0)
684 return;
685 wxDataViewItem firstChild = items[0];
686
687 UInt16 headerHeight = 0;
688 MacDataViewListCtrlPtr->GetHeaderButtonHeight(&headerHeight);
689
690
691 if (event.GetY() < headerHeight)
692 {
693 unsigned int col_count = GetColumnCount();
694 unsigned int col;
695 for (col = 0; col < col_count; col++)
696 {
697 wxDataViewColumn *column = GetColumn( col );
698 if (column->IsHidden())
699 continue;
700
701 Rect itemrect;
702 ::GetDataBrowserItemPartBounds( MacDataViewListCtrlPtr->GetControlRef(),
703 reinterpret_cast<DataBrowserItemID>(firstChild.GetID()), column->GetPropertyID(),
704 kDataBrowserPropertyEnclosingPart, &itemrect );
705
706 if (abs( event.GetX() - itemrect.right) < 3)
707 {
708 if (column->GetFlags() & wxDATAVIEW_COL_RESIZABLE)
709 SetCursor( wxCursor( wxCURSOR_SIZEWE ) );
710 else
711 SetCursor( *wxSTANDARD_CURSOR );
712 return;
713 }
714 }
715
716 }
717
718 SetCursor( *wxSTANDARD_CURSOR );
719 #endif
720 }
721
722 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
723
724 BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
725 EVT_SIZE(wxDataViewCtrl::OnSize)
726 EVT_MOTION(wxDataViewCtrl::OnMouse)
727 END_EVENT_TABLE()
728
729 #endif // (wxUSE_DATAVIEWCTRL != 0) && (!defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0))
730