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"
32 #include "wx/msgdlg.h"
35 #include "wx/stockitem.h"
36 #include "wx/calctrl.h"
37 #include "wx/popupwin.h"
38 #include "wx/renderer.h"
39 #include "wx/dcbuffer.h"
42 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
49 // wxDataViewHeaderWindow
50 //-----------------------------------------------------------------------------
52 class wxDataViewHeaderWindow
: public wxWindow
55 wxDataViewHeaderWindow( wxDataViewCtrl
*parent
,
57 const wxPoint
&pos
= wxDefaultPosition
,
58 const wxSize
&size
= wxDefaultSize
,
59 const wxString
&name
= wxT("wxdataviewctrlheaderwindow") );
60 virtual ~wxDataViewHeaderWindow();
62 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
63 wxDataViewCtrl
*GetOwner() { return m_owner
; }
65 void OnPaint( wxPaintEvent
&event
);
66 void OnMouse( wxMouseEvent
&event
);
67 void OnSetFocus( wxFocusEvent
&event
);
70 wxDataViewCtrl
*m_owner
;
71 wxCursor
*m_resizeCursor
;
74 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow
)
78 //-----------------------------------------------------------------------------
79 // wxDataViewRenameTimer
80 //-----------------------------------------------------------------------------
82 class wxDataViewRenameTimer
: public wxTimer
85 wxDataViewMainWindow
*m_owner
;
88 wxDataViewRenameTimer( wxDataViewMainWindow
*owner
);
92 //-----------------------------------------------------------------------------
93 // wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
94 //-----------------------------------------------------------------------------
96 class wxDataViewTextCtrlWrapper
: public wxEvtHandler
99 // NB: text must be a valid object but not Create()d yet
100 wxDataViewTextCtrlWrapper( wxDataViewMainWindow
*owner
,
102 wxDataViewListModel
*model
,
103 unsigned int col
, unsigned int row
,
106 wxTextCtrl
*GetText() const { return m_text
; }
108 void AcceptChangesAndFinish();
111 void OnChar( wxKeyEvent
&event
);
112 void OnKeyUp( wxKeyEvent
&event
);
113 void OnKillFocus( wxFocusEvent
&event
);
115 bool AcceptChanges();
119 wxDataViewMainWindow
*m_owner
;
121 wxString m_startValue
;
122 wxDataViewListModel
*m_model
;
126 bool m_aboutToFinish
;
128 DECLARE_EVENT_TABLE()
131 //-----------------------------------------------------------------------------
132 // wxDataViewMainWindow
133 //-----------------------------------------------------------------------------
135 WX_DEFINE_SORTED_USER_EXPORTED_ARRAY_SIZE_T(unsigned int, wxDataViewSelection
, WXDLLIMPEXP_ADV
);
137 class wxDataViewMainWindow
: public wxWindow
140 wxDataViewMainWindow( wxDataViewCtrl
*parent
,
142 const wxPoint
&pos
= wxDefaultPosition
,
143 const wxSize
&size
= wxDefaultSize
,
144 const wxString
&name
= wxT("wxdataviewctrlmainwindow") );
145 virtual ~wxDataViewMainWindow();
147 // notifications from wxDataViewListModel
150 bool RowInserted( unsigned int before
);
151 bool RowDeleted( unsigned int row
);
152 bool RowChanged( unsigned int row
);
153 bool ValueChanged( unsigned int col
, unsigned int row
);
154 bool RowsReordered( unsigned int *new_order
);
157 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
158 wxDataViewCtrl
*GetOwner() { return m_owner
; }
160 void OnPaint( wxPaintEvent
&event
);
161 void OnArrowChar(unsigned int newCurrent
, const wxKeyEvent
& event
);
162 void OnChar( wxKeyEvent
&event
);
163 void OnMouse( wxMouseEvent
&event
);
164 void OnSetFocus( wxFocusEvent
&event
);
165 void OnKillFocus( wxFocusEvent
&event
);
167 void UpdateDisplay();
168 void RecalculateDisplay();
169 void OnInternalIdle();
171 void OnRenameTimer();
172 void FinishEditing( wxTextCtrl
*text
);
174 void ScrollWindow( int dx
, int dy
, const wxRect
*rect
);
176 bool HasCurrentRow() { return m_currentRow
!= (unsigned int)-1; }
177 void ChangeCurrentRow( unsigned int row
);
179 bool IsSingleSel() const { return !GetParent()->HasFlag(wxDV_MULTIPLE
); };
180 bool IsEmpty() { return GetRowCount() == 0; }
182 int GetCountPerPage();
183 int GetEndOfLastCol();
184 unsigned int GetFirstVisibleRow();
185 unsigned int GetLastVisibleRow();
186 unsigned int GetRowCount();
188 void SelectAllRows( bool on
);
189 void SelectRow( unsigned int row
, bool on
);
190 void SelectRows( unsigned int from
, unsigned int to
, bool on
);
191 void ReverseRowSelection( unsigned int row
);
192 bool IsRowSelected( unsigned int row
);
194 void RefreshRow( unsigned int row
);
195 void RefreshRows( unsigned int from
, unsigned int to
);
196 void RefreshRowsAfter( unsigned int firstRow
);
199 wxDataViewCtrl
*m_owner
;
203 wxDataViewColumn
*m_currentCol
;
204 unsigned int m_currentRow
;
205 wxDataViewSelection m_selection
;
207 wxDataViewRenameTimer
*m_renameTimer
;
208 wxDataViewTextCtrlWrapper
*m_textctrlWrapper
;
216 // for double click logic
217 unsigned int m_lineLastClicked
,
218 m_lineBeforeLastClicked
,
219 m_lineSelectSingleOnUp
;
222 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow
)
223 DECLARE_EVENT_TABLE()
226 // ---------------------------------------------------------
227 // wxGenericDataViewListModelNotifier
228 // ---------------------------------------------------------
230 class wxGenericDataViewListModelNotifier
: public wxDataViewListModelNotifier
233 wxGenericDataViewListModelNotifier( wxDataViewMainWindow
*mainWindow
)
234 { m_mainWindow
= mainWindow
; }
236 virtual bool RowAppended()
237 { return m_mainWindow
->RowAppended(); }
238 virtual bool RowPrepended()
239 { return m_mainWindow
->RowPrepended(); }
240 virtual bool RowInserted( unsigned int before
)
241 { return m_mainWindow
->RowInserted( before
); }
242 virtual bool RowDeleted( unsigned int row
)
243 { return m_mainWindow
->RowDeleted( row
); }
244 virtual bool RowChanged( unsigned int row
)
245 { return m_mainWindow
->RowChanged( row
); }
246 virtual bool ValueChanged( unsigned int col
, unsigned int row
)
247 { return m_mainWindow
->ValueChanged( col
, row
); }
248 virtual bool RowsReordered( unsigned int *new_order
)
249 { return m_mainWindow
->RowsReordered( new_order
); }
250 virtual bool Cleared()
251 { return m_mainWindow
->Cleared(); }
253 wxDataViewMainWindow
*m_mainWindow
;
256 // ---------------------------------------------------------
257 // wxDataViewRenderer
258 // ---------------------------------------------------------
260 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
)
262 wxDataViewRenderer::wxDataViewRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
263 wxDataViewRendererBase( varianttype
, mode
)
268 wxDataViewRenderer::~wxDataViewRenderer()
274 wxDC
*wxDataViewRenderer::GetDC()
278 if (GetOwner() == NULL
)
280 if (GetOwner()->GetOwner() == NULL
)
282 m_dc
= new wxClientDC( GetOwner()->GetOwner() );
288 // ---------------------------------------------------------
289 // wxDataViewCustomRenderer
290 // ---------------------------------------------------------
292 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
)
294 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString
&varianttype
,
295 wxDataViewCellMode mode
) :
296 wxDataViewRenderer( varianttype
, mode
)
300 // ---------------------------------------------------------
301 // wxDataViewTextRenderer
302 // ---------------------------------------------------------
304 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewCustomRenderer
)
306 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
307 wxDataViewCustomRenderer( varianttype
, mode
)
311 bool wxDataViewTextRenderer::SetValue( const wxVariant
&value
)
313 m_text
= value
.GetString();
318 bool wxDataViewTextRenderer::GetValue( wxVariant
& WXUNUSED(value
) )
323 bool wxDataViewTextRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
325 dc
->DrawText( m_text
, cell
.x
, cell
.y
);
330 wxSize
wxDataViewTextRenderer::GetSize()
332 return wxSize(80,20);
335 // ---------------------------------------------------------
336 // wxDataViewBitmapRenderer
337 // ---------------------------------------------------------
339 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewCustomRenderer
)
341 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
) :
342 wxDataViewCustomRenderer( varianttype
, mode
)
346 bool wxDataViewBitmapRenderer::SetValue( const wxVariant
&value
)
348 if (value
.GetType() == wxT("wxBitmap"))
350 if (value
.GetType() == wxT("wxIcon"))
356 bool wxDataViewBitmapRenderer::GetValue( wxVariant
& WXUNUSED(value
) )
361 bool wxDataViewBitmapRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
364 dc
->DrawBitmap( m_bitmap
, cell
.x
, cell
.y
);
365 else if (m_icon
.Ok())
366 dc
->DrawIcon( m_icon
, cell
.x
, cell
.y
);
371 wxSize
wxDataViewBitmapRenderer::GetSize()
374 return wxSize( m_bitmap
.GetWidth(), m_bitmap
.GetHeight() );
375 else if (m_icon
.Ok())
376 return wxSize( m_icon
.GetWidth(), m_icon
.GetHeight() );
378 return wxSize(16,16);
381 // ---------------------------------------------------------
382 // wxDataViewToggleRenderer
383 // ---------------------------------------------------------
385 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleRenderer
, wxDataViewCustomRenderer
)
387 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString
&varianttype
,
388 wxDataViewCellMode mode
) :
389 wxDataViewCustomRenderer( varianttype
, mode
)
394 bool wxDataViewToggleRenderer::SetValue( const wxVariant
&value
)
396 m_toggle
= value
.GetBool();
401 bool wxDataViewToggleRenderer::GetValue( wxVariant
&WXUNUSED(value
) )
406 bool wxDataViewToggleRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
408 // User wxRenderer here
411 rect
.x
= cell
.x
+ cell
.width
/2 - 10;
413 rect
.y
= cell
.y
+ cell
.height
/2 - 10;
418 flags
|= wxCONTROL_CHECKED
;
419 if (GetMode() != wxDATAVIEW_CELL_ACTIVATABLE
)
420 flags
|= wxCONTROL_DISABLED
;
422 wxRendererNative::Get().DrawCheckBox(
423 GetOwner()->GetOwner(),
431 bool wxDataViewToggleRenderer::Activate( wxRect
WXUNUSED(cell
), wxDataViewListModel
*model
, unsigned int col
, unsigned int row
)
433 bool value
= !m_toggle
;
434 wxVariant variant
= value
;
435 model
->SetValue( variant
, col
, row
);
436 model
->ValueChanged( col
, row
);
440 wxSize
wxDataViewToggleRenderer::GetSize()
442 return wxSize(20,20);
445 // ---------------------------------------------------------
446 // wxDataViewProgressRenderer
447 // ---------------------------------------------------------
449 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
)
451 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString
&label
,
452 const wxString
&varianttype
, wxDataViewCellMode mode
) :
453 wxDataViewCustomRenderer( varianttype
, mode
)
459 wxDataViewProgressRenderer::~wxDataViewProgressRenderer()
463 bool wxDataViewProgressRenderer::SetValue( const wxVariant
&value
)
465 m_value
= (long) value
;
467 if (m_value
< 0) m_value
= 0;
468 if (m_value
> 100) m_value
= 100;
473 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
475 double pct
= (double)m_value
/ 100.0;
477 bar
.width
= (int)(cell
.width
* pct
);
478 dc
->SetPen( *wxTRANSPARENT_PEN
);
479 dc
->SetBrush( *wxBLUE_BRUSH
);
480 dc
->DrawRectangle( bar
);
482 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
483 dc
->SetPen( *wxBLACK_PEN
);
484 dc
->DrawRectangle( cell
);
489 wxSize
wxDataViewProgressRenderer::GetSize()
491 return wxSize(40,12);
494 // ---------------------------------------------------------
495 // wxDataViewDateRenderer
496 // ---------------------------------------------------------
498 #define wxUSE_DATE_RENDERER_POPUP (wxUSE_CALENDARCTRL && wxUSE_POPUPWIN)
500 #if wxUSE_DATE_RENDERER_POPUP
502 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
505 wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime
*value
,
506 wxDataViewListModel
*model
, unsigned int col
, unsigned int row
) :
507 wxPopupTransientWindow( parent
, wxBORDER_SIMPLE
)
512 m_cal
= new wxCalendarCtrl( this, wxID_ANY
, *value
);
513 wxBoxSizer
*sizer
= new wxBoxSizer( wxHORIZONTAL
);
514 sizer
->Add( m_cal
, 1, wxGROW
);
519 void OnCalendar( wxCalendarEvent
&event
);
521 wxCalendarCtrl
*m_cal
;
522 wxDataViewListModel
*m_model
;
527 virtual void OnDismiss()
532 DECLARE_EVENT_TABLE()
535 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
)
536 EVT_CALENDAR( wxID_ANY
, wxDataViewDateRendererPopupTransient::OnCalendar
)
539 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent
&event
)
541 wxDateTime date
= event
.GetDate();
542 wxVariant value
= date
;
543 m_model
->SetValue( value
, m_col
, m_row
);
544 m_model
->ValueChanged( m_col
, m_row
);
548 #endif // wxUSE_DATE_RENDERER_POPUP
550 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
)
552 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString
&varianttype
,
553 wxDataViewCellMode mode
) :
554 wxDataViewCustomRenderer( varianttype
, mode
)
558 bool wxDataViewDateRenderer::SetValue( const wxVariant
&value
)
560 m_date
= value
.GetDateTime();
565 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC
*dc
, int WXUNUSED(state
) )
567 dc
->SetFont( GetOwner()->GetOwner()->GetFont() );
568 wxString tmp
= m_date
.FormatDate();
569 dc
->DrawText( tmp
, cell
.x
, cell
.y
);
574 wxSize
wxDataViewDateRenderer::GetSize()
576 wxDataViewCtrl
* view
= GetOwner()->GetOwner();
577 wxString tmp
= m_date
.FormatDate();
579 view
->GetTextExtent( tmp
, &x
, &y
, &d
);
580 return wxSize(x
,y
+d
);
583 bool wxDataViewDateRenderer::Activate( wxRect
WXUNUSED(cell
), wxDataViewListModel
*model
, unsigned int col
, unsigned int row
)
586 model
->GetValue( variant
, col
, row
);
587 wxDateTime value
= variant
.GetDateTime();
589 #if wxUSE_DATE_RENDERER_POPUP
590 wxDataViewDateRendererPopupTransient
*popup
= new wxDataViewDateRendererPopupTransient(
591 GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row
);
592 wxPoint pos
= wxGetMousePosition();
595 popup
->Popup( popup
->m_cal
);
596 #else // !wxUSE_DATE_RENDERER_POPUP
597 wxMessageBox(value
.Format());
598 #endif // wxUSE_DATE_RENDERER_POPUP/!wxUSE_DATE_RENDERER_POPUP
602 // ---------------------------------------------------------
604 // ---------------------------------------------------------
606 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
)
608 wxDataViewColumn::wxDataViewColumn( const wxString
&title
, wxDataViewRenderer
*cell
, unsigned int model_column
,
609 int width
, int flags
) :
610 wxDataViewColumnBase( title
, cell
, model_column
, width
, flags
)
617 wxDataViewColumn::wxDataViewColumn( const wxBitmap
&bitmap
, wxDataViewRenderer
*cell
, unsigned int model_column
,
618 int width
, int flags
) :
619 wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, flags
)
626 void wxDataViewColumn::SetAlignment( wxAlignment
WXUNUSED(align
) )
631 void wxDataViewColumn::SetSortable( bool WXUNUSED(sortable
) )
636 bool wxDataViewColumn::GetSortable()
642 void wxDataViewColumn::SetSortOrder( bool WXUNUSED(ascending
) )
647 bool wxDataViewColumn::IsSortOrderAscending()
654 wxDataViewColumn::~wxDataViewColumn()
658 void wxDataViewColumn::SetTitle( const wxString
&title
)
660 wxDataViewColumnBase::SetTitle( title
);
664 void wxDataViewColumn::SetBitmap( const wxBitmap
&bitmap
)
666 wxDataViewColumnBase::SetBitmap( bitmap
);
670 int wxDataViewColumn::GetWidth()
675 //-----------------------------------------------------------------------------
676 // wxDataViewHeaderWindow
677 //-----------------------------------------------------------------------------
679 IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow
, wxWindow
)
681 BEGIN_EVENT_TABLE(wxDataViewHeaderWindow
,wxWindow
)
682 EVT_PAINT (wxDataViewHeaderWindow::OnPaint
)
683 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse
)
684 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus
)
687 wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
688 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
689 wxWindow( parent
, id
, pos
, size
, 0, name
)
693 m_resizeCursor
= new wxCursor( wxCURSOR_SIZEWE
);
695 wxVisualAttributes attr
= wxPanel::GetClassDefaultAttributes();
696 SetBackgroundStyle( wxBG_STYLE_CUSTOM
);
697 SetOwnForegroundColour( attr
.colFg
);
698 SetOwnBackgroundColour( attr
.colBg
);
700 SetOwnFont( attr
.font
);
703 wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
705 delete m_resizeCursor
;
708 void wxDataViewHeaderWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
711 GetClientSize( &w
, &h
);
713 wxAutoBufferedPaintDC
dc( this );
715 dc
.SetBackground(GetBackgroundColour());
719 m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL
);
722 m_owner
->GetViewStart( &x
, NULL
);
724 // account for the horz scrollbar offset
725 dc
.SetDeviceOrigin( -x
* xpix
, 0 );
727 dc
.SetFont( GetFont() );
729 unsigned int cols
= GetOwner()->GetNumberOfColumns();
732 for (i
= 0; i
< cols
; i
++)
734 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
735 int width
= col
->GetWidth();
740 wxRendererNative::Get().DrawHeaderButton
744 wxRect(xpos
, 0, cw
, ch
-1),
745 m_parent
->IsEnabled() ? 0
746 : (int)wxCONTROL_DISABLED
749 dc
.DrawText( col
->GetTitle(), xpos
+3, 3 );
755 void wxDataViewHeaderWindow::OnMouse( wxMouseEvent
&WXUNUSED(event
) )
759 void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent
&event
)
761 GetParent()->SetFocus();
765 //-----------------------------------------------------------------------------
766 // wxDataViewRenameTimer
767 //-----------------------------------------------------------------------------
769 wxDataViewRenameTimer::wxDataViewRenameTimer( wxDataViewMainWindow
*owner
)
774 void wxDataViewRenameTimer::Notify()
776 m_owner
->OnRenameTimer();
779 //-----------------------------------------------------------------------------
780 // wxDataViewTextCtrlWrapper: wraps a wxTextCtrl for inline editing
781 //-----------------------------------------------------------------------------
783 BEGIN_EVENT_TABLE(wxDataViewTextCtrlWrapper
, wxEvtHandler
)
784 EVT_CHAR (wxDataViewTextCtrlWrapper::OnChar
)
785 EVT_KEY_UP (wxDataViewTextCtrlWrapper::OnKeyUp
)
786 EVT_KILL_FOCUS (wxDataViewTextCtrlWrapper::OnKillFocus
)
789 wxDataViewTextCtrlWrapper::wxDataViewTextCtrlWrapper(
790 wxDataViewMainWindow
*owner
,
792 wxDataViewListModel
*model
,
793 unsigned int col
, unsigned int row
,
803 m_aboutToFinish
= false;
806 model
->GetValue( value
, col
, row
);
807 m_startValue
= value
.GetString();
809 m_owner
->GetOwner()->CalcScrolledPosition(
810 rectLabel
.x
, rectLabel
.y
, &rectLabel
.x
, &rectLabel
.y
);
812 m_text
->Create( owner
, wxID_ANY
, m_startValue
,
813 wxPoint(rectLabel
.x
-2,rectLabel
.y
-2),
814 wxSize(rectLabel
.width
+7,rectLabel
.height
+4) );
817 m_text
->PushEventHandler(this);
820 void wxDataViewTextCtrlWrapper::AcceptChangesAndFinish()
822 m_aboutToFinish
= true;
824 // Notify the owner about the changes
827 // Even if vetoed, close the control (consistent with MSW)
831 void wxDataViewTextCtrlWrapper::OnChar( wxKeyEvent
&event
)
833 switch ( event
.m_keyCode
)
836 AcceptChangesAndFinish();
840 // m_owner->OnRenameCancelled( m_itemEdited );
849 void wxDataViewTextCtrlWrapper::OnKeyUp( wxKeyEvent
&event
)
857 // auto-grow the textctrl
858 wxSize parentSize
= m_owner
->GetSize();
859 wxPoint myPos
= m_text
->GetPosition();
860 wxSize mySize
= m_text
->GetSize();
862 m_text
->GetTextExtent(m_text
->GetValue() + _T("MM"), &sx
, &sy
);
863 if (myPos
.x
+ sx
> parentSize
.x
)
864 sx
= parentSize
.x
- myPos
.x
;
867 m_text
->SetSize(sx
, wxDefaultCoord
);
872 void wxDataViewTextCtrlWrapper::OnKillFocus( wxFocusEvent
&event
)
874 if ( !m_finished
&& !m_aboutToFinish
)
877 //if ( !AcceptChanges() )
878 // m_owner->OnRenameCancelled( m_itemEdited );
883 // We must let the native text control handle focus
887 bool wxDataViewTextCtrlWrapper::AcceptChanges()
889 const wxString value
= m_text
->GetValue();
891 if ( value
== m_startValue
)
892 // nothing changed, always accept
895 // if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
896 // vetoed by the user
899 // accepted, do rename the item
902 m_model
->SetValue( variant
, m_col
, m_row
);
903 m_model
->ValueChanged( m_col
, m_row
);
908 void wxDataViewTextCtrlWrapper::Finish()
914 m_text
->RemoveEventHandler(this);
915 m_owner
->FinishEditing(m_text
);
918 wxPendingDelete
.Append( this );
922 //-----------------------------------------------------------------------------
923 // wxDataViewMainWindow
924 //-----------------------------------------------------------------------------
926 int LINKAGEMODE
wxDataViewSelectionCmp( unsigned int row1
, unsigned int row2
)
928 if (row1
> row2
) return 1;
929 if (row1
== row2
) return 0;
934 IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow
, wxWindow
)
936 BEGIN_EVENT_TABLE(wxDataViewMainWindow
,wxWindow
)
937 EVT_PAINT (wxDataViewMainWindow::OnPaint
)
938 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse
)
939 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus
)
940 EVT_KILL_FOCUS (wxDataViewMainWindow::OnKillFocus
)
941 EVT_CHAR (wxDataViewMainWindow::OnChar
)
944 wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
945 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
946 wxWindow( parent
, id
, pos
, size
, wxWANTS_CHARS
, name
),
947 m_selection( wxDataViewSelectionCmp
)
952 m_lastOnSame
= false;
953 m_renameTimer
= new wxDataViewRenameTimer( this );
954 m_textctrlWrapper
= NULL
;
956 // TODO: user better initial values/nothing selected
960 // TODO: we need to calculate this smartly
964 m_dragStart
= wxPoint(0,0);
965 m_lineLastClicked
= (unsigned int) -1;
966 m_lineBeforeLastClicked
= (unsigned int) -1;
967 m_lineSelectSingleOnUp
= (unsigned int) -1;
971 SetBackgroundStyle( wxBG_STYLE_CUSTOM
);
972 SetBackgroundColour( *wxWHITE
);
977 wxDataViewMainWindow::~wxDataViewMainWindow()
979 delete m_renameTimer
;
982 void wxDataViewMainWindow::OnRenameTimer()
984 // We have to call this here because changes may just have
985 // been made and no screen update taken place.
991 unsigned int cols
= GetOwner()->GetNumberOfColumns();
993 for (i
= 0; i
< cols
; i
++)
995 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
996 if (c
== m_currentCol
)
998 xpos
+= c
->GetWidth();
1000 wxRect
labelRect( xpos
, m_currentRow
* m_lineHeight
, m_currentCol
->GetWidth(), m_lineHeight
);
1002 wxClassInfo
*textControlClass
= CLASSINFO(wxTextCtrl
);
1004 wxTextCtrl
* const text
= (wxTextCtrl
*)textControlClass
->CreateObject();
1005 m_textctrlWrapper
= new wxDataViewTextCtrlWrapper(this, text
, GetOwner()->GetModel(),
1006 m_currentCol
->GetModelColumn(), m_currentRow
, labelRect
);
1009 void wxDataViewMainWindow::FinishEditing( wxTextCtrl
*text
)
1012 m_textctrlWrapper
= NULL
;
1014 // SetFocusIgnoringChildren();
1017 bool wxDataViewMainWindow::RowAppended()
1022 bool wxDataViewMainWindow::RowPrepended()
1027 bool wxDataViewMainWindow::RowInserted( unsigned int WXUNUSED(before
) )
1032 bool wxDataViewMainWindow::RowDeleted( unsigned int WXUNUSED(row
) )
1037 bool wxDataViewMainWindow::RowChanged( unsigned int WXUNUSED(row
) )
1042 bool wxDataViewMainWindow::ValueChanged( unsigned int WXUNUSED(col
), unsigned int row
)
1044 wxRect
rect( 0, row
*m_lineHeight
, 10000, m_lineHeight
);
1045 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1046 Refresh( true, &rect
);
1051 bool wxDataViewMainWindow::RowsReordered( unsigned int *WXUNUSED(new_order
) )
1058 bool wxDataViewMainWindow::Cleared()
1063 void wxDataViewMainWindow::UpdateDisplay()
1068 void wxDataViewMainWindow::OnInternalIdle()
1070 wxWindow::OnInternalIdle();
1074 RecalculateDisplay();
1079 void wxDataViewMainWindow::RecalculateDisplay()
1081 wxDataViewListModel
*model
= GetOwner()->GetModel();
1089 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1091 for (i
= 0; i
< cols
; i
++)
1093 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
1094 width
+= col
->GetWidth();
1097 int height
= model
->GetNumberOfRows() * m_lineHeight
;
1099 SetVirtualSize( width
, height
);
1100 GetOwner()->SetScrollRate( 10, m_lineHeight
);
1105 void wxDataViewMainWindow::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
1107 wxWindow::ScrollWindow( dx
, dy
, rect
);
1108 GetOwner()->m_headerArea
->ScrollWindow( dx
, 0 );
1111 void wxDataViewMainWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1113 wxAutoBufferedPaintDC
dc( this );
1115 dc
.SetBackground(GetBackgroundColour());
1118 GetOwner()->PrepareDC( dc
);
1120 dc
.SetFont( GetFont() );
1122 wxRect update
= GetUpdateRegion().GetBox();
1123 m_owner
->CalcUnscrolledPosition( update
.x
, update
.y
, &update
.x
, &update
.y
);
1125 wxDataViewListModel
*model
= GetOwner()->GetModel();
1127 unsigned int item_start
= wxMax( 0, (update
.y
/ m_lineHeight
) );
1128 unsigned int item_count
= wxMin( (int)(((update
.y
+ update
.height
) / m_lineHeight
) - item_start
+ 1),
1129 (int)(model
->GetNumberOfRows()-item_start
) );
1134 for (item
= item_start
; item
< item_start
+item_count
; item
++)
1136 if (m_selection
.Index( item
) != wxNOT_FOUND
)
1138 int flags
= wxCONTROL_SELECTED
;
1139 if (item
== m_currentRow
)
1140 flags
|= wxCONTROL_CURRENT
;
1142 flags
|= wxCONTROL_FOCUSED
;
1143 wxRect
rect( 0, item
*m_lineHeight
+1, GetEndOfLastCol(), m_lineHeight
-2 );
1144 wxRendererNative::Get().DrawItemSelectionRect
1154 if (item
== m_currentRow
)
1156 int flags
= wxCONTROL_CURRENT
;
1158 flags
|= wxCONTROL_FOCUSED
; // should have no effect
1159 wxRect
rect( 0, item
*m_lineHeight
+1, GetEndOfLastCol(), m_lineHeight
-2 );
1160 wxRendererNative::Get().DrawItemSelectionRect
1174 cell_rect
.height
= m_lineHeight
;
1175 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1177 for (i
= 0; i
< cols
; i
++)
1179 wxDataViewColumn
*col
= GetOwner()->GetColumn( i
);
1180 wxDataViewRenderer
*cell
= col
->GetRenderer();
1181 cell_rect
.width
= col
->GetWidth();
1183 for (item
= item_start
; item
< item_start
+item_count
; item
++)
1185 cell_rect
.y
= item
*m_lineHeight
;
1187 model
->GetValue( value
, col
->GetModelColumn(), item
);
1188 cell
->SetValue( value
);
1189 wxSize size
= cell
->GetSize();
1190 // cannot be bigger than allocated space
1191 size
.x
= wxMin( size
.x
, cell_rect
.width
);
1192 size
.y
= wxMin( size
.y
, cell_rect
.height
);
1193 // TODO: check for left/right/centre alignment here
1196 item_rect
.x
= cell_rect
.x
+ (cell_rect
.width
/ 2) - (size
.x
/ 2);
1197 item_rect
.y
= cell_rect
.y
+ (cell_rect
.height
/ 2) - (size
.y
/ 2);
1199 item_rect
.width
= size
.x
;
1200 item_rect
.height
= size
.y
;
1203 if (item
== m_currentRow
)
1204 state
|= wxDATAVIEW_CELL_SELECTED
;
1205 cell
->Render( item_rect
, &dc
, state
);
1208 cell_rect
.x
+= cell_rect
.width
;
1212 int wxDataViewMainWindow::GetCountPerPage()
1214 wxSize size
= GetClientSize();
1215 return size
.y
/ m_lineHeight
;
1218 int wxDataViewMainWindow::GetEndOfLastCol()
1222 for (i
= 0; i
< GetOwner()->GetNumberOfColumns(); i
++)
1224 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
1225 width
+= c
->GetWidth();
1230 unsigned int wxDataViewMainWindow::GetFirstVisibleRow()
1234 m_owner
->CalcUnscrolledPosition( x
, y
, &x
, &y
);
1236 return y
/ m_lineHeight
;
1239 unsigned int wxDataViewMainWindow::GetLastVisibleRow()
1241 wxSize client_size
= GetClientSize();
1242 m_owner
->CalcUnscrolledPosition( client_size
.x
, client_size
.y
, &client_size
.x
, &client_size
.y
);
1244 return wxMin( GetRowCount()-1, ((unsigned)client_size
.y
/m_lineHeight
)+1 );
1247 unsigned int wxDataViewMainWindow::GetRowCount()
1249 return GetOwner()->GetModel()->GetNumberOfRows();
1252 void wxDataViewMainWindow::ChangeCurrentRow( unsigned int row
)
1259 void wxDataViewMainWindow::SelectAllRows( bool on
)
1266 m_selection
.Clear();
1267 for (unsigned int i
= 0; i
< GetRowCount(); i
++)
1268 m_selection
.Add( i
);
1273 unsigned int first_visible
= GetFirstVisibleRow();
1274 unsigned int last_visible
= GetLastVisibleRow();
1276 for (i
= 0; i
< m_selection
.GetCount(); i
++)
1278 unsigned int row
= m_selection
[i
];
1279 if ((row
>= first_visible
) && (row
<= last_visible
))
1282 m_selection
.Clear();
1286 void wxDataViewMainWindow::SelectRow( unsigned int row
, bool on
)
1288 if (m_selection
.Index( row
) == wxNOT_FOUND
)
1292 m_selection
.Add( row
);
1300 m_selection
.Remove( row
);
1306 void wxDataViewMainWindow::SelectRows( unsigned int from
, unsigned int to
, bool on
)
1310 unsigned int tmp
= from
;
1316 for (i
= from
; i
<= to
; i
++)
1318 if (m_selection
.Index( i
) == wxNOT_FOUND
)
1321 m_selection
.Add( i
);
1326 m_selection
.Remove( i
);
1329 RefreshRows( from
, to
);
1332 void wxDataViewMainWindow::ReverseRowSelection( unsigned int row
)
1334 if (m_selection
.Index( row
) == wxNOT_FOUND
)
1335 m_selection
.Add( row
);
1337 m_selection
.Remove( row
);
1341 bool wxDataViewMainWindow::IsRowSelected( unsigned int row
)
1343 return (m_selection
.Index( row
) != wxNOT_FOUND
);
1346 void wxDataViewMainWindow::RefreshRow( unsigned int row
)
1348 wxRect
rect( 0, row
*m_lineHeight
, GetEndOfLastCol(), m_lineHeight
);
1349 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1351 wxSize client_size
= GetClientSize();
1352 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1353 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1354 if (intersect_rect
.width
> 0)
1355 Refresh( true, &intersect_rect
);
1358 void wxDataViewMainWindow::RefreshRows( unsigned int from
, unsigned int to
)
1362 unsigned int tmp
= to
;
1367 wxRect
rect( 0, from
*m_lineHeight
, GetEndOfLastCol(), (to
-from
+1) * m_lineHeight
);
1368 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1370 wxSize client_size
= GetClientSize();
1371 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1372 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1373 if (intersect_rect
.width
> 0)
1374 Refresh( true, &intersect_rect
);
1377 void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow
)
1379 unsigned int count
= GetRowCount();
1380 if (firstRow
> count
)
1383 wxRect
rect( 0, firstRow
*m_lineHeight
, GetEndOfLastCol(), count
* m_lineHeight
);
1384 m_owner
->CalcScrolledPosition( rect
.x
, rect
.y
, &rect
.x
, &rect
.y
);
1386 wxSize client_size
= GetClientSize();
1387 wxRect
client_rect( 0, 0, client_size
.x
, client_size
.y
);
1388 wxRect intersect_rect
= client_rect
.Intersect( rect
);
1389 if (intersect_rect
.width
> 0)
1390 Refresh( true, &intersect_rect
);
1393 void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent
, const wxKeyEvent
& event
)
1395 wxCHECK_RET( newCurrent
< GetRowCount(),
1396 _T("invalid item index in OnArrowChar()") );
1398 // if there is no selection, we cannot move it anywhere
1399 if (!HasCurrentRow())
1402 unsigned int oldCurrent
= m_currentRow
;
1404 // in single selection we just ignore Shift as we can't select several
1406 if ( event
.ShiftDown() && !IsSingleSel() )
1408 RefreshRow( oldCurrent
);
1410 ChangeCurrentRow( newCurrent
);
1412 // select all the items between the old and the new one
1413 if ( oldCurrent
> newCurrent
)
1415 newCurrent
= oldCurrent
;
1416 oldCurrent
= m_currentRow
;
1419 SelectRows( oldCurrent
, newCurrent
, true );
1423 RefreshRow( oldCurrent
);
1425 // all previously selected items are unselected unless ctrl is held
1426 if ( !event
.ControlDown() )
1427 SelectAllRows(false);
1429 ChangeCurrentRow( newCurrent
);
1431 if ( !event
.ControlDown() )
1432 SelectRow( m_currentRow
, true );
1434 RefreshRow( m_currentRow
);
1440 void wxDataViewMainWindow::OnChar( wxKeyEvent
&event
)
1442 if (event
.GetKeyCode() == WXK_TAB
)
1444 wxNavigationKeyEvent nevent
;
1445 nevent
.SetWindowChange( event
.ControlDown() );
1446 nevent
.SetDirection( !event
.ShiftDown() );
1447 nevent
.SetEventObject( GetParent()->GetParent() );
1448 nevent
.SetCurrentFocus( m_parent
);
1449 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent
))
1453 // no item -> nothing to do
1454 if (!HasCurrentRow())
1460 // don't use m_linesPerPage directly as it might not be computed yet
1461 const int pageSize
= GetCountPerPage();
1462 wxCHECK_RET( pageSize
, _T("should have non zero page size") );
1464 switch ( event
.GetKeyCode() )
1467 if ( m_currentRow
> 0 )
1468 OnArrowChar( m_currentRow
- 1, event
);
1472 if ( m_currentRow
< GetRowCount() - 1 )
1473 OnArrowChar( m_currentRow
+ 1, event
);
1478 OnArrowChar( GetRowCount() - 1, event
);
1483 OnArrowChar( 0, event
);
1488 int steps
= pageSize
- 1;
1489 int index
= m_currentRow
- steps
;
1493 OnArrowChar( index
, event
);
1499 int steps
= pageSize
- 1;
1500 unsigned int index
= m_currentRow
+ steps
;
1501 unsigned int count
= GetRowCount();
1502 if ( index
>= count
)
1505 OnArrowChar( index
, event
);
1514 void wxDataViewMainWindow::OnMouse( wxMouseEvent
&event
)
1516 if (event
.GetEventType() == wxEVT_MOUSEWHEEL
)
1518 // let the base handle mouse wheel events.
1523 int x
= event
.GetX();
1524 int y
= event
.GetY();
1525 m_owner
->CalcUnscrolledPosition( x
, y
, &x
, &y
);
1527 wxDataViewColumn
*col
= NULL
;
1530 unsigned int cols
= GetOwner()->GetNumberOfColumns();
1532 for (i
= 0; i
< cols
; i
++)
1534 wxDataViewColumn
*c
= GetOwner()->GetColumn( i
);
1535 if (x
< xpos
+ c
->GetWidth())
1540 xpos
+= c
->GetWidth();
1544 wxDataViewRenderer
*cell
= col
->GetRenderer();
1546 unsigned int current
= y
/ m_lineHeight
;
1548 if ((current
> GetRowCount()) || (x
> GetEndOfLastCol()))
1550 // Unselect all if below the last row ?
1554 wxDataViewListModel
*model
= GetOwner()->GetModel();
1556 if (event
.Dragging())
1558 if (m_dragCount
== 0)
1560 // we have to report the raw, physical coords as we want to be
1561 // able to call HitTest(event.m_pointDrag) from the user code to
1562 // get the item being dragged
1563 m_dragStart
= event
.GetPosition();
1568 if (m_dragCount
!= 3)
1571 if (event
.LeftIsDown())
1573 // Notify cell about drag
1582 bool forceClick
= false;
1584 if (event
.ButtonDClick())
1586 m_renameTimer
->Stop();
1587 m_lastOnSame
= false;
1590 if (event
.LeftDClick())
1592 if ( current
== m_lineLastClicked
)
1594 if (cell
->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE
)
1597 model
->GetValue( value
, col
->GetModelColumn(), current
);
1598 cell
->SetValue( value
);
1599 wxRect
cell_rect( xpos
, current
* m_lineHeight
, col
->GetWidth(), m_lineHeight
);
1600 cell
->Activate( cell_rect
, model
, col
->GetModelColumn(), current
);
1606 // The first click was on another item, so don't interpret this as
1607 // a double click, but as a simple click instead
1614 if (m_lineSelectSingleOnUp
!= (unsigned int)-1)
1616 // select single line
1617 SelectAllRows( false );
1618 SelectRow( m_lineSelectSingleOnUp
, true );
1623 if ((col
== m_currentCol
) && (current
== m_currentRow
) &&
1624 (cell
->GetMode() == wxDATAVIEW_CELL_EDITABLE
) )
1626 m_renameTimer
->Start( 100, true );
1630 m_lastOnSame
= false;
1631 m_lineSelectSingleOnUp
= (unsigned int)-1;
1635 // This is necessary, because after a DnD operation in
1636 // from and to ourself, the up event is swallowed by the
1637 // DnD code. So on next non-up event (which means here and
1638 // now) m_lineSelectSingleOnUp should be reset.
1639 m_lineSelectSingleOnUp
= (unsigned int)-1;
1642 if (event
.RightDown())
1644 m_lineBeforeLastClicked
= m_lineLastClicked
;
1645 m_lineLastClicked
= current
;
1647 // If the item is already selected, do not update the selection.
1648 // Multi-selections should not be cleared if a selected item is clicked.
1649 if (!IsRowSelected(current
))
1651 SelectAllRows(false);
1652 ChangeCurrentRow(current
);
1653 SelectRow(m_currentRow
,true);
1656 // notify cell about right click
1659 // Allow generation of context menu event
1662 else if (event
.MiddleDown())
1664 // notify cell about middle click
1667 if (event
.LeftDown() || forceClick
)
1673 m_lineBeforeLastClicked
= m_lineLastClicked
;
1674 m_lineLastClicked
= current
;
1676 unsigned int oldCurrentRow
= m_currentRow
;
1677 bool oldWasSelected
= IsRowSelected(m_currentRow
);
1679 bool cmdModifierDown
= event
.CmdDown();
1680 if ( IsSingleSel() || !(cmdModifierDown
|| event
.ShiftDown()) )
1682 if ( IsSingleSel() || !IsRowSelected(current
) )
1684 SelectAllRows( false );
1686 ChangeCurrentRow(current
);
1688 SelectRow(m_currentRow
,true);
1690 else // multi sel & current is highlighted & no mod keys
1692 m_lineSelectSingleOnUp
= current
;
1693 ChangeCurrentRow(current
); // change focus
1696 else // multi sel & either ctrl or shift is down
1698 if (cmdModifierDown
)
1700 ChangeCurrentRow(current
);
1702 ReverseRowSelection(m_currentRow
);
1704 else if (event
.ShiftDown())
1706 ChangeCurrentRow(current
);
1708 unsigned int lineFrom
= oldCurrentRow
,
1711 if ( lineTo
< lineFrom
)
1714 lineFrom
= m_currentRow
;
1717 SelectRows(lineFrom
, lineTo
, true);
1719 else // !ctrl, !shift
1721 // test in the enclosing if should make it impossible
1722 wxFAIL_MSG( _T("how did we get here?") );
1726 if (m_currentRow
!= oldCurrentRow
)
1727 RefreshRow( oldCurrentRow
);
1729 wxDataViewColumn
*oldCurrentCol
= m_currentCol
;
1731 // Update selection here...
1734 m_lastOnSame
= !forceClick
&& ((col
== oldCurrentCol
) && (current
== oldCurrentRow
)) && oldWasSelected
;
1738 void wxDataViewMainWindow::OnSetFocus( wxFocusEvent
&event
)
1742 if (HasCurrentRow())
1748 void wxDataViewMainWindow::OnKillFocus( wxFocusEvent
&event
)
1752 if (HasCurrentRow())
1758 //-----------------------------------------------------------------------------
1760 //-----------------------------------------------------------------------------
1762 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
)
1764 BEGIN_EVENT_TABLE(wxDataViewCtrl
, wxDataViewCtrlBase
)
1765 EVT_SIZE(wxDataViewCtrl::OnSize
)
1768 wxDataViewCtrl::~wxDataViewCtrl()
1771 GetModel()->RemoveNotifier( m_notifier
);
1774 void wxDataViewCtrl::Init()
1779 bool wxDataViewCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1780 const wxPoint
& pos
, const wxSize
& size
,
1781 long style
, const wxValidator
& validator
)
1783 if (!wxControl::Create( parent
, id
, pos
, size
, style
| wxScrolledWindowStyle
|wxSUNKEN_BORDER
, validator
))
1789 MacSetClipChildren( true ) ;
1792 m_clientArea
= new wxDataViewMainWindow( this, wxID_ANY
);
1794 m_headerArea
= new wxDataViewHeaderWindow( this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,22) );
1796 m_headerArea
= new wxDataViewHeaderWindow( this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,25) );
1799 SetTargetWindow( m_clientArea
);
1801 wxBoxSizer
*sizer
= new wxBoxSizer( wxVERTICAL
);
1802 sizer
->Add( m_headerArea
, 0, wxGROW
);
1803 sizer
->Add( m_clientArea
, 1, wxGROW
);
1810 WXLRESULT
wxDataViewCtrl::MSWWindowProc(WXUINT nMsg
,
1814 WXLRESULT rc
= wxDataViewCtrlBase::MSWWindowProc(nMsg
, wParam
, lParam
);
1817 // we need to process arrows ourselves for scrolling
1818 if ( nMsg
== WM_GETDLGCODE
)
1820 rc
|= DLGC_WANTARROWS
;
1828 void wxDataViewCtrl::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1830 // We need to override OnSize so that our scrolled
1831 // window a) does call Layout() to use sizers for
1832 // positioning the controls but b) does not query
1833 // the sizer for their size and use that for setting
1834 // the scrollable area as set that ourselves by
1835 // calling SetScrollbar() further down.
1842 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel
*model
)
1844 if (!wxDataViewCtrlBase::AssociateModel( model
))
1847 m_notifier
= new wxGenericDataViewListModelNotifier( m_clientArea
);
1849 model
->AddNotifier( m_notifier
);
1851 m_clientArea
->UpdateDisplay();
1856 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn
*col
)
1858 if (!wxDataViewCtrlBase::AppendColumn(col
))
1861 m_clientArea
->UpdateDisplay();
1866 void wxDataViewCtrl::SetSelection( int WXUNUSED(row
) )
1871 void wxDataViewCtrl::SetSelectionRange( unsigned int WXUNUSED(from
), unsigned int WXUNUSED(to
) )
1876 void wxDataViewCtrl::SetSelections( const wxArrayInt
& WXUNUSED(aSelections
) )
1881 void wxDataViewCtrl::Unselect( unsigned int WXUNUSED(row
) )
1886 bool wxDataViewCtrl::IsSelected( unsigned int WXUNUSED(row
) ) const
1893 int wxDataViewCtrl::GetSelection() const
1900 int wxDataViewCtrl::GetSelections(wxArrayInt
& WXUNUSED(aSelections
) ) const
1908 // !wxUSE_GENERICDATAVIEWCTRL
1911 // wxUSE_DATAVIEWCTRL