1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/datavgen.cpp
3 // Purpose: wxDataViewCtrl generic implementation
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #if wxUSE_DATAVIEWCTRL
19 #include "wx/dataview.h"
21 #ifdef wxUSE_GENERICDATAVIEWCTRL
25 #include "wx/msw/wrapwin.h"
29 #include "wx/dcclient.h"
31 #include "wx/settings.h"
34 #include "wx/stockitem.h"
35 #include "wx/calctrl.h"
36 #include "wx/popupwin.h"
37 #include "wx/renderer.h"
38 #include "wx/dcbuffer.h"
41 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
48 // wxDataViewHeaderWindow
49 //-----------------------------------------------------------------------------
51 class wxDataViewHeaderWindow
: public wxWindow
54 wxDataViewHeaderWindow( wxDataViewCtrl
*parent
,
56 const wxPoint
&pos
= wxDefaultPosition
,
57 const wxSize
&size
= wxDefaultSize
,
58 const wxString
&name
= wxT("wxdataviewctrlheaderwindow") );
59 virtual ~wxDataViewHeaderWindow();
61 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
62 wxDataViewCtrl
*GetOwner() { return m_owner
; }
64 void OnPaint( wxPaintEvent
&event
);
65 void OnMouse( wxMouseEvent
&event
);
66 void OnSetFocus( wxFocusEvent
&event
);
69 wxDataViewCtrl
*m_owner
;
70 wxCursor
*m_resizeCursor
;
73 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow
)
77 //-----------------------------------------------------------------------------
78 // wxDataViewRenameTimer
79 //-----------------------------------------------------------------------------
81 class wxDataViewRenameTimer
: public wxTimer
84 wxDataViewMainWindow
*m_owner
;
87 wxDataViewRenameTimer( wxDataViewMainWindow
*owner
);
91 //-----------------------------------------------------------------------------
92 // wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
93 //-----------------------------------------------------------------------------
95 class wxDataViewTextCtrlWrapper
: public wxEvtHandler
98 // NB: text must be a valid object but not Create()d yet
99 wxDataViewTextCtrlWrapper( wxDataViewMainWindow
*owner
,
101 wxDataViewListModel
*model
,
102 unsigned int col
, unsigned int row
,
105 wxTextCtrl
*GetText() const { return m_text
; }
107 void AcceptChangesAndFinish();
110 void OnChar( wxKeyEvent
&event
);
111 void OnKeyUp( wxKeyEvent
&event
);
112 void OnKillFocus( wxFocusEvent
&event
);
114 bool AcceptChanges();
118 wxDataViewMainWindow
*m_owner
;
120 wxString m_startValue
;
121 wxDataViewListModel
*m_model
;
125 bool m_aboutToFinish
;
127 DECLARE_EVENT_TABLE()
130 //-----------------------------------------------------------------------------
131 // wxDataViewMainWindow
132 //-----------------------------------------------------------------------------
134 WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection
, WXDLLIMPEXP_ADV
);
136 class wxDataViewMainWindow
: public wxWindow
139 wxDataViewMainWindow( wxDataViewCtrl
*parent
,
141 const wxPoint
&pos
= wxDefaultPosition
,
142 const wxSize
&size
= wxDefaultSize
,
143 const wxString
&name
= wxT("wxdataviewctrlmainwindow") );
144 virtual ~wxDataViewMainWindow();
146 // notifications from wxDataViewListModel
149 bool RowInserted( unsigned int before
);
150 bool RowDeleted( unsigned int row
);
151 bool RowChanged( unsigned int row
);
152 bool ValueChanged( unsigned int col
, unsigned int row
);
153 bool RowsReordered( unsigned int *new_order
);
156 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
157 wxDataViewCtrl
*GetOwner() { return m_owner
; }
159 void OnPaint( wxPaintEvent
&event
);
160 void OnArrowChar(unsigned int newCurrent
, const wxKeyEvent
& event
);
161 void OnChar( wxKeyEvent
&event
);
162 void OnMouse( wxMouseEvent
&event
);
163 void OnSetFocus( wxFocusEvent
&event
);
164 void OnKillFocus( wxFocusEvent
&event
);
166 void UpdateDisplay();
167 void RecalculateDisplay();
168 void OnInternalIdle();
170 void OnRenameTimer();
171 void FinishEditing( wxTextCtrl
*text
);
173 void ScrollWindow( int dx
, int dy
, const wxRect
*rect
);
175 bool HasCurrentRow() { return m_currentRow
!= (unsigned int)-1; }
176 void ChangeCurrentRow( unsigned int row
);
178 bool IsSingleSel() const { return !GetParent()->HasFlag(wxDV_MULTIPLE
); };
179 bool IsEmpty() { return GetRowCount() == 0; }
181 int GetCountPerPage();
182 int GetEndOfLastCol();
183 unsigned int GetFirstVisibleRow();
184 unsigned int GetLastVisibleRow();
185 unsigned int GetRowCount();
187 void SelectAllRows( bool on
);
188 void SelectRow( unsigned int row
, bool on
);
189 void SelectRows( unsigned int from
, unsigned int to
, bool on
);
190 void ReverseRowSelection( unsigned int row
);
191 bool IsRowSelected( unsigned int row
);
193 void RefreshRow( unsigned int row
);
194 void RefreshRows( unsigned int from
, unsigned int to
);
195 void RefreshRowsAfter( unsigned int firstRow
);
198 wxDataViewCtrl
*m_owner
;
202 wxDataViewColumn
*m_currentCol
;
203 unsigned int m_currentRow
;
204 wxDataViewSelection m_selection
;
206 wxDataViewRenameTimer
*m_renameTimer
;
207 wxDataViewTextCtrlWrapper
*m_textctrlWrapper
;
215 // for double click logic
216 unsigned int m_lineLastClicked
,
217 m_lineBeforeLastClicked
,
218 m_lineSelectSingleOnUp
;
221 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow
)
222 DECLARE_EVENT_TABLE()
225 // ---------------------------------------------------------
226 // wxGenericDataViewListModelNotifier
227 // ---------------------------------------------------------
229 class wxGenericDataViewListModelNotifier
: public wxDataViewListModelNotifier
232 wxGenericDataViewListModelNotifier( wxDataViewMainWindow
*mainWindow
)
233 { m_mainWindow
= mainWindow
; }
235 virtual bool RowAppended()
236 { return m_mainWindow
->RowAppended(); }
237 virtual bool RowPrepended()
238 { return m_mainWindow
->RowPrepended(); }
239 virtual bool RowInserted( unsigned int before
)
240 { return m_mainWindow
->RowInserted( before
); }
241 virtual bool RowDeleted( unsigned int row
)
242 { return m_mainWindow
->RowDeleted( row
); }
243 virtual bool RowChanged( unsigned int row
)
244 { return m_mainWindow
->RowChanged( row
); }
245 virtual bool ValueChanged( unsigned int col
, unsigned int row
)
246 { return m_mainWindow
->ValueChanged( col
, row
); }
247 virtual bool RowsReordered( unsigned int *new_order
)
248 { return m_mainWindow
->RowsReordered( new_order
); }
249 virtual bool Cleared()
250 { return m_mainWindow
->Cleared(); }
252 wxDataViewMainWindow
*m_mainWindow
;
255 // ---------------------------------------------------------
256 // wxDataViewRenderer
257 // ---------------------------------------------------------
259 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
)
261 wxDataViewRenderer::wxDataViewRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
262 wxDataViewRendererBase( varianttype
, mode
)
267 wxDataViewRenderer::~wxDataViewRenderer()
273 wxDC
*wxDataViewRenderer::GetDC()
277 if (GetOwner() == NULL
)
279 if (GetOwner()->GetOwner() == NULL
)
281 m_dc
= new wxClientDC( GetOwner()->GetOwner() );
287 // ---------------------------------------------------------
288 // wxDataViewCustomRenderer
289 // ---------------------------------------------------------
291 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
)
293 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString
&varianttype
,
294 wxDataViewCellMode mode
) :
295 wxDataViewRenderer( varianttype
, mode
)
299 // ---------------------------------------------------------
300 // wxDataViewTextRenderer
301 // ---------------------------------------------------------
303 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewCustomRenderer
)
305 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
306 wxDataViewCustomRenderer( varianttype
, mode
)
310 bool wxDataViewTextRenderer::SetValue( const wxVariant
&value
)
312 m_text
= value
.GetString();
317 bool wxDataViewTextRenderer::GetValue( wxVariant
& WXUNUSED(value
) )
322 bool wxDataViewTextRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
324 dc
->DrawText( m_text
, cell
.x
, cell
.y
);
329 wxSize
wxDataViewTextRenderer::GetSize()
331 return wxSize(80,20);
334 // ---------------------------------------------------------
335 // wxDataViewBitmapRenderer
336 // ---------------------------------------------------------
338 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewCustomRenderer
)
340 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
341 wxDataViewCustomRenderer( varianttype
, mode
)
345 bool wxDataViewBitmapRenderer::SetValue( const wxVariant
&value
)
347 if (value
.GetType() == wxT("wxBitmap"))
349 if (value
.GetType() == wxT("wxIcon"))
355 bool wxDataViewBitmapRenderer::GetValue( wxVariant
& WXUNUSED(value
) )
360 bool wxDataViewBitmapRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
363 dc
->DrawBitmap( m_bitmap
, cell
.x
, cell
.y
);
364 else if (m_icon
.Ok())
365 dc
->DrawIcon( m_icon
, cell
.x
, cell
.y
);
370 wxSize
wxDataViewBitmapRenderer::GetSize()
373 return wxSize( m_bitmap
.GetWidth(), m_bitmap
.GetHeight() );
374 else if (m_icon
.Ok())
375 return wxSize( m_icon
.GetWidth(), m_icon
.GetHeight() );
377 return wxSize(16,16);
380 // ---------------------------------------------------------
381 // wxDataViewToggleRenderer
382 // ---------------------------------------------------------
384 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer
, wxDataViewCustomRenderer
)
386 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString
&varianttype
,
387 wxDataViewCellMode mode
) :
388 wxDataViewCustomRenderer( varianttype
, mode
)
393 bool wxDataViewToggleRenderer::SetValue( const wxVariant
&value
)
395 m_toggle
= value
.GetBool();
400 bool wxDataViewToggleRenderer::GetValue( wxVariant
&WXUNUSED(value
) )
405 bool wxDataViewToggleRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
407 // User wxRenderer here
410 rect
.x
= cell
.x
+ cell
.width
/2 - 10;
412 rect
.y
= cell
.y
+ cell
.height
/2 - 10;
417 flags
|= wxCONTROL_CHECKED
;
418 if (GetMode() != wxDATAVIEW_CELL_ACTIVATABLE
)
419 flags
|= wxCONTROL_DISABLED
;
421 wxRendererNative::Get().DrawCheckBox(
422 GetOwner()->GetOwner(),
430 bool wxDataViewToggleRenderer::Activate( wxRect
WXUNUSED(cell
), wxDataViewListModel
*model
, unsigned int col
, unsigned int row
)
432 bool value
= !m_toggle
;
433 wxVariant variant
= value
;
434 model
->SetValue( variant
, col
, row
);
435 model
->ValueChanged( col
, row
);
439 wxSize
wxDataViewToggleRenderer::GetSize()
441 return wxSize(20,20);
444 // ---------------------------------------------------------
445 // wxDataViewProgressRenderer
446 // ---------------------------------------------------------
448 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
)
450 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString
&label
,
451 const wxString
&varianttype
, wxDataViewCellMode mode
) :
452 wxDataViewCustomRenderer( varianttype
, mode
)
458 wxDataViewProgressRenderer::~wxDataViewProgressRenderer()
462 bool wxDataViewProgressRenderer::SetValue( const wxVariant
&value
)
464 m_value
= (long) value
;
466 if (m_value
< 0) m_value
= 0;
467 if (m_value
> 100) m_value
= 100;
472 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
474 double pct
= (double)m_value
/ 100.0;
476 bar
.width
= (int)(cell
.width
* pct
);
477 dc
->SetPen( *wxTRANSPARENT_PEN
);
478 dc
->SetBrush( *wxBLUE_BRUSH
);
479 dc
->DrawRectangle( bar
);
481 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
482 dc
->SetPen( *wxBLACK_PEN
);
483 dc
->DrawRectangle( cell
);
488 wxSize
wxDataViewProgressRenderer::GetSize()
490 return wxSize(40,12);
493 // ---------------------------------------------------------
494 // wxDataViewDateRenderer
495 // ---------------------------------------------------------
497 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
500 wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime
*value
,
501 wxDataViewListModel
*model
, unsigned int col
, unsigned int row
) :
502 wxPopupTransientWindow( parent
, wxBORDER_SIMPLE
)
507 m_cal
= new wxCalendarCtrl( this, wxID_ANY
, *value
);
508 wxBoxSizer
*sizer
= new wxBoxSizer( wxHORIZONTAL
);
509 sizer
->Add( m_cal
, 1, wxGROW
);
514 void OnCalendar( wxCalendarEvent
&event
);
516 wxCalendarCtrl
*m_cal
;
517 wxDataViewListModel
*m_model
;
522 virtual void OnDismiss()
527 DECLARE_EVENT_TABLE()
530 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
)
531 EVT_CALENDAR( wxID_ANY
, wxDataViewDateRendererPopupTransient::OnCalendar
)
534 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent
&event
)
536 wxDateTime date
= event
.GetDate();
537 wxVariant value
= date
;
538 m_model
->SetValue( value
, m_col
, m_row
);
539 m_model
->ValueChanged( m_col
, m_row
);
543 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
)
545 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString
&varianttype
,
546 wxDataViewCellMode mode
) :
547 wxDataViewCustomRenderer( varianttype
, mode
)
551 bool wxDataViewDateRenderer::SetValue( const wxVariant
&value
)
553 m_date
= value
.GetDateTime();
558 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
560 dc
->SetFont( GetOwner()->GetOwner()->GetFont() );
561 wxString tmp
= m_date
.FormatDate();
562 dc
->DrawText( tmp
, cell
.x
, cell
.y
);
567 wxSize
wxDataViewDateRenderer::GetSize()
569 wxDataViewCtrl
* view
= GetOwner()->GetOwner();
570 wxString tmp
= m_date
.FormatDate();
572 view
->GetTextExtent( tmp
, &x
, &y
, &d
);
573 return wxSize(x
,y
+d
);
576 bool wxDataViewDateRenderer::Activate( wxRect
WXUNUSED(cell
), wxDataViewListModel
*model
, unsigned int col
, unsigned int row
)
579 model
->GetValue( variant
, col
, row
);
580 wxDateTime value
= variant
.GetDateTime();
582 wxDataViewDateRendererPopupTransient
*popup
= new wxDataViewDateRendererPopupTransient(
583 GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row
);
584 wxPoint pos
= wxGetMousePosition();
587 popup
->Popup( popup
->m_cal
);
592 // ---------------------------------------------------------
594 // ---------------------------------------------------------
596 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
)
598 wxDataViewColumn::wxDataViewColumn( const wxString
&title
, wxDataViewRenderer
*cell
, unsigned int model_column
,
599 int width
, int flags
) :
600 wxDataViewColumnBase( title
, cell
, model_column
, width
, flags
)
607 wxDataViewColumn::wxDataViewColumn( const wxBitmap
&bitmap
, wxDataViewRenderer
*cell
, unsigned int model_column
,
608 int width
, int flags
) :
609 wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, flags
)
616 void wxDataViewColumn::SetAlignment( wxAlignment
WXUNUSED(align
) )
621 void wxDataViewColumn::SetSortable( bool WXUNUSED(sortable
) )
626 bool wxDataViewColumn::GetSortable()
632 void wxDataViewColumn::SetSortOrder( bool WXUNUSED(ascending
) )
637 bool wxDataViewColumn::IsSortOrderAscending()
644 wxDataViewColumn::~wxDataViewColumn()
648 void wxDataViewColumn::SetTitle( const wxString
&title
)
650 wxDataViewColumnBase::SetTitle( title
);
654 void wxDataViewColumn::SetBitmap( const wxBitmap
&bitmap
)
656 wxDataViewColumnBase::SetBitmap( bitmap
);
660 int wxDataViewColumn::GetWidth()
665 //-----------------------------------------------------------------------------
666 // wxDataViewHeaderWindow
667 //-----------------------------------------------------------------------------
669 IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow
, wxWindow
)
671 BEGIN_EVENT_TABLE(wxDataViewHeaderWindow
,wxWindow
)
672 EVT_PAINT (wxDataViewHeaderWindow::OnPaint
)
673 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse
)
674 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus
)
677 wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
678 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
679 wxWindow( parent
, id
, pos
, size
, 0, name
)
683 m_resizeCursor
= new wxCursor( wxCURSOR_SIZEWE
);
685 wxVisualAttributes attr
= wxPanel::GetClassDefaultAttributes();
686 SetBackgroundStyle( wxBG_STYLE_CUSTOM
);
687 SetOwnForegroundColour( attr
.colFg
);
688 SetOwnBackgroundColour( attr
.colBg
);
690 SetOwnFont( attr
.font
);
693 wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
695 delete m_resizeCursor
;
698 void wxDataViewHeaderWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
701 GetClientSize( &w
, &h
);
703 wxAutoBufferedPaintDC
dc( this );
705 dc
.SetBackground(GetBackgroundColour());
709 m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL
);
712 m_owner
->GetViewStart( &x
, NULL
);
714 // account for the horz scrollbar offset
715 dc
.SetDeviceOrigin( -x
* xpix
, 0 );
717 dc
.SetFont( GetFont() );
719 unsigned int cols
= GetOwner()->GetNumberOfColumns();
722 for (i
= 0; i
< cols
; i
++)
724 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
725 int width
= col
->GetWidth();
730 wxRendererNative::Get().DrawHeaderButton
734 wxRect(xpos
, 0, cw
, ch
-1),
735 m_parent
->IsEnabled() ? 0
736 : (int)wxCONTROL_DISABLED
739 dc
.DrawText( col
->GetTitle(), xpos
+3, 3 );
745 void wxDataViewHeaderWindow::OnMouse( wxMouseEvent
&WXUNUSED(event
) )
749 void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent
&event
)
751 GetParent()->SetFocus();
755 //-----------------------------------------------------------------------------
756 // wxDataViewRenameTimer
757 //-----------------------------------------------------------------------------
759 wxDataViewRenameTimer::wxDataViewRenameTimer( wxDataViewMainWindow
*owner
)
764 void wxDataViewRenameTimer::Notify()
766 m_owner
->OnRenameTimer();
769 //-----------------------------------------------------------------------------
770 // wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
771 //-----------------------------------------------------------------------------
773 BEGIN_EVENT_TABLE(wxDataViewTextCtrlWrapper
, wxEvtHandler
)
774 EVT_CHAR (wxDataViewTextCtrlWrapper::OnChar
)
775 EVT_KEY_UP (wxDataViewTextCtrlWrapper::OnKeyUp
)
776 EVT_KILL_FOCUS (wxDataViewTextCtrlWrapper::OnKillFocus
)
779 wxDataViewTextCtrlWrapper::wxDataViewTextCtrlWrapper(
780 wxDataViewMainWindow
*owner
,
782 wxDataViewListModel
*model
,
783 unsigned int col
, unsigned int row
,
793 m_aboutToFinish
= false;
796 model
->GetValue( value
, col
, row
);
797 m_startValue
= value
.GetString();
799 m_owner
->GetOwner()->CalcScrolledPosition(
800 rectLabel
.x
, rectLabel
.y
, &rectLabel
.x
, &rectLabel
.y
);
802 m_text
->Create( owner
, wxID_ANY
, m_startValue
,
803 wxPoint(rectLabel
.x
-2,rectLabel
.y
-2),
804 wxSize(rectLabel
.width
+7,rectLabel
.height
+4) );
807 m_text
->PushEventHandler(this);
810 void wxDataViewTextCtrlWrapper::AcceptChangesAndFinish()
812 m_aboutToFinish
= true;
814 // Notify the owner about the changes
817 // Even if vetoed, close the control (consistent with MSW)
821 void wxDataViewTextCtrlWrapper::OnChar( wxKeyEvent
&event
)
823 switch ( event
.m_keyCode
)
826 AcceptChangesAndFinish();
830 // m_owner->OnRenameCancelled( m_itemEdited );
839 void wxDataViewTextCtrlWrapper::OnKeyUp( wxKeyEvent
&event
)
847 // auto-grow the textctrl
848 wxSize parentSize
= m_owner
->GetSize();
849 wxPoint myPos
= m_text
->GetPosition();
850 wxSize mySize
= m_text
->GetSize();
852 m_text
->GetTextExtent(m_text
->GetValue() + _T("MM"), &sx
, &sy
);
853 if (myPos
.x
+ sx
> parentSize
.x
)
854 sx
= parentSize
.x
- myPos
.x
;
857 m_text
->SetSize(sx
, wxDefaultCoord
);
862 void wxDataViewTextCtrlWrapper::OnKillFocus( wxFocusEvent
&event
)
864 if ( !m_finished
&& !m_aboutToFinish
)
867 //if ( !AcceptChanges() )
868 // m_owner->OnRenameCancelled( m_itemEdited );
873 // We must let the native text control handle focus
877 bool wxDataViewTextCtrlWrapper::AcceptChanges()
879 const wxString value
= m_text
->GetValue();
881 if ( value
== m_startValue
)
882 // nothing changed, always accept
885 // if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
886 // vetoed by the user
889 // accepted, do rename the item
892 m_model
->SetValue( variant
, m_col
, m_row
);
893 m_model
->ValueChanged( m_col
, m_row
);
898 void wxDataViewTextCtrlWrapper::Finish()
904 m_text
->RemoveEventHandler(this);
905 m_owner
->FinishEditing(m_text
);
908 wxPendingDelete
.Append( this );
912 //-----------------------------------------------------------------------------
913 // wxDataViewMainWindow
914 //-----------------------------------------------------------------------------
916 int LINKAGEMODE
wxDataViewSelectionCmp( unsigned int row1
, unsigned int row2
)
918 if (row1
> row2
) return 1;
919 if (row1
== row2
) return 0;
924 IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow
, wxWindow
)
926 BEGIN_EVENT_TABLE(wxDataViewMainWindow
,wxWindow
)
927 EVT_PAINT (wxDataViewMainWindow::OnPaint
)
928 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse
)
929 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus
)
930 EVT_KILL_FOCUS (wxDataViewMainWindow::OnKillFocus
)
931 EVT_CHAR (wxDataViewMainWindow::OnChar
)
934 wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
935 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
936 wxWindow( parent
, id
, pos
, size
, wxWANTS_CHARS
, name
),
937 m_selection( wxDataViewSelectionCmp
)
942 m_lastOnSame
= false;
943 m_renameTimer
= new wxDataViewRenameTimer( this );
944 m_textctrlWrapper
= NULL
;
946 // TODO: user better initial values/nothing selected
950 // TODO: we need to calculate this smartly
954 m_dragStart
= wxPoint(0,0);
955 m_lineLastClicked
= (unsigned int) -1;
956 m_lineBeforeLastClicked
= (unsigned int) -1;
957 m_lineSelectSingleOnUp
= (unsigned int) -1;
961 SetBackgroundStyle( wxBG_STYLE_CUSTOM
);
962 SetBackgroundColour( *wxWHITE
);
967 wxDataViewMainWindow::~wxDataViewMainWindow()
969 delete m_renameTimer
;
972 void wxDataViewMainWindow::OnRenameTimer()
974 // We have to call this here because changes may just have
975 // been made and no screen update taken place.
981 unsigned int cols
= GetOwner()->GetNumberOfColumns();
983 for (i
= 0; i
< cols
; i
++)
985 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
986 if (c
== m_currentCol
)
988 xpos
+= c
->GetWidth();
990 wxRect
labelRect( xpos
, m_currentRow
* m_lineHeight
, m_currentCol
->GetWidth(), m_lineHeight
);
992 wxClassInfo
*textControlClass
= CLASSINFO(wxTextCtrl
);
994 wxTextCtrl
* const text
= (wxTextCtrl
*)textControlClass
->CreateObject();
995 m_textctrlWrapper
= new wxDataViewTextCtrlWrapper(this, text
, GetOwner()->GetModel(),
996 m_currentCol
->GetModelColumn(), m_currentRow
, labelRect
);
999 void wxDataViewMainWindow::FinishEditing( wxTextCtrl
*text
)
1002 m_textctrlWrapper
= NULL
;
1004 // SetFocusIgnoringChildren();
1007 bool wxDataViewMainWindow::RowAppended()
1012 bool wxDataViewMainWindow::RowPrepended()
1017 bool wxDataViewMainWindow::RowInserted( unsigned int WXUNUSED(before
) )
1022 bool wxDataViewMainWindow::RowDeleted( unsigned int WXUNUSED(row
) )
1027 bool wxDataViewMainWindow::RowChanged( unsigned int WXUNUSED(row
) )
1032 bool wxDataViewMainWindow::ValueChanged( unsigned int WXUNUSED(col
), unsigned int row
)
1034 wxRect
rect( 0, row
*m_lineHeight
, 10000, m_lineHeight
);
1035 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1036 Refresh( true, &rect
);
1041 bool wxDataViewMainWindow::RowsReordered( unsigned int *WXUNUSED(new_order
) )
1048 bool wxDataViewMainWindow::Cleared()
1053 void wxDataViewMainWindow::UpdateDisplay()
1058 void wxDataViewMainWindow::OnInternalIdle()
1060 wxWindow::OnInternalIdle();
1064 RecalculateDisplay();
1069 void wxDataViewMainWindow::RecalculateDisplay()
1071 wxDataViewListModel
*model
= GetOwner()->GetModel();
1079 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1081 for (i
= 0; i
< cols
; i
++)
1083 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
1084 width
+= col
->GetWidth();
1087 int height
= model
->GetNumberOfRows() * m_lineHeight
;
1089 SetVirtualSize( width
, height
);
1090 GetOwner()->SetScrollRate( 10, m_lineHeight
);
1095 void wxDataViewMainWindow::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
1097 wxWindow::ScrollWindow( dx
, dy
, rect
);
1098 GetOwner()->m_headerArea
->ScrollWindow( dx
, 0 );
1101 void wxDataViewMainWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1103 wxAutoBufferedPaintDC
dc( this );
1105 dc
.SetBackground(GetBackgroundColour());
1108 GetOwner()->PrepareDC( dc
);
1110 dc
.SetFont( GetFont() );
1112 wxRect update
= GetUpdateRegion().GetBox();
1113 m_owner
->CalcUnscrolledPosition( update
.x
, update
.y
, &update
.x
, &update
.y
);
1115 wxDataViewListModel
*model
= GetOwner()->GetModel();
1117 unsigned int item_start
= wxMax( 0, (update
.y
/ m_lineHeight
) );
1118 unsigned int item_count
= wxMin( (int)(((update
.y
+ update
.height
) / m_lineHeight
) - item_start
+ 1),
1119 (int)(model
->GetNumberOfRows()-item_start
) );
1124 for (item
= item_start
; item
< item_start
+item_count
; item
++)
1126 if (m_selection
.Index( item
) != wxNOT_FOUND
)
1128 int flags
= wxCONTROL_SELECTED
;
1129 if (item
== m_currentRow
)
1130 flags
|= wxCONTROL_CURRENT
;
1132 flags
|= wxCONTROL_FOCUSED
;
1133 wxRect
rect( 0, item
*m_lineHeight
+1, GetEndOfLastCol(), m_lineHeight
-2 );
1134 wxRendererNative::Get().DrawItemSelectionRect
1144 if (item
== m_currentRow
)
1146 int flags
= wxCONTROL_CURRENT
;
1148 flags
|= wxCONTROL_FOCUSED
; // should have no effect
1149 wxRect
rect( 0, item
*m_lineHeight
+1, GetEndOfLastCol(), m_lineHeight
-2 );
1150 wxRendererNative::Get().DrawItemSelectionRect
1164 cell_rect
.height
= m_lineHeight
;
1165 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1167 for (i
= 0; i
< cols
; i
++)
1169 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
1170 wxDataViewRenderer
*cell
= col
->GetRenderer();
1171 cell_rect
.width
= col
->GetWidth();
1173 for (item
= item_start
; item
< item_start
+item_count
; item
++)
1175 cell_rect
.y
= item
*m_lineHeight
;
1177 model
->GetValue( value
, col
->GetModelColumn(), item
);
1178 cell
->SetValue( value
);
1179 wxSize size
= cell
->GetSize();
1180 // cannot be bigger than allocated space
1181 size
.x
= wxMin( size
.x
, cell_rect
.width
);
1182 size
.y
= wxMin( size
.y
, cell_rect
.height
);
1183 // TODO: check for left/right/centre alignment here
1186 item_rect
.x
= cell_rect
.x
+ (cell_rect
.width
/ 2) - (size
.x
/ 2);
1187 item_rect
.y
= cell_rect
.y
+ (cell_rect
.height
/ 2) - (size
.y
/ 2);
1189 item_rect
.width
= size
.x
;
1190 item_rect
.height
= size
.y
;
1191 cell
->Render( item_rect
, &dc
, 0 );
1194 cell_rect
.x
+= cell_rect
.width
;
1198 int wxDataViewMainWindow::GetCountPerPage()
1200 wxSize size
= GetClientSize();
1201 return size
.y
/ m_lineHeight
;
1204 int wxDataViewMainWindow::GetEndOfLastCol()
1208 for (i
= 0; i
< GetOwner()->GetNumberOfColumns(); i
++)
1210 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
1211 width
+= c
->GetWidth();
1216 unsigned int wxDataViewMainWindow::GetFirstVisibleRow()
1220 m_owner
->CalcUnscrolledPosition( x
, y
, &x
, &y
);
1222 return y
/ m_lineHeight
;
1225 unsigned int wxDataViewMainWindow::GetLastVisibleRow()
1227 wxSize client_size
= GetClientSize();
1228 m_owner
->CalcUnscrolledPosition( client_size
.x
, client_size
.y
, &client_size
.x
, &client_size
.y
);
1230 return wxMin( GetRowCount()-1, ((unsigned)client_size
.y
/m_lineHeight
)+1 );
1233 unsigned int wxDataViewMainWindow::GetRowCount()
1235 return GetOwner()->GetModel()->GetNumberOfRows();
1238 void wxDataViewMainWindow::ChangeCurrentRow( unsigned int row
)
1245 void wxDataViewMainWindow::SelectAllRows( bool on
)
1252 m_selection
.Clear();
1253 for (unsigned int i
= 0; i
< GetRowCount(); i
++)
1254 m_selection
.Add( i
);
1259 unsigned int first_visible
= GetFirstVisibleRow();
1260 unsigned int last_visible
= GetLastVisibleRow();
1262 for (i
= 0; i
< m_selection
.GetCount(); i
++)
1264 unsigned int row
= m_selection
[i
];
1265 if ((row
>= first_visible
) && (row
<= last_visible
))
1268 m_selection
.Clear();
1272 void wxDataViewMainWindow::SelectRow( unsigned int row
, bool on
)
1274 if (m_selection
.Index( row
) == wxNOT_FOUND
)
1278 m_selection
.Add( row
);
1286 m_selection
.Remove( row
);
1292 void wxDataViewMainWindow::SelectRows( unsigned int from
, unsigned int to
, bool on
)
1296 unsigned int tmp
= from
;
1302 for (i
= from
; i
<= to
; i
++)
1304 if (m_selection
.Index( i
) == wxNOT_FOUND
)
1307 m_selection
.Add( i
);
1312 m_selection
.Remove( i
);
1315 RefreshRows( from
, to
);
1318 void wxDataViewMainWindow::ReverseRowSelection( unsigned int row
)
1320 if (m_selection
.Index( row
) == wxNOT_FOUND
)
1321 m_selection
.Add( row
);
1323 m_selection
.Remove( row
);
1327 bool wxDataViewMainWindow::IsRowSelected( unsigned int row
)
1329 return (m_selection
.Index( row
) != wxNOT_FOUND
);
1332 void wxDataViewMainWindow::RefreshRow( unsigned int row
)
1334 wxRect
rect( 0, row
*m_lineHeight
, GetEndOfLastCol(), m_lineHeight
);
1335 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1337 wxSize client_size
= GetClientSize();
1338 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1339 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1340 if (intersect_rect
.width
> 0)
1341 Refresh( true, &intersect_rect
);
1344 void wxDataViewMainWindow::RefreshRows( unsigned int from
, unsigned int to
)
1348 unsigned int tmp
= to
;
1353 wxRect
rect( 0, from
*m_lineHeight
, GetEndOfLastCol(), (to
-from
+1) * m_lineHeight
);
1354 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1356 wxSize client_size
= GetClientSize();
1357 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1358 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1359 if (intersect_rect
.width
> 0)
1360 Refresh( true, &intersect_rect
);
1363 void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow
)
1365 unsigned int count
= GetRowCount();
1366 if (firstRow
> count
)
1369 wxRect
rect( 0, firstRow
*m_lineHeight
, GetEndOfLastCol(), count
* m_lineHeight
);
1370 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1372 wxSize client_size
= GetClientSize();
1373 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1374 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1375 if (intersect_rect
.width
> 0)
1376 Refresh( true, &intersect_rect
);
1379 void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent
, const wxKeyEvent
& event
)
1381 wxCHECK_RET( newCurrent
< GetRowCount(),
1382 _T("invalid item index in OnArrowChar()") );
1384 // if there is no selection, we cannot move it anywhere
1385 if (!HasCurrentRow())
1388 unsigned int oldCurrent
= m_currentRow
;
1390 // in single selection we just ignore Shift as we can't select several
1392 if ( event
.ShiftDown() && !IsSingleSel() )
1394 RefreshRow( oldCurrent
);
1396 ChangeCurrentRow( newCurrent
);
1398 // select all the items between the old and the new one
1399 if ( oldCurrent
> newCurrent
)
1401 newCurrent
= oldCurrent
;
1402 oldCurrent
= m_currentRow
;
1405 SelectRows( oldCurrent
, newCurrent
, true );
1409 RefreshRow( oldCurrent
);
1411 // all previously selected items are unselected unless ctrl is held
1412 if ( !event
.ControlDown() )
1413 SelectAllRows(false);
1415 ChangeCurrentRow( newCurrent
);
1417 if ( !event
.ControlDown() )
1418 SelectRow( m_currentRow
, true );
1420 RefreshRow( m_currentRow
);
1426 void wxDataViewMainWindow::OnChar( wxKeyEvent
&event
)
1428 if (event
.GetKeyCode() == WXK_TAB
)
1430 wxNavigationKeyEvent nevent
;
1431 nevent
.SetWindowChange( event
.ControlDown() );
1432 nevent
.SetDirection( !event
.ShiftDown() );
1433 nevent
.SetEventObject( GetParent()->GetParent() );
1434 nevent
.SetCurrentFocus( m_parent
);
1435 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent
))
1439 // no item -> nothing to do
1440 if (!HasCurrentRow())
1446 // don't use m_linesPerPage directly as it might not be computed yet
1447 const int pageSize
= GetCountPerPage();
1448 wxCHECK_RET( pageSize
, _T("should have non zero page size") );
1450 switch ( event
.GetKeyCode() )
1453 if ( m_currentRow
> 0 )
1454 OnArrowChar( m_currentRow
- 1, event
);
1458 if ( m_currentRow
< GetRowCount() - 1 )
1459 OnArrowChar( m_currentRow
+ 1, event
);
1464 OnArrowChar( GetRowCount() - 1, event
);
1469 OnArrowChar( 0, event
);
1474 int steps
= pageSize
- 1;
1475 int index
= m_currentRow
- steps
;
1479 OnArrowChar( index
, event
);
1485 int steps
= pageSize
- 1;
1486 unsigned int index
= m_currentRow
+ steps
;
1487 unsigned int count
= GetRowCount();
1488 if ( index
>= count
)
1491 OnArrowChar( index
, event
);
1500 void wxDataViewMainWindow::OnMouse( wxMouseEvent
&event
)
1502 if (event
.GetEventType() == wxEVT_MOUSEWHEEL
)
1504 // let the base handle mouse wheel events.
1509 int x
= event
.GetX();
1510 int y
= event
.GetY();
1511 m_owner
->CalcUnscrolledPosition( x
, y
, &x
, &y
);
1513 wxDataViewColumn
*col
= NULL
;
1516 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1518 for (i
= 0; i
< cols
; i
++)
1520 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
1521 if (x
< xpos
+ c
->GetWidth())
1526 xpos
+= c
->GetWidth();
1530 wxDataViewRenderer
*cell
= col
->GetRenderer();
1532 unsigned int current
= y
/ m_lineHeight
;
1534 if ((current
> GetRowCount()) || (x
> GetEndOfLastCol()))
1536 // Unselect all if below the last row ?
1540 wxDataViewListModel
*model
= GetOwner()->GetModel();
1542 if (event
.Dragging())
1544 if (m_dragCount
== 0)
1546 // we have to report the raw, physical coords as we want to be
1547 // able to call HitTest(event.m_pointDrag) from the user code to
1548 // get the item being dragged
1549 m_dragStart
= event
.GetPosition();
1554 if (m_dragCount
!= 3)
1557 if (event
.LeftIsDown())
1559 // Notify cell about drag
1568 bool forceClick
= false;
1570 if (event
.ButtonDClick())
1572 m_renameTimer
->Stop();
1573 m_lastOnSame
= false;
1576 if (event
.LeftDClick())
1578 if ( current
== m_lineLastClicked
)
1580 if (cell
->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE
)
1583 model
->GetValue( value
, col
->GetModelColumn(), current
);
1584 cell
->SetValue( value
);
1585 wxRect
cell_rect( xpos
, current
* m_lineHeight
, col
->GetWidth(), m_lineHeight
);
1586 cell
->Activate( cell_rect
, model
, col
->GetModelColumn(), current
);
1592 // The first click was on another item, so don't interpret this as
1593 // a double click, but as a simple click instead
1600 if (m_lineSelectSingleOnUp
!= (unsigned int)-1)
1602 // select single line
1603 SelectAllRows( false );
1604 SelectRow( m_lineSelectSingleOnUp
, true );
1609 if ((col
== m_currentCol
) && (current
== m_currentRow
) &&
1610 (cell
->GetMode() == wxDATAVIEW_CELL_EDITABLE
) )
1612 m_renameTimer
->Start( 100, true );
1616 m_lastOnSame
= false;
1617 m_lineSelectSingleOnUp
= (unsigned int)-1;
1621 // This is necessary, because after a DnD operation in
1622 // from and to ourself, the up event is swallowed by the
1623 // DnD code. So on next non-up event (which means here and
1624 // now) m_lineSelectSingleOnUp should be reset.
1625 m_lineSelectSingleOnUp
= (unsigned int)-1;
1628 if (event
.RightDown())
1630 m_lineBeforeLastClicked
= m_lineLastClicked
;
1631 m_lineLastClicked
= current
;
1633 // If the item is already selected, do not update the selection.
1634 // Multi-selections should not be cleared if a selected item is clicked.
1635 if (!IsRowSelected(current
))
1637 SelectAllRows(false);
1638 ChangeCurrentRow(current
);
1639 SelectRow(m_currentRow
,true);
1642 // notify cell about right click
1645 // Allow generation of context menu event
1648 else if (event
.MiddleDown())
1650 // notify cell about middle click
1653 if (event
.LeftDown() || forceClick
)
1659 m_lineBeforeLastClicked
= m_lineLastClicked
;
1660 m_lineLastClicked
= current
;
1662 unsigned int oldCurrentRow
= m_currentRow
;
1663 bool oldWasSelected
= IsRowSelected(m_currentRow
);
1665 bool cmdModifierDown
= event
.CmdDown();
1666 if ( IsSingleSel() || !(cmdModifierDown
|| event
.ShiftDown()) )
1668 if ( IsSingleSel() || !IsRowSelected(current
) )
1670 SelectAllRows( false );
1672 ChangeCurrentRow(current
);
1674 SelectRow(m_currentRow
,true);
1676 else // multi sel & current is highlighted & no mod keys
1678 m_lineSelectSingleOnUp
= current
;
1679 ChangeCurrentRow(current
); // change focus
1682 else // multi sel & either ctrl or shift is down
1684 if (cmdModifierDown
)
1686 ChangeCurrentRow(current
);
1688 ReverseRowSelection(m_currentRow
);
1690 else if (event
.ShiftDown())
1692 ChangeCurrentRow(current
);
1694 unsigned int lineFrom
= oldCurrentRow
,
1697 if ( lineTo
< lineFrom
)
1700 lineFrom
= m_currentRow
;
1703 SelectRows(lineFrom
, lineTo
, true);
1705 else // !ctrl, !shift
1707 // test in the enclosing if should make it impossible
1708 wxFAIL_MSG( _T("how did we get here?") );
1712 if (m_currentRow
!= oldCurrentRow
)
1713 RefreshRow( oldCurrentRow
);
1715 wxDataViewColumn
*oldCurrentCol
= m_currentCol
;
1717 // Update selection here...
1720 m_lastOnSame
= !forceClick
&& ((col
== oldCurrentCol
) && (current
== oldCurrentRow
)) && oldWasSelected
;
1724 void wxDataViewMainWindow::OnSetFocus( wxFocusEvent
&event
)
1728 if (HasCurrentRow())
1734 void wxDataViewMainWindow::OnKillFocus( wxFocusEvent
&event
)
1738 if (HasCurrentRow())
1744 //-----------------------------------------------------------------------------
1746 //-----------------------------------------------------------------------------
1748 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
)
1750 BEGIN_EVENT_TABLE(wxDataViewCtrl
, wxDataViewCtrlBase
)
1751 EVT_SIZE(wxDataViewCtrl::OnSize
)
1754 wxDataViewCtrl::~wxDataViewCtrl()
1757 GetModel()->RemoveNotifier( m_notifier
);
1760 void wxDataViewCtrl::Init()
1765 bool wxDataViewCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1766 const wxPoint
& pos
, const wxSize
& size
,
1767 long style
, const wxValidator
& validator
)
1769 if (!wxControl::Create( parent
, id
, pos
, size
, style
| wxScrolledWindowStyle
|wxSUNKEN_BORDER
, validator
))
1775 MacSetClipChildren( true ) ;
1778 m_clientArea
= new wxDataViewMainWindow( this, wxID_ANY
);
1780 m_headerArea
= new wxDataViewHeaderWindow( this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,22) );
1782 m_headerArea
= new wxDataViewHeaderWindow( this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,25) );
1785 SetTargetWindow( m_clientArea
);
1787 wxBoxSizer
*sizer
= new wxBoxSizer( wxVERTICAL
);
1788 sizer
->Add( m_headerArea
, 0, wxGROW
);
1789 sizer
->Add( m_clientArea
, 1, wxGROW
);
1796 WXLRESULT
wxDataViewCtrl::MSWWindowProc(WXUINT nMsg
,
1800 WXLRESULT rc
= wxDataViewCtrlBase::MSWWindowProc(nMsg
, wParam
, lParam
);
1803 // we need to process arrows ourselves for scrolling
1804 if ( nMsg
== WM_GETDLGCODE
)
1806 rc
|= DLGC_WANTARROWS
;
1814 void wxDataViewCtrl::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1816 // We need to override OnSize so that our scrolled
1817 // window a) does call Layout() to use sizers for
1818 // positioning the controls but b) does not query
1819 // the sizer for their size and use that for setting
1820 // the scrollable area as set that ourselves by
1821 // calling SetScrollbar() further down.
1828 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel
*model
)
1830 if (!wxDataViewCtrlBase::AssociateModel( model
))
1833 m_notifier
= new wxGenericDataViewListModelNotifier( m_clientArea
);
1835 model
->AddNotifier( m_notifier
);
1837 m_clientArea
->UpdateDisplay();
1842 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn
*col
)
1844 if (!wxDataViewCtrlBase::AppendColumn(col
))
1847 m_clientArea
->UpdateDisplay();
1852 void wxDataViewCtrl::SetSelection( int WXUNUSED(row
) )
1857 void wxDataViewCtrl::SetSelectionRange( unsigned int WXUNUSED(from
), unsigned int WXUNUSED(to
) )
1862 void wxDataViewCtrl::SetSelections( const wxArrayInt
& WXUNUSED(aSelections
) )
1867 void wxDataViewCtrl::Unselect( unsigned int WXUNUSED(row
) )
1872 bool wxDataViewCtrl::IsSelected( unsigned int WXUNUSED(row
) ) const
1879 int wxDataViewCtrl::GetSelection() const
1886 int wxDataViewCtrl::GetSelections(wxArrayInt
& WXUNUSED(aSelections
) ) const
1894 // !wxUSE_GENERICDATAVIEWCTRL
1897 // wxUSE_DATAVIEWCTRL