1 /////////////////////////////////////////////////////////////////////////////
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"
15 #if wxUSE_DATAVIEWCTRL
17 #include "wx/dataview.h"
19 #ifdef wxUSE_GENERICDATAVIEWCTRL
21 #include "wx/stockitem.h"
22 #include "wx/dcclient.h"
23 #include "wx/calctrl.h"
24 #include "wx/popupwin.h"
27 #include "wx/renderer.h"
30 #include <windows.h> // for DLGC_WANTARROWS
31 #include "wx/msw/winundef.h"
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
40 // ---------------------------------------------------------
41 // wxGenericDataViewListModelNotifier
42 // ---------------------------------------------------------
44 class wxGenericDataViewListModelNotifier
: public wxDataViewListModelNotifier
47 wxGenericDataViewListModelNotifier( wxDataViewListModel
*wx_model
);
49 virtual bool RowAppended();
50 virtual bool RowPrepended();
51 virtual bool RowInserted( size_t before
);
52 virtual bool RowDeleted( size_t row
);
53 virtual bool RowChanged( size_t row
);
54 virtual bool ValueChanged( size_t col
, size_t row
);
55 virtual bool RowsReordered( size_t *new_order
);
56 virtual bool Cleared();
58 wxDataViewListModel
*m_wx_model
;
61 // ---------------------------------------------------------
62 // wxGenericDataViewListModelNotifier
63 // ---------------------------------------------------------
65 wxGenericDataViewListModelNotifier::wxGenericDataViewListModelNotifier(
66 wxDataViewListModel
*wx_model
)
68 m_wx_model
= wx_model
;
71 bool wxGenericDataViewListModelNotifier::RowAppended()
73 size_t pos
= m_wx_model
->GetNumberOfRows()-1;
78 bool wxGenericDataViewListModelNotifier::RowPrepended()
83 bool wxGenericDataViewListModelNotifier::RowInserted( size_t before
)
88 bool wxGenericDataViewListModelNotifier::RowDeleted( size_t row
)
93 bool wxGenericDataViewListModelNotifier::RowChanged( size_t row
)
98 bool wxGenericDataViewListModelNotifier::ValueChanged( size_t model_col
, size_t model_row
)
100 wxNode
*node
= GetOwner()->m_viewingColumns
.GetFirst();
103 wxDataViewViewingColumn
* viewing_column
= (wxDataViewViewingColumn
*) node
->GetData();
104 if (viewing_column
->m_modelColumn
== model_col
)
109 node
= node
->GetNext();
115 bool wxGenericDataViewListModelNotifier::RowsReordered( size_t *new_order
)
117 wxNode
*node
= GetOwner()->m_viewingColumns
.GetFirst();
120 wxDataViewViewingColumn
* viewing_column
= (wxDataViewViewingColumn
*) node
->GetData();
122 node
= node
->GetNext();
128 bool wxGenericDataViewListModelNotifier::Cleared()
133 // ---------------------------------------------------------
135 // ---------------------------------------------------------
137 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCell
, wxDataViewCellBase
)
139 wxDataViewCell::wxDataViewCell( const wxString
&varianttype
, wxDataViewCellMode mode
) :
140 wxDataViewCellBase( varianttype
, mode
)
144 // ---------------------------------------------------------
145 // wxDataViewTextCell
146 // ---------------------------------------------------------
148 IMPLEMENT_ABSTRACT_CLASS(wxDataViewTextCell
, wxDataViewCell
)
150 wxDataViewTextCell::wxDataViewTextCell( const wxString
&varianttype
, wxDataViewCellMode mode
) :
151 wxDataViewCell( varianttype
, mode
)
155 bool wxDataViewTextCell::SetValue( const wxVariant
&value
)
160 bool wxDataViewTextCell::GetValue( wxVariant
&value
)
165 // ---------------------------------------------------------
166 // wxDataViewToggleCell
167 // ---------------------------------------------------------
169 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleCell
, wxDataViewCell
)
171 wxDataViewToggleCell::wxDataViewToggleCell( const wxString
&varianttype
,
172 wxDataViewCellMode mode
) :
173 wxDataViewCell( varianttype
, mode
)
177 bool wxDataViewToggleCell::SetValue( const wxVariant
&value
)
182 bool wxDataViewToggleCell::GetValue( wxVariant
&value
)
187 // ---------------------------------------------------------
188 // wxDataViewCustomCell
189 // ---------------------------------------------------------
191 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomCell
, wxDataViewCell
)
193 wxDataViewCustomCell::wxDataViewCustomCell( const wxString
&varianttype
,
194 wxDataViewCellMode mode
) :
195 wxDataViewCell( varianttype
, mode
)
202 bool wxDataViewCustomCell::Init()
207 wxDataViewCustomCell::~wxDataViewCustomCell()
213 wxDC
*wxDataViewCustomCell::GetDC()
217 if (GetOwner() == NULL
)
219 if (GetOwner()->GetOwner() == NULL
)
221 m_dc
= new wxClientDC( GetOwner()->GetOwner() );
227 // ---------------------------------------------------------
228 // wxDataViewProgressCell
229 // ---------------------------------------------------------
231 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressCell
, wxDataViewCustomCell
)
233 wxDataViewProgressCell::wxDataViewProgressCell( const wxString
&label
,
234 const wxString
&varianttype
, wxDataViewCellMode mode
) :
235 wxDataViewCustomCell( varianttype
, mode
)
241 wxDataViewProgressCell::~wxDataViewProgressCell()
245 bool wxDataViewProgressCell::SetValue( const wxVariant
&value
)
247 m_value
= (long) value
;
249 if (m_value
< 0) m_value
= 0;
250 if (m_value
> 100) m_value
= 100;
255 bool wxDataViewProgressCell::Render( wxRect cell
, wxDC
*dc
, int state
)
257 double pct
= (double)m_value
/ 100.0;
259 bar
.width
= (int)(cell
.width
* pct
);
260 dc
->SetPen( *wxTRANSPARENT_PEN
);
261 dc
->SetBrush( *wxBLUE_BRUSH
);
262 dc
->DrawRectangle( bar
);
264 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
265 dc
->SetPen( *wxBLACK_PEN
);
266 dc
->DrawRectangle( cell
);
271 wxSize
wxDataViewProgressCell::GetSize()
273 return wxSize(40,12);
276 // ---------------------------------------------------------
277 // wxDataViewDateCell
278 // ---------------------------------------------------------
280 class wxDataViewDateCellPopupTransient
: public wxPopupTransientWindow
283 wxDataViewDateCellPopupTransient( wxWindow
* parent
, wxDateTime
*value
,
284 wxDataViewListModel
*model
, size_t col
, size_t row
) :
285 wxPopupTransientWindow( parent
, wxBORDER_SIMPLE
)
290 m_cal
= new wxCalendarCtrl( this, -1, *value
);
291 wxBoxSizer
*sizer
= new wxBoxSizer( wxHORIZONTAL
);
292 sizer
->Add( m_cal
, 1, wxGROW
);
297 virtual void OnDismiss()
301 void OnCalendar( wxCalendarEvent
&event
);
303 wxCalendarCtrl
*m_cal
;
304 wxDataViewListModel
*m_model
;
309 DECLARE_EVENT_TABLE()
312 BEGIN_EVENT_TABLE(wxDataViewDateCellPopupTransient
,wxPopupTransientWindow
)
313 EVT_CALENDAR( -1, wxDataViewDateCellPopupTransient::OnCalendar
)
316 void wxDataViewDateCellPopupTransient::OnCalendar( wxCalendarEvent
&event
)
318 wxDateTime date
= event
.GetDate();
319 wxVariant value
= date
;
320 m_model
->SetValue( value
, m_col
, m_row
);
321 m_model
->ValueChanged( m_col
, m_row
);
325 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateCell
, wxDataViewCustomCell
)
327 wxDataViewDateCell::wxDataViewDateCell( const wxString
&varianttype
,
328 wxDataViewCellMode mode
) :
329 wxDataViewCustomCell( varianttype
, mode
)
333 bool wxDataViewDateCell::SetValue( const wxVariant
&value
)
335 m_date
= value
.GetDateTime();
340 bool wxDataViewDateCell::Render( wxRect cell
, wxDC
*dc
, int state
)
342 dc
->SetFont( GetOwner()->GetOwner()->GetFont() );
343 wxString tmp
= m_date
.FormatDate();
344 dc
->DrawText( tmp
, cell
.x
, cell
.y
);
349 wxSize
wxDataViewDateCell::GetSize()
351 wxDataViewCtrl
* view
= GetOwner()->GetOwner();
352 wxString tmp
= m_date
.FormatDate();
354 view
->GetTextExtent( tmp
, &x
, &y
, &d
);
355 return wxSize(x
,y
+d
);
358 bool wxDataViewDateCell::Activate( wxRect cell
, wxDataViewListModel
*model
, size_t col
, size_t row
)
361 model
->GetValue( variant
, col
, row
);
362 wxDateTime value
= variant
.GetDateTime();
364 wxDataViewDateCellPopupTransient
*popup
= new wxDataViewDateCellPopupTransient(
365 GetOwner()->GetOwner()->GetParent(), &value
, model
, col
, row
);
366 wxPoint pos
= wxGetMousePosition();
369 popup
->Popup( popup
->m_cal
);
374 // ---------------------------------------------------------
376 // ---------------------------------------------------------
378 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
)
380 wxDataViewColumn::wxDataViewColumn( const wxString
&title
, wxDataViewCell
*cell
,
381 size_t model_column
, int flags
) :
382 wxDataViewColumnBase( title
, cell
, model_column
, flags
)
386 wxDataViewColumn::~wxDataViewColumn()
390 void wxDataViewColumn::SetTitle( const wxString
&title
)
392 wxDataViewColumnBase::SetTitle( title
);
396 //-----------------------------------------------------------------------------
397 // wxDataViewHeaderWindow
398 //-----------------------------------------------------------------------------
400 class wxDataViewHeaderWindow
: public wxWindow
403 wxDataViewHeaderWindow( wxDataViewCtrl
*parent
,
405 const wxPoint
&pos
= wxDefaultPosition
,
406 const wxSize
&size
= wxDefaultSize
,
407 const wxString
&name
= wxT("wxdataviewctrlheaderwindow") );
408 ~wxDataViewHeaderWindow();
410 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
411 wxDataViewCtrl
*GetOwner() { return m_owner
; }
413 void OnPaint( wxPaintEvent
&event
);
414 void OnMouse( wxMouseEvent
&event
);
415 void OnSetFocus( wxFocusEvent
&event
);
418 wxDataViewCtrl
*m_owner
;
419 wxCursor
*m_resizeCursor
;
422 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow
)
423 DECLARE_EVENT_TABLE()
426 IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow
, wxWindow
)
428 BEGIN_EVENT_TABLE(wxDataViewHeaderWindow
,wxWindow
)
429 EVT_PAINT (wxDataViewHeaderWindow::OnPaint
)
430 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse
)
431 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus
)
434 wxDataViewHeaderWindow::wxDataViewHeaderWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
435 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
436 wxWindow( parent
, id
, pos
, size
, 0, name
)
440 m_resizeCursor
= new wxCursor( wxCURSOR_SIZEWE
);
442 wxVisualAttributes attr
= wxPanel::GetClassDefaultAttributes();
443 SetOwnForegroundColour( attr
.colFg
);
444 SetOwnBackgroundColour( attr
.colBg
);
446 SetOwnFont( attr
.font
);
449 wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
451 delete m_resizeCursor
;
454 void wxDataViewHeaderWindow::OnPaint( wxPaintEvent
&event
)
460 m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL
);
463 m_owner
->GetViewStart( &x
, NULL
);
465 // account for the horz scrollbar offset
466 dc
.SetDeviceOrigin( -x
* xpix
, 0 );
468 dc
.SetFont( GetFont() );
470 dc
.DrawText( wxT("This is the header.."), 5, 5 );
473 void wxDataViewHeaderWindow::OnMouse( wxMouseEvent
&event
)
477 void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent
&event
)
482 //-----------------------------------------------------------------------------
483 // wxDataViewMainWindow
484 //-----------------------------------------------------------------------------
486 class wxDataViewMainWindow
: public wxWindow
489 wxDataViewMainWindow( wxDataViewCtrl
*parent
,
491 const wxPoint
&pos
= wxDefaultPosition
,
492 const wxSize
&size
= wxDefaultSize
,
493 const wxString
&name
= wxT("wxdataviewctrlmainwindow") );
494 ~wxDataViewMainWindow();
496 void SetOwner( wxDataViewCtrl
* owner
) { m_owner
= owner
; }
497 wxDataViewCtrl
*GetOwner() { return m_owner
; }
499 void OnPaint( wxPaintEvent
&event
);
500 void OnMouse( wxMouseEvent
&event
);
501 void OnSetFocus( wxFocusEvent
&event
);
504 wxDataViewCtrl
*m_owner
;
507 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow
)
508 DECLARE_EVENT_TABLE()
511 IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow
, wxWindow
)
513 BEGIN_EVENT_TABLE(wxDataViewMainWindow
,wxWindow
)
514 EVT_PAINT (wxDataViewMainWindow::OnPaint
)
515 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse
)
516 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus
)
519 wxDataViewMainWindow::wxDataViewMainWindow( wxDataViewCtrl
*parent
, wxWindowID id
,
520 const wxPoint
&pos
, const wxSize
&size
, const wxString
&name
) :
521 wxWindow( parent
, id
, pos
, size
, 0, name
)
526 wxDataViewMainWindow::~wxDataViewMainWindow()
530 void wxDataViewMainWindow::OnPaint( wxPaintEvent
&event
)
532 wxPaintDC
dc( this );
537 m_owner
->CalcScrolledPosition( 0, 0, &dev_x
, &dev_y
);
539 dc
.SetFont( GetFont() );
541 dc
.DrawText( wxT("main window"), 5, 5 );
544 void wxDataViewMainWindow::OnMouse( wxMouseEvent
&event
)
549 void wxDataViewMainWindow::OnSetFocus( wxFocusEvent
&event
)
554 //-----------------------------------------------------------------------------
556 //-----------------------------------------------------------------------------
558 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
)
560 wxDataViewCtrl::~wxDataViewCtrl()
563 GetModel()->RemoveNotifier( m_notifier
);
566 void wxDataViewCtrl::Init()
571 bool wxDataViewCtrl::Create(wxWindow
*parent
, wxWindowID id
,
572 const wxPoint
& pos
, const wxSize
& size
,
573 long style
, const wxValidator
& validator
)
578 MacSetClipChildren( true ) ;
581 m_clientArea
= new wxDataViewMainWindow( this, -1 );
582 m_headerArea
= new wxDataViewHeaderWindow( this, -1, wxDefaultPosition
, wxSize(-1,25) );
584 SetTargetWindow( m_clientArea
);
586 wxBoxSizer
*sizer
= new wxBoxSizer( wxVERTICAL
);
587 sizer
->Add( m_headerArea
, 0, wxGROW
);
588 sizer
->Add( m_clientArea
, 1, wxGROW
);
595 WXLRESULT
wxDataViewCtrl::MSWWindowProc(WXUINT nMsg
,
599 WXLRESULT rc
= wxPanel::MSWWindowProc(nMsg
, wParam
, lParam
);
602 // we need to process arrows ourselves for scrolling
603 if ( nMsg
== WM_GETDLGCODE
)
605 rc
|= DLGC_WANTARROWS
;
613 void wxDataViewCtrl::ScrollWindow( int dx
, int dy
, const wxRect
*rect
)
615 wxDataViewCtrlBase::ScrollWindow( dx
, dy
, rect
);
616 m_headerArea
->ScrollWindow( dx
, 0, rect
);
619 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel
*model
)
621 if (!wxDataViewCtrlBase::AssociateModel( model
))
624 m_notifier
= new wxGenericDataViewListModelNotifier( model
);
626 model
->AddNotifier( m_notifier
);
631 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn
*col
)
633 if (!wxDataViewCtrlBase::AppendColumn(col
))
640 // !wxUSE_GENERICDATAVIEWCTRL
643 // wxUSE_DATAVIEWCTRL