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