]> git.saurik.com Git - wxWidgets.git/blob - src/generic/treectrl.cpp
wxFrame::CreateToolBar() stuff
[wxWidgets.git] / src / generic / treectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: treectrl.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id: $Id$
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "treectrl.h"
13 #endif
14
15 #include "wx/treectrl.h"
16 #include "wx/settings.h"
17 #include "wx/log.h"
18
19 //-----------------------------------------------------------------------------
20 // wxTreeItem
21 //-----------------------------------------------------------------------------
22
23 IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject)
24
25 wxTreeItem::wxTreeItem()
26 {
27 m_mask = 0;
28 m_itemId = 0;
29 m_state = 0;
30 m_stateMask = 0;
31 m_image = -1;
32 m_selectedImage = -1;
33 m_children = 0;
34 m_data = 0;
35 };
36
37 //-----------------------------------------------------------------------------
38 // wxTreeEvent
39 //-----------------------------------------------------------------------------
40
41 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent,wxCommandEvent)
42
43 wxTreeEvent::wxTreeEvent( wxEventType commandType, int id ) :
44 wxCommandEvent( commandType, id )
45 {
46 m_code = 0;
47 m_oldItem = 0;
48 };
49
50 //-----------------------------------------------------------------------------
51 // wxGenericTreeItem
52 //-----------------------------------------------------------------------------
53
54 IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeItem,wxObject)
55
56 wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem *parent )
57 {
58 Reset();
59 m_parent = parent;
60 m_hasHilight = FALSE;
61 };
62
63 wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem *parent, const wxTreeItem& item, wxDC *dc )
64 {
65 Reset();
66 SetItem( item, dc );
67 m_parent = parent;
68 m_hasHilight = FALSE;
69 };
70
71 void wxGenericTreeItem::SetItem( const wxTreeItem &item, wxDC *dc )
72 {
73 if ((item.m_mask & wxTREE_MASK_HANDLE) == wxTREE_MASK_HANDLE)
74 m_itemId = item.m_itemId;
75 if ((item.m_mask & wxTREE_MASK_STATE) == wxTREE_MASK_STATE)
76 m_state = item.m_state;
77 if ((item.m_mask & wxTREE_MASK_TEXT) == wxTREE_MASK_TEXT)
78 m_text = item.m_text;
79 if ((item.m_mask & wxTREE_MASK_IMAGE) == wxTREE_MASK_IMAGE)
80 m_image = item.m_image;
81 if ((item.m_mask & wxTREE_MASK_SELECTED_IMAGE) == wxTREE_MASK_SELECTED_IMAGE)
82 m_selectedImage = item.m_selectedImage;
83 if ((item.m_mask & wxTREE_MASK_CHILDREN) == wxTREE_MASK_CHILDREN)
84 m_hasChildren = (item.m_children > 0);
85 if ((item.m_mask & wxTREE_MASK_DATA) == wxTREE_MASK_DATA)
86 m_data = item.m_data;
87 long lw = 0;
88 long lh = 0;
89 dc->GetTextExtent( m_text, &lw, &lh );
90 m_width = lw;
91 m_height = lh;
92 };
93
94 void wxGenericTreeItem::SetText( const wxString &text, wxDC *dc )
95 {
96 m_text = text;
97 long lw = 0;
98 long lh = 0;
99 dc->GetTextExtent( m_text, &lw, &lh );
100 m_width = lw;
101 m_height = lh;
102 };
103
104 void wxGenericTreeItem::Reset()
105 {
106 m_itemId = -1;
107 m_state = 0;
108 m_text = "";
109 m_image = -1;
110 m_selectedImage = -1;
111 // m_children = 0;
112 m_hasChildren = FALSE;
113 m_data = 0;
114 m_x = 0;
115 m_y = 0;
116 m_height = 0;
117 m_width = 0;
118 m_xCross = 0;
119 m_yCross = 0;
120 m_level = 0;
121 m_children.DeleteContents( TRUE );
122 m_isCollapsed = TRUE;
123 m_parent = NULL;
124 };
125
126 void wxGenericTreeItem::GetItem( wxTreeItem &item ) const
127 {
128 if ((item.m_mask & wxTREE_MASK_STATE) == wxTREE_MASK_STATE)
129 item.m_state = m_state;
130 if ((item.m_mask & wxTREE_MASK_TEXT) == wxTREE_MASK_TEXT)
131 item.m_text = m_text;
132 if ((item.m_mask & wxTREE_MASK_IMAGE) == wxTREE_MASK_IMAGE)
133 item.m_image = m_image;
134 if ((item.m_mask & wxTREE_MASK_SELECTED_IMAGE) == wxTREE_MASK_SELECTED_IMAGE)
135 item.m_selectedImage = m_selectedImage;
136 if ((item.m_mask & wxTREE_MASK_CHILDREN) == wxTREE_MASK_CHILDREN)
137 item.m_children = (int)m_hasChildren;
138 if ((item.m_mask & wxTREE_MASK_DATA) == wxTREE_MASK_DATA)
139 item.m_data = m_data;
140 };
141
142 bool wxGenericTreeItem::HasChildren()
143 {
144 return m_hasChildren;
145 };
146
147 bool wxGenericTreeItem::HasPlus()
148 {
149 if ( !HasChildren() )
150 return FALSE;
151
152 return !IsExpanded();
153 };
154
155 int wxGenericTreeItem::NumberOfVisibleDescendents()
156 {
157 int ret = m_children.Number();
158 wxNode *node = m_children.First();
159 while (node)
160 {
161 wxGenericTreeItem *item = (wxGenericTreeItem*)node->Data();
162 ret += item->NumberOfVisibleDescendents();
163 node = node->Next();
164 };
165 return ret;
166 };
167
168 int wxGenericTreeItem::NumberOfVisibleChildren()
169 {
170 return m_isCollapsed ? 0 : m_children.Number();
171 };
172
173 wxGenericTreeItem *wxGenericTreeItem::FindItem( long itemId ) const
174 {
175 if (m_itemId == itemId) return (wxGenericTreeItem*)(this);
176 wxNode *node = m_children.First();
177 while (node)
178 {
179 wxGenericTreeItem *item = (wxGenericTreeItem*)node->Data();
180 wxGenericTreeItem *res = item->FindItem( itemId );
181 if (res) return (wxGenericTreeItem*)(res);
182 node = node->Next();
183 };
184 return NULL;
185 };
186
187 void wxGenericTreeItem::AddChild( wxGenericTreeItem *child )
188 {
189 m_children.Append( child );
190 };
191
192 void wxGenericTreeItem::SetCross( int x, int y )
193 {
194 m_xCross = x;
195 m_yCross = y;
196 };
197
198 void wxGenericTreeItem::GetSize( int &x, int &y )
199 {
200 if (y < m_y + 10) y = m_y +10;
201 int width = m_x + m_width;
202 if (width > x) x = width;
203 wxNode *node = m_children.First();
204 while (node)
205 {
206 wxGenericTreeItem *item = (wxGenericTreeItem*)node->Data();
207 item->GetSize( x, y );
208 node = node->Next();
209 };
210 };
211
212 long wxGenericTreeItem::HitTest( const wxPoint& point, int &flags )
213 {
214 if ((point.y > m_y) && (point.y < m_y+m_height))
215 {
216 if ((point.x > m_xCross-5) &&
217 (point.x < m_xCross+5) &&
218 (point.y > m_yCross-5) &&
219 (point.y < m_yCross+5) &&
220 (m_hasChildren))
221 {
222 flags = wxTREE_HITTEST_ONITEMBUTTON;
223 return m_itemId;
224 };
225 if ((point.x > m_x) && (point.x < m_x+m_width))
226 {
227 flags = wxTREE_HITTEST_ONITEMLABEL;
228 return m_itemId;
229 };
230 if (point.x > m_x)
231 {
232 flags = wxTREE_HITTEST_ONITEMRIGHT;
233 return m_itemId;
234 };
235 flags = wxTREE_HITTEST_ONITEMINDENT;
236 return m_itemId;
237 }
238 else
239 {
240 if (!m_isCollapsed)
241 {
242 wxNode *node = m_children.First();
243 while (node)
244 {
245 wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data();
246 long res = child->HitTest( point, flags );
247 if (res != -1) return res;
248 node = node->Next();
249 };
250 };
251 };
252 return -1;
253 };
254
255 void wxGenericTreeItem::PrepareEvent( wxTreeEvent &event )
256 {
257 event.m_item.m_itemId = m_itemId;
258 event.m_item.m_state = m_state;
259 event.m_item.m_text = m_text;
260 event.m_item.m_image = m_image;
261 event.m_item.m_selectedImage = m_selectedImage;
262 event.m_item.m_children = (int)m_hasChildren;
263 event.m_item.m_data = m_data;
264 event.m_oldItem = 0;
265 event.m_code = 0;
266 event.m_pointDrag.x = 0;
267 event.m_pointDrag.y = 0;
268 };
269
270 void wxGenericTreeItem::SendKeyDown( wxWindow *target )
271 {
272 wxTreeEvent event( wxEVT_COMMAND_TREE_KEY_DOWN, target->GetId() );
273 PrepareEvent( event );
274 event.SetEventObject( target );
275 target->ProcessEvent( event );
276 };
277
278 void wxGenericTreeItem::SendSelected( wxWindow *target )
279 {
280 wxTreeEvent event( wxEVT_COMMAND_TREE_SEL_CHANGED, target->GetId() );
281 PrepareEvent( event );
282 event.SetEventObject( target );
283 target->ProcessEvent( event );
284 };
285
286 void wxGenericTreeItem::SendDelete( wxWindow *target )
287 {
288 wxTreeEvent event( wxEVT_COMMAND_TREE_DELETE_ITEM, target->GetId() );
289 PrepareEvent( event );
290 event.SetEventObject( target );
291 target->ProcessEvent( event );
292 };
293
294 void wxGenericTreeItem::SendExpand( wxWindow *target )
295 {
296 m_isCollapsed = FALSE;
297
298 wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_EXPANDING, target->GetId() );
299 event.SetEventObject( target );
300 PrepareEvent( event );
301 target->ProcessEvent( event );
302
303 event.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED);
304 PrepareEvent( event );
305 target->ProcessEvent( event );
306 };
307
308 void wxGenericTreeItem::SendCollapse( wxWindow *target )
309 {
310 m_isCollapsed = TRUE;
311
312 wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, target->GetId() );
313 event.SetEventObject( target );
314 PrepareEvent( event );
315 target->ProcessEvent( event );
316
317 event.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
318 PrepareEvent( event );
319 target->ProcessEvent( event );
320 };
321
322 void wxGenericTreeItem::SetHilight( bool set )
323 {
324 m_hasHilight = set;
325 };
326
327 bool wxGenericTreeItem::HasHilight()
328 {
329 return m_hasHilight;
330 };
331
332 //-----------------------------------------------------------------------------
333 // wxTreeCtrl
334 //-----------------------------------------------------------------------------
335
336 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl,wxScrolledWindow)
337
338 BEGIN_EVENT_TABLE(wxTreeCtrl,wxScrolledWindow)
339 EVT_PAINT (wxTreeCtrl::OnPaint)
340 EVT_MOUSE_EVENTS (wxTreeCtrl::OnMouse)
341 EVT_CHAR (wxTreeCtrl::OnChar)
342 EVT_SET_FOCUS (wxTreeCtrl::OnSetFocus)
343 EVT_KILL_FOCUS (wxTreeCtrl::OnKillFocus)
344 END_EVENT_TABLE()
345
346 wxTreeCtrl::wxTreeCtrl()
347 {
348 m_current = NULL;
349 m_anchor = NULL;
350 m_hasFocus = FALSE;
351 m_xScroll = 0;
352 m_yScroll = 0;
353 m_lastId = 0;
354 m_lineHeight = 10;
355 m_indent = 15;
356 m_isCreated = FALSE;
357 m_dc = NULL;
358 m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
359 m_imageList = NULL;
360 m_smallImageList = NULL;
361 };
362
363 wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id,
364 const wxPoint& pos, const wxSize& size,
365 long style, const wxString& name )
366 {
367 m_current = NULL;
368 m_anchor = NULL;
369 m_hasFocus = FALSE;
370 m_xScroll = 0;
371 m_yScroll = 0;
372 m_lastId = 0;
373 m_lineHeight = 10;
374 m_indent = 15;
375 m_isCreated = FALSE;
376 m_dc = NULL;
377 m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
378 m_imageList = NULL;
379 m_smallImageList = NULL;
380 Create( parent, id, pos, size, style, name );
381 };
382
383 wxTreeCtrl::~wxTreeCtrl()
384 {
385 if (m_dc) delete m_dc;
386 };
387
388 bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id,
389 const wxPoint& pos, const wxSize& size,
390 long style, const wxString& name )
391 {
392 wxScrolledWindow::Create( parent, id, pos, size, style, name );
393 SetBackgroundColour( *wxWHITE );
394 m_dottedPen = wxPen( *wxBLACK, 0, 0 );
395 return TRUE;
396 };
397
398 int wxTreeCtrl::GetCount() const
399 {
400 if (!m_anchor) return 0;
401 return m_anchor->NumberOfVisibleDescendents();
402 };
403
404 long wxTreeCtrl::InsertItem( long parent, const wxString& label, int image,
405 int selImage, long WXUNUSED(insertAfter) )
406 {
407 wxGenericTreeItem *p = NULL;
408 if (parent == 0)
409 {
410 if (m_anchor) return -1;
411 }
412 else
413 {
414 p = FindItem( parent );
415 if (!p) return -1;
416 };
417 wxTreeItem item;
418 m_lastId++;
419 item.m_mask = wxTREE_MASK_HANDLE;
420 item.m_itemId = m_lastId;
421 if (!label.IsNull() || (label == ""))
422 {
423 item.m_text = label;
424 item.m_mask |= wxTREE_MASK_TEXT;
425 };
426 if (image >= 0)
427 {
428 item.m_image = image;
429 item.m_mask |= wxTREE_MASK_IMAGE;
430 };
431 if (selImage >= 0)
432 {
433 item.m_selectedImage = selImage;
434 item.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
435 };
436
437 wxClientDC dc(this);
438 wxGenericTreeItem *new_child = new wxGenericTreeItem( p, item, &dc );
439 if (p)
440 p->AddChild( new_child );
441 else
442 m_anchor = new_child;
443
444 if (p)
445 {
446 CalculatePositions();
447
448 if (!p->HasChildren()) p->m_hasChildren = TRUE;
449
450 int ch = 0;
451 GetClientSize( NULL, &ch );
452
453 wxRectangle rect;
454 rect.x = 0; rect.y = 0;
455 rect.width = 10000; rect.height = ch;
456
457 PrepareDC( dc );
458 if (p->m_children.Number() == 1)
459 {
460 rect.y = dc.LogicalToDeviceY( p->m_y );
461 }
462 else
463 {
464 wxNode *node = p->m_children.Member( new_child )->Previous();
465 wxGenericTreeItem* last_child = (wxGenericTreeItem*)node->Data();
466 rect.y = dc.LogicalToDeviceY( last_child->m_y );
467 };
468
469 long doX = 0;
470 long doY = 0;
471 dc.GetDeviceOrigin( &doX, &doY );
472 rect.height = ch-rect.y-doY;
473
474 AdjustMyScrollbars();
475
476 if (rect.height > 0) Refresh( FALSE, &rect);
477 }
478 else
479 {
480 AdjustMyScrollbars();
481
482 Refresh();
483 };
484
485 return m_lastId;
486 };
487
488 long wxTreeCtrl::InsertItem( long parent, wxTreeItem &info, long WXUNUSED(insertAfter) )
489 {
490 int oldMask = info.m_mask;
491 wxGenericTreeItem *p = NULL;
492 if (parent == 0)
493 {
494 if (m_anchor) return -1;
495 }
496 else
497 {
498 p = FindItem( parent );
499 if (!p)
500 {
501 printf( "TreeItem not found.\n" );
502 return -1;
503 };
504 };
505 long ret = 0;
506 if ((info.m_mask & wxTREE_MASK_HANDLE) == 0)
507 {
508 m_lastId++;
509 info.m_itemId = m_lastId;
510 info.m_mask |= wxTREE_MASK_HANDLE;
511 ret = m_lastId;
512 }
513 else
514 {
515 ret = info.m_itemId;
516 };
517
518 wxClientDC dc(this);
519 wxGenericTreeItem *new_child = new wxGenericTreeItem( p, info, &dc );
520 if (p)
521 p->AddChild( new_child );
522 else
523 m_anchor = new_child;
524
525 if (p)
526 {
527 CalculatePositions();
528
529 if (!p->HasChildren()) p->m_hasChildren = TRUE;
530
531 int ch = 0;
532 GetClientSize( NULL, &ch );
533
534 wxRectangle rect;
535 rect.x = 0; rect.y = 0;
536 rect.width = 10000; rect.height = ch;
537
538 PrepareDC( dc );
539 if (p->m_children.Number() == 1)
540 {
541 rect.y = dc.LogicalToDeviceY( p->m_y );
542 }
543 else
544 {
545 wxNode *node = p->m_children.Member( new_child )->Previous();
546 wxGenericTreeItem* last_child = (wxGenericTreeItem*)node->Data();
547 rect.y = dc.LogicalToDeviceY( last_child->m_y );
548 };
549
550 long doX = 0;
551 long doY = 0;
552 dc.GetDeviceOrigin( &doX, &doY );
553 rect.height = ch-rect.y-doY;
554
555 AdjustMyScrollbars();
556
557 if (rect.height > 0) Refresh( FALSE, &rect);
558 }
559 else
560 {
561 AdjustMyScrollbars();
562
563 Refresh();
564 };
565
566 info.m_mask = oldMask;
567 return ret;
568 };
569
570 bool wxTreeCtrl::ExpandItem( long item, int action )
571 {
572 wxGenericTreeItem *i = FindItem( item );
573 if (!i)
574 return FALSE;
575
576 switch (action)
577 {
578 case wxTREE_EXPAND_EXPAND:
579 {
580 i->SendExpand( this );
581 break;
582 }
583
584 case wxTREE_EXPAND_COLLAPSE_RESET:
585 case wxTREE_EXPAND_COLLAPSE:
586 {
587 wxNode *node = i->m_children.First();
588 while (node)
589 {
590 wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data();
591 if ( child->IsExpanded() )
592 ExpandItem( child->m_itemId, wxTREE_EXPAND_COLLAPSE );
593 node = node->Next();
594 };
595
596 CalculatePositions();
597
598 i->SendCollapse( this );
599 break;
600 }
601
602 case wxTREE_EXPAND_TOGGLE:
603 {
604 if ( i->IsExpanded() )
605 ExpandItem( item, wxTREE_EXPAND_COLLAPSE );
606 else
607 ExpandItem( item, wxTREE_EXPAND_EXPAND );
608 return TRUE;
609 }
610 };
611
612 int cw = 0;
613 int ch = 0;
614 GetClientSize( &cw, &ch );
615 wxRect rect;
616 rect.x = 0;
617 rect.width = cw;
618 wxClientDC dc(this);
619 PrepareDC(dc);
620 rect.y = dc.LogicalToDeviceY( i->m_y );
621
622 long doY = 0;
623 dc.GetDeviceOrigin( NULL, &doY );
624 rect.height = ch-rect.y-doY;
625 Refresh( TRUE, &rect );
626
627 AdjustMyScrollbars();
628
629 return TRUE;
630 };
631
632 void wxTreeCtrl::DeleteItem( long item )
633 {
634 wxGenericTreeItem *pItem = FindItem( item );
635 wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteItem: no such pItem." );
636
637 pItem->m_parent->m_children.DeleteObject(pItem);
638
639 Refresh();
640 }
641
642 void wxTreeCtrl::DeleteChildren( long item )
643 {
644 wxGenericTreeItem *pItem = FindItem( item );
645 wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteChildren: no such pItem." );
646
647 pItem->m_children.Clear();
648
649 Refresh();
650 }
651
652 bool wxTreeCtrl::DeleteAllItems()
653 {
654 delete m_anchor;
655 m_anchor = NULL;
656 Refresh();
657 return TRUE;
658 };
659
660 bool wxTreeCtrl::GetItem( wxTreeItem &info ) const
661 {
662 wxGenericTreeItem *i = FindItem( info.m_itemId );
663 if (!i) return FALSE;
664 i->GetItem( info );
665 return TRUE;
666 };
667
668 long wxTreeCtrl::GetItemData( long item ) const
669 {
670 wxGenericTreeItem *i = FindItem( item );
671 if (!i) return 0;
672 return i->m_data;
673 };
674
675 wxString wxTreeCtrl::GetItemText( long item ) const
676 {
677 wxGenericTreeItem *i = FindItem( item );
678 if (!i) return "";
679 return i->m_text;
680 };
681
682 int wxTreeCtrl::GetItemImage(long item) const
683 {
684 wxGenericTreeItem *i = FindItem( item );
685 return i == 0 ? -1 : i->GetImage();
686 }
687
688 long wxTreeCtrl::GetParent( long item ) const
689 {
690 wxGenericTreeItem *i = FindItem( item );
691 if (!i) return -1;
692 i = i->m_parent;
693 if (!i) return -1;
694 return i->m_parent->m_itemId;
695 };
696
697 long wxTreeCtrl::GetRootItem() const
698 {
699 if (m_anchor) return m_anchor->m_itemId;
700 return -1;
701 };
702
703 long wxTreeCtrl::GetSelection() const
704 {
705 return m_current ? m_current->GetItemId() : -1;
706 };
707
708 bool wxTreeCtrl::SelectItem(long itemId)
709 {
710 wxGenericTreeItem *pItem = FindItem(itemId);
711 if ( !pItem ) {
712 wxLogDebug("Can't select an item %d which doesn't exist.", itemId);
713
714 return FALSE;
715 }
716
717 SelectItem(pItem);
718
719 return TRUE;
720 };
721
722 void wxTreeCtrl::SelectItem(wxGenericTreeItem *item)
723 {
724 if (m_current != item)
725 {
726 if (m_current)
727 {
728 m_current->SetHilight( FALSE );
729 RefreshLine( m_current );
730 };
731 m_current = item;
732 m_current->SetHilight( TRUE );
733 RefreshLine( m_current );
734
735 m_current->SendSelected( this );
736 }
737 }
738
739 bool wxTreeCtrl::ItemHasChildren( long item ) const
740 {
741 wxGenericTreeItem *i = FindItem( item );
742 if (!i) return FALSE;
743 return i->m_hasChildren;
744 };
745
746 void wxTreeCtrl::SetIndent( int indent )
747 {
748 m_indent = indent;
749 Refresh();
750 };
751
752 int wxTreeCtrl::GetIndent() const
753 {
754 return m_indent;
755 };
756
757 bool wxTreeCtrl::SetItem( wxTreeItem &info )
758 {
759 wxGenericTreeItem *i = FindItem( info.m_itemId );
760 if (!i) return FALSE;
761 wxClientDC dc(this);
762 i->SetItem( info, &dc );
763 Refresh();
764 return TRUE;
765 };
766
767 bool wxTreeCtrl::SetItemData( long item, long data )
768 {
769 wxGenericTreeItem *i = FindItem( item );
770 if (!i) return FALSE;
771 i->m_data = data;
772 return TRUE;
773 };
774
775 bool wxTreeCtrl::SetItemText( long item, const wxString &text )
776 {
777 wxGenericTreeItem *i = FindItem( item );
778 if (!i) return FALSE;
779 wxClientDC dc(this);
780 i->SetText( text, &dc );
781 return TRUE;
782 };
783
784 void wxTreeCtrl::SetItemImage(long item, int image, int imageSel) const
785 {
786 wxGenericTreeItem *i = FindItem( item );
787 if ( i != 0 ) {
788 i->SetImage(image);
789 i->SetSelectedImage(imageSel);
790 }
791 }
792
793 long wxTreeCtrl::HitTest( const wxPoint& point, int &flags )
794 {
795 flags = 0;
796 if (!m_anchor) return -1;
797 return m_anchor->HitTest( point, flags );
798 };
799
800 wxImageList *wxTreeCtrl::GetImageList( int which ) const
801 {
802 if (which == wxIMAGE_LIST_NORMAL) return m_imageList;
803 return m_smallImageList;
804 };
805
806 void wxTreeCtrl::SetImageList( wxImageList *imageList, int which )
807 {
808 if (which == wxIMAGE_LIST_NORMAL)
809 {
810 if (m_imageList) delete m_imageList;
811 m_imageList = imageList;
812 }
813 else
814 {
815 if (m_smallImageList) delete m_smallImageList;
816 m_smallImageList = imageList;
817 };
818 };
819
820 void wxTreeCtrl::AdjustMyScrollbars()
821 {
822 if (m_anchor)
823 {
824 int x = 0;
825 int y = 0;
826 m_anchor->GetSize( x, y );
827 y += 2*m_lineHeight;
828 int x_pos = GetScrollPos( wxHORIZONTAL );
829 int y_pos = GetScrollPos( wxVERTICAL );
830 SetScrollbars( 10, 10, x/10, y/10, x_pos, y_pos );
831 }
832 else
833 {
834 SetScrollbars( 0, 0, 0, 0 );
835 };
836 };
837
838 void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y )
839 {
840 int horizX = level*m_indent;
841
842 item->m_x = horizX+33;
843 item->m_y = y-m_lineHeight/3;
844 item->m_height = m_lineHeight;
845
846 item->SetCross( horizX+15, y );
847
848 int oldY = y;
849
850 if (IsExposed( 0, item->m_y-2, 10000, m_lineHeight+4 ))
851 {
852 int startX = horizX;
853 int endX = horizX + 10;
854
855 if (!item->HasChildren()) endX += 20;
856 dc.DrawLine( startX, y, endX, y );
857
858 if (item->HasChildren())
859 {
860 dc.DrawLine( horizX+20, y, horizX+30, y );
861 dc.SetPen( *wxGREY_PEN );
862 dc.DrawRectangle( horizX+10, y-4, 11, 9 );
863 dc.SetPen( *wxBLACK_PEN );
864 dc.DrawLine( horizX+13, y, horizX+18, y );
865 if (item->HasPlus())
866 dc.DrawLine( horizX+15, y-2, horizX+15, y+3 );
867 };
868
869 if (item->HasHilight())
870 {
871 dc.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
872 dc.SetBrush( *m_hilightBrush );
873 long tw, th;
874 dc.GetTextExtent( item->m_text, &tw, &th );
875 if (m_hasFocus)
876 {
877 dc.SetPen( *wxBLACK_PEN );
878 dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 );
879 }
880 else
881 {
882 dc.SetPen( *wxTRANSPARENT_PEN );
883 dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 );
884 }
885 dc.DrawText( item->m_text, item->m_x, item->m_y );
886
887 dc.SetPen( *wxBLACK_PEN );
888 dc.SetTextForeground( *wxBLACK );
889 dc.SetBrush( *wxWHITE_BRUSH );
890 }
891 else
892 {
893 dc.SetPen( *wxTRANSPARENT_PEN );
894 long tw, th;
895 dc.GetTextExtent( item->m_text, &tw, &th );
896 dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 );
897 dc.DrawText( item->m_text, item->m_x, item->m_y );
898 dc.SetPen( *wxBLACK_PEN );
899 };
900 };
901
902 if (item->NumberOfVisibleChildren() == 0) return;
903
904 int semiOldY = y;
905
906 wxNode *node = item->m_children.First();
907 while (node)
908 {
909 wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data();
910
911 y += m_lineHeight;
912 semiOldY = y;
913
914 PaintLevel( child, dc, level+1, y );
915
916 node = node->Next();
917 };
918
919 dc.DrawLine( horizX+15, oldY+5, horizX+15, semiOldY );
920 }
921
922 void wxTreeCtrl::OnPaint( const wxPaintEvent &WXUNUSED(event) )
923 {
924 if (!m_anchor) return;
925
926 if (!m_dc)
927 {
928 m_dc = new wxPaintDC(this);
929 PrepareDC( *m_dc );
930 };
931
932 m_dc->SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
933
934 m_dc->SetPen( m_dottedPen );
935 m_lineHeight = (int)(m_dc->GetCharHeight() + 4);
936
937 int y = m_lineHeight / 2 + 2;
938 PaintLevel( m_anchor, *m_dc, 0, y );
939 };
940
941 void wxTreeCtrl::OnSetFocus( const wxFocusEvent &WXUNUSED(event) )
942 {
943 m_hasFocus = TRUE;
944 if (m_current) RefreshLine( m_current );
945 };
946
947 void wxTreeCtrl::OnKillFocus( const wxFocusEvent &WXUNUSED(event) )
948 {
949 m_hasFocus = FALSE;
950 if (m_current) RefreshLine( m_current );
951 };
952
953 void wxTreeCtrl::OnChar( wxKeyEvent &event )
954 {
955 event.Skip();
956 };
957
958 void wxTreeCtrl::OnMouse( const wxMouseEvent &event )
959 {
960 if (!event.LeftDown() &&
961 !event.LeftDClick()) return;
962
963 wxClientDC dc(this);
964 PrepareDC(dc);
965 long x = dc.DeviceToLogicalX( (long)event.GetX() );
966 long y = dc.DeviceToLogicalY( (long)event.GetY() );
967
968 int flag = 0;
969 long id = HitTest( wxPoint(x,y), flag );
970 if (id == -1)
971 return;
972 wxGenericTreeItem *item = FindItem( id );
973
974 if (!item) return;
975 if ((flag != wxTREE_HITTEST_ONITEMBUTTON) &&
976 (flag != wxTREE_HITTEST_ONITEMLABEL)) return;
977
978 SelectItem(item);
979
980 if (event.LeftDClick())
981 m_current->SendKeyDown( this );
982
983 if (flag == wxTREE_HITTEST_ONITEMBUTTON)
984 {
985 ExpandItem( item->m_itemId, wxTREE_EXPAND_TOGGLE );
986 return;
987 };
988 };
989
990 void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y )
991 {
992 int horizX = level*m_indent;
993
994 item->m_x = horizX+33;
995 item->m_y = y-m_lineHeight/3-2;
996 item->m_height = m_lineHeight;
997
998 if (item->NumberOfVisibleChildren() == 0) return;
999
1000 wxNode *node = item->m_children.First();
1001 while (node)
1002 {
1003 wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data();
1004
1005 y += m_lineHeight;
1006 CalculateLevel( child, dc, level+1, y );
1007
1008 node = node->Next();
1009 };
1010 };
1011
1012 void wxTreeCtrl::CalculatePositions()
1013 {
1014 if (!m_anchor)
1015 return;
1016
1017 wxClientDC dc(this);
1018 PrepareDC( dc );
1019
1020 dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
1021
1022 dc.SetPen( m_dottedPen );
1023 m_lineHeight = (int)(dc.GetCharHeight() + 4);
1024
1025 int y = m_lineHeight / 2 + 2;
1026 CalculateLevel( m_anchor, dc, 0, y );
1027 };
1028
1029 wxGenericTreeItem *wxTreeCtrl::FindItem( long itemId ) const
1030 {
1031 if (!m_anchor) return NULL;
1032 return m_anchor->FindItem( itemId );
1033 };
1034
1035 void wxTreeCtrl::RefreshLine( wxGenericTreeItem *item )
1036 {
1037 if (!item) return;
1038 wxClientDC dc(this);
1039 PrepareDC( dc );
1040 wxRect rect;
1041 rect.x = dc.LogicalToDeviceX( item->m_x-2 );
1042 rect.y = dc.LogicalToDeviceY( item->m_y-2 );
1043 rect.width = 1000;
1044 rect.height = dc.GetCharHeight()+4;
1045 Refresh( TRUE, &rect );
1046 };
1047
1048
1049