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