]> git.saurik.com Git - wxWidgets.git/blob - src/generic/datavgen.cpp
41af9707f1f758a80e4e69d35f67a4d8cf4893cb
[wxWidgets.git] / src / generic / datavgen.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: datavgen.cpp
3 // Purpose: wxDataViewCtrl generic implementation
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #include "wx/defs.h"
14
15 #if wxUSE_DATAVIEWCTRL
16
17 #include "wx/dataview.h"
18
19 #ifdef wxUSE_GENERICDATAVIEWCTRL
20
21 #include "wx/stockitem.h"
22 #include "wx/dcclient.h"
23 #include "wx/calctrl.h"
24 #include "wx/popupwin.h"
25 #include "wx/sizer.h"
26 #include "wx/log.h"
27 #include "wx/renderer.h"
28
29 #ifdef __WXMSW__
30 #include <windows.h> // for DLGC_WANTARROWS
31 #include "wx/msw/winundef.h"
32 #endif
33
34 //-----------------------------------------------------------------------------
35 // classes
36 //-----------------------------------------------------------------------------
37
38 class wxDataViewCtrl;
39
40 // ---------------------------------------------------------
41 // wxGenericDataViewListModelNotifier
42 // ---------------------------------------------------------
43
44 class wxGenericDataViewListModelNotifier: public wxDataViewListModelNotifier
45 {
46 public:
47 wxGenericDataViewListModelNotifier( wxDataViewListModel *wx_model );
48
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();
57
58 wxDataViewListModel *m_wx_model;
59 };
60
61 // ---------------------------------------------------------
62 // wxGenericDataViewListModelNotifier
63 // ---------------------------------------------------------
64
65 wxGenericDataViewListModelNotifier::wxGenericDataViewListModelNotifier(
66 wxDataViewListModel *wx_model )
67 {
68 m_wx_model = wx_model;
69 }
70
71 bool wxGenericDataViewListModelNotifier::RowAppended()
72 {
73 size_t pos = m_wx_model->GetNumberOfRows()-1;
74
75 return false;
76 }
77
78 bool wxGenericDataViewListModelNotifier::RowPrepended()
79 {
80 return false;
81 }
82
83 bool wxGenericDataViewListModelNotifier::RowInserted( size_t before )
84 {
85 return false;
86 }
87
88 bool wxGenericDataViewListModelNotifier::RowDeleted( size_t row )
89 {
90 return false;
91 }
92
93 bool wxGenericDataViewListModelNotifier::RowChanged( size_t row )
94 {
95 return true;
96 }
97
98 bool wxGenericDataViewListModelNotifier::ValueChanged( size_t model_col, size_t model_row )
99 {
100 wxNode *node = GetOwner()->m_viewingColumns.GetFirst();
101 while (node)
102 {
103 wxDataViewViewingColumn* viewing_column = (wxDataViewViewingColumn*) node->GetData();
104 if (viewing_column->m_modelColumn == model_col)
105 {
106
107 }
108
109 node = node->GetNext();
110 }
111
112 return false;
113 }
114
115 bool wxGenericDataViewListModelNotifier::RowsReordered( size_t *new_order )
116 {
117 wxNode *node = GetOwner()->m_viewingColumns.GetFirst();
118 while (node)
119 {
120 wxDataViewViewingColumn* viewing_column = (wxDataViewViewingColumn*) node->GetData();
121
122 node = node->GetNext();
123 }
124
125 return false;
126 }
127
128 bool wxGenericDataViewListModelNotifier::Cleared()
129 {
130 return false;
131 }
132
133 // ---------------------------------------------------------
134 // wxDataViewCell
135 // ---------------------------------------------------------
136
137 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCell, wxDataViewCellBase)
138
139 wxDataViewCell::wxDataViewCell( const wxString &varianttype, wxDataViewCellMode mode ) :
140 wxDataViewCellBase( varianttype, mode )
141 {
142 }
143
144 // ---------------------------------------------------------
145 // wxDataViewTextCell
146 // ---------------------------------------------------------
147
148 IMPLEMENT_ABSTRACT_CLASS(wxDataViewTextCell, wxDataViewCell)
149
150 wxDataViewTextCell::wxDataViewTextCell( const wxString &varianttype, wxDataViewCellMode mode ) :
151 wxDataViewCell( varianttype, mode )
152 {
153 }
154
155 bool wxDataViewTextCell::SetValue( const wxVariant &value )
156 {
157 return false;
158 }
159
160 bool wxDataViewTextCell::GetValue( wxVariant &value )
161 {
162 return false;
163 }
164
165 // ---------------------------------------------------------
166 // wxDataViewToggleCell
167 // ---------------------------------------------------------
168
169 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleCell, wxDataViewCell)
170
171 wxDataViewToggleCell::wxDataViewToggleCell( const wxString &varianttype,
172 wxDataViewCellMode mode ) :
173 wxDataViewCell( varianttype, mode )
174 {
175 }
176
177 bool wxDataViewToggleCell::SetValue( const wxVariant &value )
178 {
179 return false;
180 }
181
182 bool wxDataViewToggleCell::GetValue( wxVariant &value )
183 {
184 return false;
185 }
186
187 // ---------------------------------------------------------
188 // wxDataViewCustomCell
189 // ---------------------------------------------------------
190
191 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomCell, wxDataViewCell)
192
193 wxDataViewCustomCell::wxDataViewCustomCell( const wxString &varianttype,
194 wxDataViewCellMode mode ) :
195 wxDataViewCell( varianttype, mode )
196 {
197 m_dc = NULL;
198
199 Init();
200 }
201
202 bool wxDataViewCustomCell::Init()
203 {
204 return false;
205 }
206
207 wxDataViewCustomCell::~wxDataViewCustomCell()
208 {
209 if (m_dc)
210 delete m_dc;
211 }
212
213 wxDC *wxDataViewCustomCell::GetDC()
214 {
215 if (m_dc == NULL)
216 {
217 if (GetOwner() == NULL)
218 return NULL;
219 if (GetOwner()->GetOwner() == NULL)
220 return NULL;
221 m_dc = new wxClientDC( GetOwner()->GetOwner() );
222 }
223
224 return m_dc;
225 }
226
227 // ---------------------------------------------------------
228 // wxDataViewProgressCell
229 // ---------------------------------------------------------
230
231 IMPLEMENT_ABSTRACT_CLASS(wxDataViewProgressCell, wxDataViewCustomCell)
232
233 wxDataViewProgressCell::wxDataViewProgressCell( const wxString &label,
234 const wxString &varianttype, wxDataViewCellMode mode ) :
235 wxDataViewCustomCell( varianttype, mode )
236 {
237 m_label = label;
238 m_value = 0;
239 }
240
241 wxDataViewProgressCell::~wxDataViewProgressCell()
242 {
243 }
244
245 bool wxDataViewProgressCell::SetValue( const wxVariant &value )
246 {
247 m_value = (long) value;
248
249 if (m_value < 0) m_value = 0;
250 if (m_value > 100) m_value = 100;
251
252 return true;
253 }
254
255 bool wxDataViewProgressCell::Render( wxRect cell, wxDC *dc, int state )
256 {
257 double pct = (double)m_value / 100.0;
258 wxRect bar = cell;
259 bar.width = (int)(cell.width * pct);
260 dc->SetPen( *wxTRANSPARENT_PEN );
261 dc->SetBrush( *wxBLUE_BRUSH );
262 dc->DrawRectangle( bar );
263
264 dc->SetBrush( *wxTRANSPARENT_BRUSH );
265 dc->SetPen( *wxBLACK_PEN );
266 dc->DrawRectangle( cell );
267
268 return true;
269 }
270
271 wxSize wxDataViewProgressCell::GetSize()
272 {
273 return wxSize(40,12);
274 }
275
276 // ---------------------------------------------------------
277 // wxDataViewDateCell
278 // ---------------------------------------------------------
279
280 class wxDataViewDateCellPopupTransient: public wxPopupTransientWindow
281 {
282 public:
283 wxDataViewDateCellPopupTransient( wxWindow* parent, wxDateTime *value,
284 wxDataViewListModel *model, size_t col, size_t row ) :
285 wxPopupTransientWindow( parent, wxBORDER_SIMPLE )
286 {
287 m_model = model;
288 m_col = col;
289 m_row = row;
290 m_cal = new wxCalendarCtrl( this, -1, *value );
291 wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
292 sizer->Add( m_cal, 1, wxGROW );
293 SetSizer( sizer );
294 sizer->Fit( this );
295 }
296
297 virtual void OnDismiss()
298 {
299 }
300
301 void OnCalendar( wxCalendarEvent &event );
302
303 wxCalendarCtrl *m_cal;
304 wxDataViewListModel *m_model;
305 size_t m_col;
306 size_t m_row;
307
308 private:
309 DECLARE_EVENT_TABLE()
310 };
311
312 BEGIN_EVENT_TABLE(wxDataViewDateCellPopupTransient,wxPopupTransientWindow)
313 EVT_CALENDAR( -1, wxDataViewDateCellPopupTransient::OnCalendar )
314 END_EVENT_TABLE()
315
316 void wxDataViewDateCellPopupTransient::OnCalendar( wxCalendarEvent &event )
317 {
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 );
322 DismissAndNotify();
323 }
324
325 IMPLEMENT_ABSTRACT_CLASS(wxDataViewDateCell, wxDataViewCustomCell)
326
327 wxDataViewDateCell::wxDataViewDateCell( const wxString &varianttype,
328 wxDataViewCellMode mode ) :
329 wxDataViewCustomCell( varianttype, mode )
330 {
331 }
332
333 bool wxDataViewDateCell::SetValue( const wxVariant &value )
334 {
335 m_date = value.GetDateTime();
336
337 return true;
338 }
339
340 bool wxDataViewDateCell::Render( wxRect cell, wxDC *dc, int state )
341 {
342 dc->SetFont( GetOwner()->GetOwner()->GetFont() );
343 wxString tmp = m_date.FormatDate();
344 dc->DrawText( tmp, cell.x, cell.y );
345
346 return true;
347 }
348
349 wxSize wxDataViewDateCell::GetSize()
350 {
351 wxDataViewCtrl* view = GetOwner()->GetOwner();
352 wxString tmp = m_date.FormatDate();
353 wxCoord x,y,d;
354 view->GetTextExtent( tmp, &x, &y, &d );
355 return wxSize(x,y+d);
356 }
357
358 bool wxDataViewDateCell::Activate( wxRect cell, wxDataViewListModel *model, size_t col, size_t row )
359 {
360 wxVariant variant;
361 model->GetValue( variant, col, row );
362 wxDateTime value = variant.GetDateTime();
363
364 wxDataViewDateCellPopupTransient *popup = new wxDataViewDateCellPopupTransient(
365 GetOwner()->GetOwner()->GetParent(), &value, model, col, row );
366 wxPoint pos = wxGetMousePosition();
367 popup->Move( pos );
368 popup->Layout();
369 popup->Popup( popup->m_cal );
370
371 return true;
372 }
373
374 // ---------------------------------------------------------
375 // wxDataViewColumn
376 // ---------------------------------------------------------
377
378 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn, wxDataViewColumnBase)
379
380 wxDataViewColumn::wxDataViewColumn( const wxString &title, wxDataViewCell *cell,
381 size_t model_column, int flags ) :
382 wxDataViewColumnBase( title, cell, model_column, flags )
383 {
384 }
385
386 wxDataViewColumn::~wxDataViewColumn()
387 {
388 }
389
390 void wxDataViewColumn::SetTitle( const wxString &title )
391 {
392 wxDataViewColumnBase::SetTitle( title );
393
394 }
395
396 //-----------------------------------------------------------------------------
397 // wxDataViewHeaderWindow
398 //-----------------------------------------------------------------------------
399
400 class wxDataViewHeaderWindow: public wxWindow
401 {
402 public:
403 wxDataViewHeaderWindow( wxDataViewCtrl *parent,
404 wxWindowID id,
405 const wxPoint &pos = wxDefaultPosition,
406 const wxSize &size = wxDefaultSize,
407 const wxString &name = wxT("wxdataviewctrlheaderwindow") );
408 ~wxDataViewHeaderWindow();
409
410 void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
411 wxDataViewCtrl *GetOwner() { return m_owner; }
412
413 void OnPaint( wxPaintEvent &event );
414 void OnMouse( wxMouseEvent &event );
415 void OnSetFocus( wxFocusEvent &event );
416
417 private:
418 wxDataViewCtrl *m_owner;
419 wxCursor *m_resizeCursor;
420
421 private:
422 DECLARE_DYNAMIC_CLASS(wxDataViewHeaderWindow)
423 DECLARE_EVENT_TABLE()
424 };
425
426 IMPLEMENT_ABSTRACT_CLASS(wxDataViewHeaderWindow, wxWindow)
427
428 BEGIN_EVENT_TABLE(wxDataViewHeaderWindow,wxWindow)
429 EVT_PAINT (wxDataViewHeaderWindow::OnPaint)
430 EVT_MOUSE_EVENTS (wxDataViewHeaderWindow::OnMouse)
431 EVT_SET_FOCUS (wxDataViewHeaderWindow::OnSetFocus)
432 END_EVENT_TABLE()
433
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 )
437 {
438 SetOwner( parent );
439
440 m_resizeCursor = new wxCursor( wxCURSOR_SIZEWE );
441
442 wxVisualAttributes attr = wxPanel::GetClassDefaultAttributes();
443 SetOwnForegroundColour( attr.colFg );
444 SetOwnBackgroundColour( attr.colBg );
445 if (!m_hasFont)
446 SetOwnFont( attr.font );
447 }
448
449 wxDataViewHeaderWindow::~wxDataViewHeaderWindow()
450 {
451 delete m_resizeCursor;
452 }
453
454 void wxDataViewHeaderWindow::OnPaint( wxPaintEvent &event )
455 {
456 wxPaintDC dc;
457 PrepareDC( dc );
458
459 int xpix;
460 m_owner->GetScrollPixelsPerUnit( &xpix, NULL );
461
462 int x;
463 m_owner->GetViewStart( &x, NULL );
464
465 // account for the horz scrollbar offset
466 dc.SetDeviceOrigin( -x * xpix, 0 );
467
468 dc.SetFont( GetFont() );
469
470 dc.DrawText( wxT("This is the header.."), 5, 5 );
471 }
472
473 void wxDataViewHeaderWindow::OnMouse( wxMouseEvent &event )
474 {
475 }
476
477 void wxDataViewHeaderWindow::OnSetFocus( wxFocusEvent &event )
478 {
479 event.Skip();
480 }
481
482 //-----------------------------------------------------------------------------
483 // wxDataViewMainWindow
484 //-----------------------------------------------------------------------------
485
486 class wxDataViewMainWindow: public wxWindow
487 {
488 public:
489 wxDataViewMainWindow( wxDataViewCtrl *parent,
490 wxWindowID id,
491 const wxPoint &pos = wxDefaultPosition,
492 const wxSize &size = wxDefaultSize,
493 const wxString &name = wxT("wxdataviewctrlmainwindow") );
494 ~wxDataViewMainWindow();
495
496 void SetOwner( wxDataViewCtrl* owner ) { m_owner = owner; }
497 wxDataViewCtrl *GetOwner() { return m_owner; }
498
499 void OnPaint( wxPaintEvent &event );
500 void OnMouse( wxMouseEvent &event );
501 void OnSetFocus( wxFocusEvent &event );
502
503 private:
504 wxDataViewCtrl *m_owner;
505
506 private:
507 DECLARE_DYNAMIC_CLASS(wxDataViewMainWindow)
508 DECLARE_EVENT_TABLE()
509 };
510
511 IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow, wxWindow)
512
513 BEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow)
514 EVT_PAINT (wxDataViewMainWindow::OnPaint)
515 EVT_MOUSE_EVENTS (wxDataViewMainWindow::OnMouse)
516 EVT_SET_FOCUS (wxDataViewMainWindow::OnSetFocus)
517 END_EVENT_TABLE()
518
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 )
522 {
523 SetOwner( parent );
524 }
525
526 wxDataViewMainWindow::~wxDataViewMainWindow()
527 {
528 }
529
530 void wxDataViewMainWindow::OnPaint( wxPaintEvent &event )
531 {
532 wxPaintDC dc( this );
533
534 PrepareDC( dc );
535
536 int dev_x, dev_y;
537 m_owner->CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
538
539 dc.SetFont( GetFont() );
540
541 dc.DrawText( wxT("main window"), 5, 5 );
542 }
543
544 void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
545 {
546 event.Skip();
547 }
548
549 void wxDataViewMainWindow::OnSetFocus( wxFocusEvent &event )
550 {
551 event.Skip();
552 }
553
554 //-----------------------------------------------------------------------------
555 // wxDataViewCtrl
556 //-----------------------------------------------------------------------------
557
558 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase)
559
560 wxDataViewCtrl::~wxDataViewCtrl()
561 {
562 if (m_notifier)
563 GetModel()->RemoveNotifier( m_notifier );
564 }
565
566 void wxDataViewCtrl::Init()
567 {
568 m_notifier = NULL;
569 }
570
571 bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
572 const wxPoint& pos, const wxSize& size,
573 long style, const wxValidator& validator )
574 {
575 Init();
576
577 #ifdef __WXMAC__
578 MacSetClipChildren( true ) ;
579 #endif
580
581 m_clientArea = new wxDataViewMainWindow( this, -1 );
582 m_headerArea = new wxDataViewHeaderWindow( this, -1, wxDefaultPosition, wxSize(-1,25) );
583
584 SetTargetWindow( m_clientArea );
585
586 wxBoxSizer *sizer = new wxBoxSizer( wxVERTICAL );
587 sizer->Add( m_headerArea, 0, wxGROW );
588 sizer->Add( m_clientArea, 1, wxGROW );
589 SetSizer( sizer );
590
591 return true;
592 }
593
594 #ifdef __WXMSW__
595 WXLRESULT wxDataViewCtrl::MSWWindowProc(WXUINT nMsg,
596 WXWPARAM wParam,
597 WXLPARAM lParam)
598 {
599 WXLRESULT rc = wxPanel::MSWWindowProc(nMsg, wParam, lParam);
600
601 #ifndef __WXWINCE__
602 // we need to process arrows ourselves for scrolling
603 if ( nMsg == WM_GETDLGCODE )
604 {
605 rc |= DLGC_WANTARROWS;
606 }
607 #endif
608
609 return rc;
610 }
611 #endif
612
613 void wxDataViewCtrl::ScrollWindow( int dx, int dy, const wxRect *rect )
614 {
615 wxDataViewCtrlBase::ScrollWindow( dx, dy, rect );
616 m_headerArea->ScrollWindow( dx, 0, rect );
617 }
618
619 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel *model )
620 {
621 if (!wxDataViewCtrlBase::AssociateModel( model ))
622 return false;
623
624 m_notifier = new wxGenericDataViewListModelNotifier( model );
625
626 model->AddNotifier( m_notifier );
627
628 return true;
629 }
630
631 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
632 {
633 if (!wxDataViewCtrlBase::AppendColumn(col))
634 return false;
635
636 return true;
637 }
638
639 #endif
640 // !wxUSE_GENERICDATAVIEWCTRL
641
642 #endif
643 // wxUSE_DATAVIEWCTRL
644