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