Add wxDataViewCtrl::{Set,Get}CurrentItem().
[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,
337 wxWindowID id,
338 const wxPoint& pos,
339 const wxSize& size,
340 long style,
341 const wxValidator& validator,
342 const wxString& name)
343 {
344 if (!(wxControl::Create(parent,id,pos,size,style,validator,name)))
345 return false;
346 m_peer = ::CreateDataView(this,parent,id,pos,size,style,GetExtraStyle());
347
348 MacPostControlCreate(pos,size);
349
350 return true;
351 }
352
353 bool wxDataViewCtrl::AssociateModel(wxDataViewModel* model)
354 {
355 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer());
356
357
358 wxCHECK_MSG(dataViewWidgetPtr != NULL,false,_("Pointer to native control must not be NULL."));
359 if (wxDataViewCtrlBase::AssociateModel(model) && dataViewWidgetPtr->AssociateModel(model))
360 {
361 if (model != NULL)
362 model->AddNotifier(new wxOSXDataViewModelNotifier(this));
363 return true;
364 }
365 else
366 return false;
367 }
368
369 bool wxDataViewCtrl::AppendColumn(wxDataViewColumn* columnPtr)
370 {
371 return wxDataViewCtrl::InsertColumn( GetColumnCount(), columnPtr );
372 }
373
374 bool wxDataViewCtrl::PrependColumn(wxDataViewColumn* columnPtr)
375 {
376 return wxDataViewCtrl::InsertColumn( 0, columnPtr );
377 }
378
379 bool wxDataViewCtrl::InsertColumn(unsigned int pos, wxDataViewColumn* columnPtr)
380 {
381 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer());
382
383 // first, some error checking:
384 wxCHECK_MSG(dataViewWidgetPtr != NULL, false,_("Pointer to native control must not be NULL."));
385 wxCHECK_MSG(columnPtr != NULL, false,_("Column pointer must not be NULL."));
386 wxCHECK_MSG(columnPtr->GetRenderer() != NULL, false,_("Column does not have a renderer."));
387 wxCHECK_MSG(GetModel() != NULL, false,_("No model associated with control."));
388 wxCHECK_MSG((columnPtr->GetModelColumn() >= 0) &&
389 (columnPtr->GetModelColumn() < GetModel()->GetColumnCount()),false,_("Column's model column has no equivalent in the associated model."));
390
391 // add column to wxWidget's internal structure:
392 if (wxDataViewCtrlBase::InsertColumn(pos,columnPtr))
393 {
394 m_ColumnPtrs.Add(columnPtr);
395 // if the insertion in the native control is successful the rest can also be initialized:
396 if (dataViewWidgetPtr->InsertColumn(pos,columnPtr))
397 {
398 // make sure that the data is up-to-date...
399 // if the newly appended column is the first column add the initial data to the control and mark the column as an expander column,
400 // otherwise ask the control to 'update' the data in the newly appended column:
401 if (GetColumnCount() == 1)
402 SetExpanderColumn(columnPtr);
403 // done:
404 return true;
405 }
406 else
407 {
408 // clean-up:
409 m_ColumnPtrs.Remove(columnPtr);
410 delete columnPtr;
411 // and send a message in debug mode:
412 wxFAIL_MSG(_("Column could not be added to native control."));
413 // failed:
414 return false;
415 }
416 }
417 else
418 {
419 // clean-up:
420 delete columnPtr;
421 wxFAIL_MSG(_("Could not add column to internal structures."));
422 // failed:
423 return false;
424 }
425 }
426
427 bool wxDataViewCtrl::ClearColumns()
428 {
429 if (GetDataViewPeer()->ClearColumns())
430 {
431 WX_CLEAR_ARRAY(m_ColumnPtrs);
432 return true;
433 }
434 else
435 return false;
436 }
437
438 bool wxDataViewCtrl::DeleteColumn(wxDataViewColumn* columnPtr)
439 {
440 if (GetDataViewPeer()->DeleteColumn(columnPtr))
441 {
442 m_ColumnPtrs.Remove(columnPtr);
443 delete columnPtr;
444 return true;
445 }
446 else
447 return false;
448 }
449
450 wxDataViewColumn* wxDataViewCtrl::GetColumn(unsigned int pos) const
451 {
452 return GetDataViewPeer()->GetColumn(pos);
453 }
454
455 unsigned int wxDataViewCtrl::GetColumnCount() const
456 {
457 return m_ColumnPtrs.GetCount();
458 }
459
460 int wxDataViewCtrl::GetColumnPosition(wxDataViewColumn const* columnPtr) const
461 {
462 return GetDataViewPeer()->GetColumnPosition(columnPtr);
463 }
464
465 void wxDataViewCtrl::Collapse(wxDataViewItem const& item)
466 {
467 GetDataViewPeer()->Collapse(item);
468 }
469
470 void wxDataViewCtrl::EnsureVisible(wxDataViewItem const& item, wxDataViewColumn const* columnPtr)
471 {
472 if (item.IsOk())
473 {
474 ExpandAncestors(item); // make sure that the item exists in the control
475 GetDataViewPeer()->EnsureVisible(item,columnPtr);
476 }
477 }
478
479 void wxDataViewCtrl::Expand(wxDataViewItem const& item)
480 {
481 return GetDataViewPeer()->Expand(item);
482 }
483
484 bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const
485 {
486 return (item.IsOk() && GetDataViewPeer()->IsExpanded(item));
487 }
488
489 wxDataViewColumn* wxDataViewCtrl::GetSortingColumn() const
490 {
491 return GetDataViewPeer()->GetSortingColumn();
492 }
493
494 unsigned int wxDataViewCtrl::GetCount() const
495 {
496 return GetDataViewPeer()->GetCount();
497 }
498
499 wxDataViewItem wxDataViewCtrl::DoGetCurrentItem() const
500 {
501 return GetDataViewPeer()->GetCurrentItem();
502 }
503
504 void wxDataViewCtrl::DoSetCurrentItem(const wxDataViewItem& item)
505 {
506 GetDataViewPeer()->SetCurrentItem(item);
507 }
508
509 wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn const* columnPtr) const
510 {
511 if (item.IsOk() && (columnPtr != NULL))
512 return GetDataViewPeer()->GetRectangle(item,columnPtr);
513 else
514 return wxRect();
515 }
516
517 wxDataViewItem wxDataViewCtrl::GetSelection() const
518 {
519 wxDataViewItemArray itemIDs;
520
521
522 if (GetDataViewPeer()->GetSelections(itemIDs) > 0)
523 return itemIDs[0];
524 else
525 return wxDataViewItem();
526 }
527
528 int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const
529 {
530 return GetDataViewPeer()->GetSelections(sel);
531 }
532
533 void wxDataViewCtrl::HitTest(wxPoint const& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const
534 {
535 return GetDataViewPeer()->HitTest(point,item,columnPtr);
536 }
537
538 bool wxDataViewCtrl::IsSelected(wxDataViewItem const& item) const
539 {
540 return GetDataViewPeer()->IsSelected(item);
541 }
542
543 void wxDataViewCtrl::Select(wxDataViewItem const& item)
544 {
545 if (item.IsOk())
546 {
547 ExpandAncestors(item); // make sure that the item exists in the control
548 GetDataViewPeer()->Select(item);
549 }
550 }
551
552 void wxDataViewCtrl::SelectAll()
553 {
554 GetDataViewPeer()->SelectAll();
555 }
556
557 void wxDataViewCtrl::SetSelections(wxDataViewItemArray const& sel)
558 {
559 size_t const noOfSelections = sel.GetCount();
560
561 size_t i;
562
563 wxDataViewItem last_parent;
564
565
566 // make sure that all to be selected items are visible in the control:
567 for (i = 0; i < noOfSelections; i++)
568 {
569 wxDataViewItem item = sel[i];
570 wxDataViewItem parent = GetModel()->GetParent( item );
571
572 if (parent.IsOk() && (parent != last_parent))
573 ExpandAncestors(item);
574 last_parent = parent;
575 }
576
577 // finally select the items:
578 wxDataViewWidgetImpl* dataViewWidgetPtr(GetDataViewPeer()); // variable definition for abbreviational purposes
579
580 for (i=0; i<noOfSelections; ++i)
581 dataViewWidgetPtr->Select(sel[i]);
582 }
583
584 void wxDataViewCtrl::Unselect(wxDataViewItem const& item)
585 {
586 if (item.IsOk())
587 GetDataViewPeer()->Unselect(item);
588 }
589
590 void wxDataViewCtrl::UnselectAll()
591 {
592 GetDataViewPeer()->UnselectAll();
593 }
594
595 //
596 // implementation
597 //
598 wxDataViewWidgetImpl* wxDataViewCtrl::GetDataViewPeer() const
599 {
600 return dynamic_cast<wxDataViewWidgetImpl*>(GetPeer());
601 }
602
603 void wxDataViewCtrl::AddChildren(wxDataViewItem const& parentItem)
604 {
605 int noOfChildren;
606
607 wxDataViewItemArray items;
608
609
610 wxCHECK_RET(GetModel() != NULL,_("Model pointer not initialized."));
611 noOfChildren = GetModel()->GetChildren(parentItem,items);
612 (void) GetModel()->ItemsAdded(parentItem,items);
613 }
614
615 void wxDataViewCtrl::FinishCustomItemEditing()
616 {
617 if (GetCustomRendererItem().IsOk())
618 {
619 GetCustomRendererPtr()->FinishEditing();
620 SetCustomRendererItem(wxDataViewItem());
621 SetCustomRendererPtr (NULL);
622 }
623 }
624
625 /*static*/
626 wxVisualAttributes
627 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
628 {
629 wxVisualAttributes attr;
630
631 attr.colFg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
632 attr.colBg = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX );
633 static wxFont font = wxFont(wxOSX_SYSTEM_FONT_VIEWS);
634 attr.font = font;
635
636 return attr;
637 }
638
639 // inherited methods from wxDataViewCtrlBase
640 void wxDataViewCtrl::DoSetExpanderColumn()
641 {
642 if (GetExpanderColumn() != NULL)
643 GetDataViewPeer()->DoSetExpanderColumn(GetExpanderColumn());
644 }
645
646 void wxDataViewCtrl::DoSetIndent()
647 {
648 GetDataViewPeer()->DoSetIndent(GetIndent());
649 }
650
651 // event handling:
652 void wxDataViewCtrl::OnSize(wxSizeEvent& event)
653 {
654 unsigned int const noOfColumns = GetColumnCount();
655
656
657 // reset DC of all custom renderers because DC has changed:
658 for (unsigned int i=0; i<noOfColumns; ++i)
659 {
660 wxDataViewColumn* dataViewColumnPtr(GetColumn(i));
661
662 if (dataViewColumnPtr != NULL)
663 {
664 wxDataViewCustomRenderer* dataViewCustomRendererPtr(dynamic_cast<wxDataViewCustomRenderer*>(dataViewColumnPtr->GetRenderer()));
665
666 if (dataViewCustomRendererPtr != NULL)
667 dataViewCustomRendererPtr->SetDC(NULL);
668 }
669 }
670
671 // update the layout of the native control after a size event:
672 GetDataViewPeer()->OnSize();
673
674 event.Skip();
675 }
676
677 wxSize wxDataViewCtrl::DoGetBestSize() const
678 {
679 wxSize best = wxControl::DoGetBestSize();
680 best.y = 80;
681
682 return best;
683 }
684
685 void wxDataViewCtrl::OnMouse(wxMouseEvent& event)
686 {
687 event.Skip();
688
689 if (GetModel() == NULL)
690 return;
691
692 #if 0
693 // Doesn't compile anymore
694 wxMacDataViewDataBrowserListViewControlPointer MacDataViewListCtrlPtr(dynamic_cast<wxMacDataViewDataBrowserListViewControlPointer>(m_peer));
695
696 int NoOfChildren;
697 wxDataViewItemArray items;
698 NoOfChildren = GetModel()->GetChildren( wxDataViewItem(), items);
699 if (NoOfChildren == 0)
700 return;
701 wxDataViewItem firstChild = items[0];
702
703 UInt16 headerHeight = 0;
704 MacDataViewListCtrlPtr->GetHeaderButtonHeight(&headerHeight);
705
706
707 if (event.GetY() < headerHeight)
708 {
709 unsigned int col_count = GetColumnCount();
710 unsigned int col;
711 for (col = 0; col < col_count; col++)
712 {
713 wxDataViewColumn *column = GetColumn( col );
714 if (column->IsHidden())
715 continue;
716
717 Rect itemrect;
718 ::GetDataBrowserItemPartBounds( MacDataViewListCtrlPtr->GetControlRef(),
719 reinterpret_cast<DataBrowserItemID>(firstChild.GetID()), column->GetPropertyID(),
720 kDataBrowserPropertyEnclosingPart, &itemrect );
721
722 if (abs( event.GetX() - itemrect.right) < 3)
723 {
724 if (column->GetFlags() & wxDATAVIEW_COL_RESIZABLE)
725 SetCursor( wxCursor( wxCURSOR_SIZEWE ) );
726 else
727 SetCursor( *wxSTANDARD_CURSOR );
728 return;
729 }
730 }
731
732 }
733
734 SetCursor( *wxSTANDARD_CURSOR );
735 #endif
736 }
737
738 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase)
739
740 BEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
741 EVT_SIZE(wxDataViewCtrl::OnSize)
742 EVT_MOTION(wxDataViewCtrl::OnMouse)
743 END_EVENT_TABLE()
744
745 #endif // (wxUSE_DATAVIEWCTRL != 0) && (!defined(wxUSE_GENERICDATAVIEWCTRL) || (wxUSE_GENERICDATAVIEWCTRL == 0))
746