1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "treectrl.h"
15 #include "wx/treectrl.h"
16 #include "wx/settings.h"
20 //-----------------------------------------------------------------------------
22 //-----------------------------------------------------------------------------
24 IMPLEMENT_DYNAMIC_CLASS(wxTreeItem
, wxObject
)
26 wxTreeItem::wxTreeItem()
38 //-----------------------------------------------------------------------------
40 //-----------------------------------------------------------------------------
42 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent
,wxCommandEvent
)
44 wxTreeEvent::wxTreeEvent( wxEventType commandType
, int id
) :
45 wxCommandEvent( commandType
, id
)
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
55 IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeItem
,wxObject
)
57 wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem
*parent
)
64 wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem
*parent
, const wxTreeItem
& item
, wxDC
*dc
)
72 void wxGenericTreeItem::SetItem( const wxTreeItem
&item
, wxDC
*dc
)
74 if ((item
.m_mask
& wxTREE_MASK_HANDLE
) == wxTREE_MASK_HANDLE
)
75 m_itemId
= item
.m_itemId
;
76 if ((item
.m_mask
& wxTREE_MASK_STATE
) == wxTREE_MASK_STATE
)
77 m_state
= item
.m_state
;
78 if ((item
.m_mask
& wxTREE_MASK_TEXT
) == wxTREE_MASK_TEXT
)
80 if ((item
.m_mask
& wxTREE_MASK_IMAGE
) == wxTREE_MASK_IMAGE
)
81 m_image
= item
.m_image
;
82 if ((item
.m_mask
& wxTREE_MASK_SELECTED_IMAGE
) == wxTREE_MASK_SELECTED_IMAGE
)
83 m_selectedImage
= item
.m_selectedImage
;
84 if ((item
.m_mask
& wxTREE_MASK_CHILDREN
) == wxTREE_MASK_CHILDREN
)
85 m_hasChildren
= (item
.m_children
> 0);
86 if ((item
.m_mask
& wxTREE_MASK_DATA
) == wxTREE_MASK_DATA
)
90 dc
->GetTextExtent( m_text
, &lw
, &lh
);
95 void wxGenericTreeItem::SetText( const wxString
&text
, wxDC
*dc
)
100 dc
->GetTextExtent( m_text
, &lw
, &lh
);
105 void wxGenericTreeItem::Reset()
111 m_selectedImage
= -1;
113 m_hasChildren
= FALSE
;
122 m_children
.DeleteContents( TRUE
);
123 m_isCollapsed
= TRUE
;
124 m_parent
= (wxGenericTreeItem
*) NULL
;
127 void wxGenericTreeItem::GetItem( wxTreeItem
&item
) const
129 if ((item
.m_mask
& wxTREE_MASK_STATE
) == wxTREE_MASK_STATE
)
130 item
.m_state
= m_state
;
131 if ((item
.m_mask
& wxTREE_MASK_TEXT
) == wxTREE_MASK_TEXT
)
132 item
.m_text
= m_text
;
133 if ((item
.m_mask
& wxTREE_MASK_IMAGE
) == wxTREE_MASK_IMAGE
)
134 item
.m_image
= m_image
;
135 if ((item
.m_mask
& wxTREE_MASK_SELECTED_IMAGE
) == wxTREE_MASK_SELECTED_IMAGE
)
136 item
.m_selectedImage
= m_selectedImage
;
137 if ((item
.m_mask
& wxTREE_MASK_CHILDREN
) == wxTREE_MASK_CHILDREN
)
138 item
.m_children
= (int)m_hasChildren
;
139 if ((item
.m_mask
& wxTREE_MASK_DATA
) == wxTREE_MASK_DATA
)
140 item
.m_data
= m_data
;
143 bool wxGenericTreeItem::HasChildren()
145 return m_hasChildren
;
148 bool wxGenericTreeItem::HasPlus()
150 if ( !HasChildren() )
153 return !IsExpanded();
156 int wxGenericTreeItem::NumberOfVisibleDescendents()
158 int ret
= m_children
.Number();
159 wxNode
*node
= m_children
.First();
162 wxGenericTreeItem
*item
= (wxGenericTreeItem
*)node
->Data();
163 ret
+= item
->NumberOfVisibleDescendents();
169 int wxGenericTreeItem::NumberOfVisibleChildren()
171 return m_isCollapsed
? 0 : m_children
.Number();
174 wxGenericTreeItem
*wxGenericTreeItem::FindItem( long itemId
) const
176 if (m_itemId
== itemId
) return (wxGenericTreeItem
*)(this);
177 wxNode
*node
= m_children
.First();
180 wxGenericTreeItem
*item
= (wxGenericTreeItem
*)node
->Data();
181 wxGenericTreeItem
*res
= item
->FindItem( itemId
);
182 if (res
) return (wxGenericTreeItem
*)(res
);
185 return (wxGenericTreeItem
*) NULL
;
188 void wxGenericTreeItem::AddChild( wxGenericTreeItem
*child
)
190 m_children
.Append( child
);
193 void wxGenericTreeItem::SetCross( int x
, int y
)
199 void wxGenericTreeItem::GetSize( int &x
, int &y
)
201 if (y
< m_y
+ 10) y
= m_y
+10;
202 int width
= m_x
+ m_width
;
203 if (width
> x
) x
= width
;
204 wxNode
*node
= m_children
.First();
207 wxGenericTreeItem
*item
= (wxGenericTreeItem
*)node
->Data();
208 item
->GetSize( x
, y
);
213 long wxGenericTreeItem::HitTest( const wxPoint
& point
, int &flags
)
215 if ((point
.y
> m_y
) && (point
.y
< m_y
+m_height
))
217 if ((point
.x
> m_xCross
-5) &&
218 (point
.x
< m_xCross
+5) &&
219 (point
.y
> m_yCross
-5) &&
220 (point
.y
< m_yCross
+5) &&
223 flags
= wxTREE_HITTEST_ONITEMBUTTON
;
226 if ((point
.x
> m_x
) && (point
.x
< m_x
+m_width
))
228 flags
= wxTREE_HITTEST_ONITEMLABEL
;
233 flags
= wxTREE_HITTEST_ONITEMRIGHT
;
236 flags
= wxTREE_HITTEST_ONITEMINDENT
;
243 wxNode
*node
= m_children
.First();
246 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
247 long res
= child
->HitTest( point
, flags
);
248 if (res
!= -1) return res
;
256 void wxGenericTreeItem::PrepareEvent( wxTreeEvent
&event
)
258 event
.m_item
.m_itemId
= m_itemId
;
259 event
.m_item
.m_state
= m_state
;
260 event
.m_item
.m_text
= m_text
;
261 event
.m_item
.m_image
= m_image
;
262 event
.m_item
.m_selectedImage
= m_selectedImage
;
263 event
.m_item
.m_children
= (int)m_hasChildren
;
264 event
.m_item
.m_data
= m_data
;
267 event
.m_pointDrag
.x
= 0;
268 event
.m_pointDrag
.y
= 0;
271 void wxGenericTreeItem::SendKeyDown( wxWindow
*target
)
273 wxTreeEvent
event( wxEVT_COMMAND_TREE_KEY_DOWN
, target
->GetId() );
274 PrepareEvent( event
);
275 event
.SetEventObject( target
);
276 target
->ProcessEvent( event
);
279 void wxGenericTreeItem::SendSelected( wxWindow
*target
)
281 wxTreeEvent
event( wxEVT_COMMAND_TREE_SEL_CHANGED
, target
->GetId() );
282 PrepareEvent( event
);
283 event
.SetEventObject( target
);
284 target
->ProcessEvent( event
);
287 void wxGenericTreeItem::SendDelete( wxWindow
*target
)
289 wxTreeEvent
event( wxEVT_COMMAND_TREE_DELETE_ITEM
, target
->GetId() );
290 PrepareEvent( event
);
291 event
.SetEventObject( target
);
292 target
->ProcessEvent( event
);
295 void wxGenericTreeItem::SendExpand( wxWindow
*target
)
297 m_isCollapsed
= FALSE
;
299 wxTreeEvent
event( wxEVT_COMMAND_TREE_ITEM_EXPANDING
, target
->GetId() );
300 event
.SetEventObject( target
);
301 PrepareEvent( event
);
302 target
->ProcessEvent( event
);
304 event
.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED
);
305 PrepareEvent( event
);
306 target
->ProcessEvent( event
);
309 void wxGenericTreeItem::SendCollapse( wxWindow
*target
)
311 m_isCollapsed
= TRUE
;
313 wxTreeEvent
event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING
, target
->GetId() );
314 event
.SetEventObject( target
);
315 PrepareEvent( event
);
316 target
->ProcessEvent( event
);
318 event
.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED
);
319 PrepareEvent( event
);
320 target
->ProcessEvent( event
);
323 void wxGenericTreeItem::SetHilight( bool set
)
328 bool wxGenericTreeItem::HasHilight()
333 //-----------------------------------------------------------------------------
335 //-----------------------------------------------------------------------------
337 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
,wxScrolledWindow
)
339 BEGIN_EVENT_TABLE(wxTreeCtrl
,wxScrolledWindow
)
340 EVT_PAINT (wxTreeCtrl::OnPaint
)
341 EVT_MOUSE_EVENTS (wxTreeCtrl::OnMouse
)
342 EVT_CHAR (wxTreeCtrl::OnChar
)
343 EVT_SET_FOCUS (wxTreeCtrl::OnSetFocus
)
344 EVT_KILL_FOCUS (wxTreeCtrl::OnKillFocus
)
347 wxTreeCtrl::wxTreeCtrl()
349 m_current
= (wxGenericTreeItem
*) NULL
;
350 m_anchor
= (wxGenericTreeItem
*) NULL
;
358 m_hilightBrush
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID
);
359 m_imageList
= (wxImageList
*) NULL
;
360 m_smallImageList
= (wxImageList
*) NULL
;
363 wxTreeCtrl::wxTreeCtrl(wxWindow
*parent
, wxWindowID id
,
364 const wxPoint
& pos
, const wxSize
& size
,
365 long style
, const wxString
& name
)
367 m_current
= (wxGenericTreeItem
*) NULL
;
368 m_anchor
= (wxGenericTreeItem
*) NULL
;
376 m_hilightBrush
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID
);
377 m_imageList
= (wxImageList
*) NULL
;
378 m_smallImageList
= (wxImageList
*) NULL
;
379 Create( parent
, id
, pos
, size
, style
, name
);
382 wxTreeCtrl::~wxTreeCtrl()
384 if (m_hilightBrush
) delete m_hilightBrush
;
385 if (m_anchor
) delete m_anchor
;
388 bool wxTreeCtrl::Create(wxWindow
*parent
, wxWindowID id
,
389 const wxPoint
& pos
, const wxSize
& size
,
390 long style
, const wxString
& name
)
392 wxScrolledWindow::Create( parent
, id
, pos
, size
, style
, name
);
393 SetBackgroundColour( *wxWHITE
);
394 m_dottedPen
= wxPen( *wxBLACK
, 0, 0 );
398 int wxTreeCtrl::GetCount() const
400 if (!m_anchor
) return 0;
401 return m_anchor
->NumberOfVisibleDescendents();
404 long wxTreeCtrl::InsertItem( long parent
, const wxString
& label
, int image
,
405 int selImage
, long WXUNUSED(insertAfter
) )
407 wxGenericTreeItem
*p
= (wxGenericTreeItem
*) NULL
;
410 if (m_anchor
) return -1;
414 p
= FindItem( parent
);
419 item
.m_mask
= wxTREE_MASK_HANDLE
;
420 item
.m_itemId
= m_lastId
;
421 if (!label
.IsNull() || (label
== ""))
424 item
.m_mask
|= wxTREE_MASK_TEXT
;
428 item
.m_image
= image
;
429 item
.m_mask
|= wxTREE_MASK_IMAGE
;
433 item
.m_selectedImage
= selImage
;
434 item
.m_mask
|= wxTREE_MASK_SELECTED_IMAGE
;
438 wxGenericTreeItem
*new_child
= new wxGenericTreeItem( p
, item
, &dc
);
440 p
->AddChild( new_child
);
442 m_anchor
= new_child
;
446 CalculatePositions();
448 if (!p
->HasChildren()) p
->m_hasChildren
= TRUE
;
451 GetClientSize( &cw
, &ch
);
456 rect
.x
= dc
.LogicalToDeviceX( 0 );
461 if (p
->m_children
.Number() == 1)
463 rect
.y
= dc
.LogicalToDeviceY( p
->m_y
);
467 wxNode
*node
= p
->m_children
.Member( new_child
)->Previous();
468 wxGenericTreeItem
* last_child
= (wxGenericTreeItem
*)node
->Data();
469 rect
.y
= dc
.LogicalToDeviceY( last_child
->m_y
);
472 AdjustMyScrollbars();
474 if (rect
.height
> 0) Refresh( FALSE
, &rect
);
478 AdjustMyScrollbars();
486 long wxTreeCtrl::InsertItem( long parent
, wxTreeItem
&info
, long WXUNUSED(insertAfter
) )
488 int oldMask
= info
.m_mask
;
489 wxGenericTreeItem
*p
= (wxGenericTreeItem
*) NULL
;
492 if (m_anchor
) return -1;
496 p
= FindItem( parent
);
499 printf( "TreeItem not found.\n" );
504 if ((info
.m_mask
& wxTREE_MASK_HANDLE
) == 0)
507 info
.m_itemId
= m_lastId
;
508 info
.m_mask
|= wxTREE_MASK_HANDLE
;
517 wxGenericTreeItem
*new_child
= new wxGenericTreeItem( p
, info
, &dc
);
519 p
->AddChild( new_child
);
521 m_anchor
= new_child
;
525 CalculatePositions();
527 if (!p
->HasChildren()) p
->m_hasChildren
= TRUE
;
530 GetClientSize( (int *) NULL
, &ch
);
535 rect
.x
= dc
.LogicalToDeviceX( 0 );
540 if (p
->m_children
.Number() == 1)
542 rect
.y
= dc
.LogicalToDeviceY( p
->m_y
);
546 wxNode
*node
= p
->m_children
.Member( new_child
)->Previous();
547 wxGenericTreeItem
* last_child
= (wxGenericTreeItem
*)node
->Data();
548 rect
.y
= dc
.LogicalToDeviceY( last_child
->m_y
);
551 AdjustMyScrollbars();
553 if (rect
.height
> 0) Refresh( FALSE
, &rect
);
557 AdjustMyScrollbars();
562 info
.m_mask
= oldMask
;
566 bool wxTreeCtrl::ExpandItem( long item
, int action
)
568 wxGenericTreeItem
*i
= FindItem( item
);
574 case wxTREE_EXPAND_EXPAND
:
576 i
->SendExpand( this );
580 case wxTREE_EXPAND_COLLAPSE_RESET
:
581 case wxTREE_EXPAND_COLLAPSE
:
583 wxNode
*node
= i
->m_children
.First();
586 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
587 if ( child
->IsExpanded() )
588 ExpandItem( child
->m_itemId
, wxTREE_EXPAND_COLLAPSE
);
592 CalculatePositions();
594 i
->SendCollapse( this );
598 case wxTREE_EXPAND_TOGGLE
:
600 if ( i
->IsExpanded() )
601 ExpandItem( item
, wxTREE_EXPAND_COLLAPSE
);
603 ExpandItem( item
, wxTREE_EXPAND_EXPAND
);
613 GetClientSize( &cw
, &ch
);
616 rect
.x
= dc
.LogicalToDeviceX( 0 );
618 rect
.y
= dc
.LogicalToDeviceY( i
->m_y
);
620 Refresh( TRUE
, &rect
);
622 AdjustMyScrollbars();
627 void wxTreeCtrl::DeleteItem( long item
)
629 wxGenericTreeItem
*pItem
= FindItem( item
);
630 wxCHECK_RET( pItem
!= NULL
, _("wxTreeCtrl::DeleteItem: no such pItem.") );
632 pItem
->m_parent
->m_children
.DeleteObject(pItem
);
637 void wxTreeCtrl::DeleteChildren( long item
)
639 wxGenericTreeItem
*pItem
= FindItem( item
);
640 wxCHECK_RET( pItem
!= NULL
, _("wxTreeCtrl::DeleteChildren: no such pItem.") );
642 pItem
->m_children
.Clear();
647 bool wxTreeCtrl::DeleteAllItems()
650 m_anchor
= (wxGenericTreeItem
*) NULL
;
655 bool wxTreeCtrl::GetItem( wxTreeItem
&info
) const
657 wxGenericTreeItem
*i
= FindItem( info
.m_itemId
);
658 if (!i
) return FALSE
;
663 long wxTreeCtrl::GetItemData( long item
) const
665 wxGenericTreeItem
*i
= FindItem( item
);
670 wxString
wxTreeCtrl::GetItemText( long item
) const
672 wxGenericTreeItem
*i
= FindItem( item
);
677 int wxTreeCtrl::GetItemImage(long item
) const
679 wxGenericTreeItem
*i
= FindItem( item
);
680 return i
== 0 ? -1 : i
->GetImage();
683 long wxTreeCtrl::GetParent( long item
) const
685 wxGenericTreeItem
*i
= FindItem( item
);
689 return i
->m_parent
->m_itemId
;
692 long wxTreeCtrl::GetRootItem() const
694 if (m_anchor
) return m_anchor
->m_itemId
;
698 long wxTreeCtrl::GetChild( long item
) const
700 wxGenericTreeItem
*i
= FindItem( item
);
702 if (!i
->HasChildren()) return -1;
703 wxNode
*node
= i
->m_children
.First();
704 i
= (wxGenericTreeItem
*)node
->Data();
708 long wxTreeCtrl::GetNextItem( long item
, int code
) const
712 case wxTREE_NEXT_CARET
: return GetSelection();
713 case wxTREE_NEXT_CHILD
: return GetChild( item
);
714 case wxTREE_NEXT_ROOT
: return GetRootItem();
715 case wxTREE_NEXT_PARENT
: return GetParent( item
);
716 case wxTREE_NEXT_NEXT
:
718 wxGenericTreeItem
*i
= FindItem( item
);
722 wxNode
*node
= i
->m_parent
->m_children
.Member( i
);
723 if (!node
) return -1;
725 if (!node
) return -1;
726 i
= (wxGenericTreeItem
*)node
->Data();
731 case wxTREE_NEXT_PREVIOUS
:
733 wxGenericTreeItem
*i
= FindItem( item
);
737 wxNode
*node
= i
->m_parent
->m_children
.Member( i
);
738 if (!node
) return -1;
739 node
= node
->Previous();
740 if (!node
) return -1;
741 i
= (wxGenericTreeItem
*)node
->Data();
750 long wxTreeCtrl::GetSelection() const
752 return m_current
? m_current
->GetItemId() : -1;
755 bool wxTreeCtrl::SelectItem( long itemId
)
757 wxGenericTreeItem
*pItem
= FindItem(itemId
);
759 wxLogDebug(_("Can't select an item %d which doesn't exist."), itemId
);
769 void wxTreeCtrl::SelectItem(wxGenericTreeItem
*item
)
771 if (m_current
!= item
)
775 m_current
->SetHilight( FALSE
);
776 RefreshLine( m_current
);
779 m_current
->SetHilight( TRUE
);
780 RefreshLine( m_current
);
782 m_current
->SendSelected( this );
786 bool wxTreeCtrl::ItemHasChildren( long item
) const
788 wxGenericTreeItem
*i
= FindItem( item
);
789 if (!i
) return FALSE
;
790 return i
->m_hasChildren
;
793 void wxTreeCtrl::SetIndent( int indent
)
799 int wxTreeCtrl::GetIndent() const
804 bool wxTreeCtrl::SetItem( wxTreeItem
&info
)
806 wxGenericTreeItem
*i
= FindItem( info
.m_itemId
);
807 if (!i
) return FALSE
;
809 i
->SetItem( info
, &dc
);
814 bool wxTreeCtrl::SetItemData( long item
, long data
)
816 wxGenericTreeItem
*i
= FindItem( item
);
817 if (!i
) return FALSE
;
822 bool wxTreeCtrl::SetItemText( long item
, const wxString
&text
)
824 wxGenericTreeItem
*i
= FindItem( item
);
825 if (!i
) return FALSE
;
827 i
->SetText( text
, &dc
);
831 void wxTreeCtrl::SetItemImage(long item
, int image
, int imageSel
) const
833 wxGenericTreeItem
*i
= FindItem( item
);
837 i
->SetSelectedImage(imageSel
);
841 int wxTreeCtrl::GetItemState( long item
, long stateMask
) const
843 wxGenericTreeItem
*i
= FindItem( item
);
847 // Currently, an item is always selected _and_ focussed in wxGTK
849 if (stateMask
& wxTREE_STATE_FOCUSED
)
851 ret
+= wxTREE_STATE_FOCUSED
;
853 if (stateMask
& wxTREE_STATE_SELECTED
)
855 ret
+= wxTREE_STATE_SELECTED
;
857 if (stateMask
& wxTREE_STATE_EXPANDED
)
859 ret
+= wxTREE_STATE_EXPANDED
;
864 bool wxTreeCtrl::SetItemState( long item
, long state
, long stateMask
)
866 wxGenericTreeItem
*i
= FindItem( item
);
867 if (!i
) return FALSE
;
869 if (stateMask
& wxTREE_STATE_FOCUSED
)
871 if (state
& wxTREE_STATE_FOCUSED
)
875 if (stateMask
& wxTREE_STATE_SELECTED
)
877 if (state
& wxTREE_STATE_SELECTED
)
881 if (stateMask
& wxTREE_STATE_EXPANDED
)
883 if (state
& wxTREE_STATE_EXPANDED
)
884 ExpandItem( i
->m_itemId
, wxTREE_EXPAND_EXPAND
);
886 ExpandItem( i
->m_itemId
, wxTREE_EXPAND_COLLAPSE
);
892 long wxTreeCtrl::HitTest( const wxPoint
& point
, int &flags
)
895 if (!m_anchor
) return -1;
896 return m_anchor
->HitTest( point
, flags
);
899 wxImageList
*wxTreeCtrl::GetImageList( int which
) const
901 if (which
== wxIMAGE_LIST_NORMAL
) return m_imageList
;
902 return m_smallImageList
;
905 void wxTreeCtrl::SetImageList( wxImageList
*imageList
, int which
)
907 if (which
== wxIMAGE_LIST_NORMAL
)
909 if (m_imageList
) delete m_imageList
;
910 m_imageList
= imageList
;
914 if (m_smallImageList
) delete m_smallImageList
;
915 m_smallImageList
= imageList
;
919 void wxTreeCtrl::AdjustMyScrollbars()
925 m_anchor
->GetSize( x
, y
);
927 int x_pos
= GetScrollPos( wxHORIZONTAL
);
928 int y_pos
= GetScrollPos( wxVERTICAL
);
929 SetScrollbars( 10, 10, x
/10, y
/10, x_pos
, y_pos
);
933 SetScrollbars( 0, 0, 0, 0 );
937 void wxTreeCtrl::PaintLevel( wxGenericTreeItem
*item
, wxDC
&dc
, int level
, int &y
)
939 int horizX
= level
*m_indent
;
941 item
->m_x
= horizX
+33;
942 item
->m_y
= y
-m_lineHeight
/3;
943 item
->m_height
= m_lineHeight
;
945 item
->SetCross( horizX
+15, y
);
949 int exposed_x
= dc
.LogicalToDeviceX( 0 );
950 int exposed_y
= dc
.LogicalToDeviceY( item
->m_y
-2 );
952 if (IsExposed( exposed_x
, exposed_y
, 1000, m_lineHeight
+4 ))
955 int endX
= horizX
+ 10;
957 if (!item
->HasChildren()) endX
+= 20;
959 dc
.DrawLine( startX
, y
, endX
, y
);
961 if (item
->HasChildren())
963 dc
.DrawLine( horizX
+20, y
, horizX
+30, y
);
964 dc
.SetPen( *wxGREY_PEN
);
965 dc
.DrawRectangle( horizX
+10, y
-4, 11, 9 );
966 dc
.SetPen( *wxBLACK_PEN
);
967 dc
.DrawLine( horizX
+13, y
, horizX
+18, y
);
969 dc
.DrawLine( horizX
+15, y
-2, horizX
+15, y
+3 );
972 if (item
->HasHilight())
974 dc
.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT
) );
975 dc
.SetBrush( *m_hilightBrush
);
977 dc
.GetTextExtent( item
->m_text
, &tw
, &th
);
980 dc
.SetPen( *wxBLACK_PEN
);
981 dc
.DrawRectangle( item
->m_x
-2, item
->m_y
-2, tw
+4, th
+4 );
985 dc
.SetPen( *wxTRANSPARENT_PEN
);
986 dc
.DrawRectangle( item
->m_x
-2, item
->m_y
-2, tw
+4, th
+4 );
988 dc
.DrawText( item
->m_text
, item
->m_x
, item
->m_y
);
990 dc
.SetPen( *wxBLACK_PEN
);
991 dc
.SetTextForeground( *wxBLACK
);
992 dc
.SetBrush( *wxWHITE_BRUSH
);
996 dc
.SetBrush( *wxWHITE_BRUSH
);
997 dc
.SetPen( *wxTRANSPARENT_PEN
);
999 dc
.GetTextExtent( item
->m_text
, &tw
, &th
);
1000 dc
.DrawRectangle( item
->m_x
-2, item
->m_y
-2, tw
+4, th
+4 );
1001 dc
.DrawText( item
->m_text
, item
->m_x
, item
->m_y
);
1002 dc
.SetPen( *wxBLACK_PEN
);
1006 if (item
->NumberOfVisibleChildren() == 0) return;
1010 wxNode
*node
= item
->m_children
.First();
1013 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
1018 PaintLevel( child
, dc
, level
+1, y
);
1020 node
= node
->Next();
1023 dc
.DrawLine( horizX
+15, oldY
+5, horizX
+15, semiOldY
);
1026 void wxTreeCtrl::OnPaint( const wxPaintEvent
&WXUNUSED(event
) )
1028 if (!m_anchor
) return;
1033 dc
.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT
) );
1035 dc
.SetPen( m_dottedPen
);
1036 m_lineHeight
= (int)(dc
.GetCharHeight() + 4);
1038 int y
= m_lineHeight
/ 2 + 2;
1039 PaintLevel( m_anchor
, dc
, 0, y
);
1042 void wxTreeCtrl::OnSetFocus( const wxFocusEvent
&WXUNUSED(event
) )
1045 if (m_current
) RefreshLine( m_current
);
1048 void wxTreeCtrl::OnKillFocus( const wxFocusEvent
&WXUNUSED(event
) )
1051 if (m_current
) RefreshLine( m_current
);
1054 void wxTreeCtrl::OnChar( wxKeyEvent
&event
)
1059 void wxTreeCtrl::OnMouse( const wxMouseEvent
&event
)
1061 if (!event
.LeftDown() &&
1062 !event
.LeftDClick()) return;
1064 wxClientDC
dc(this);
1066 long x
= dc
.DeviceToLogicalX( (long)event
.GetX() );
1067 long y
= dc
.DeviceToLogicalY( (long)event
.GetY() );
1070 long id
= HitTest( wxPoint(x
,y
), flag
);
1073 wxGenericTreeItem
*item
= FindItem( id
);
1076 if ((flag
!= wxTREE_HITTEST_ONITEMBUTTON
) &&
1077 (flag
!= wxTREE_HITTEST_ONITEMLABEL
)) return;
1081 if (event
.LeftDClick())
1082 m_current
->SendKeyDown( this );
1084 if (flag
== wxTREE_HITTEST_ONITEMBUTTON
)
1086 ExpandItem( item
->m_itemId
, wxTREE_EXPAND_TOGGLE
);
1091 void wxTreeCtrl::CalculateLevel( wxGenericTreeItem
*item
, wxDC
&dc
, int level
, int &y
)
1093 int horizX
= level
*m_indent
;
1095 item
->m_x
= horizX
+33;
1096 item
->m_y
= y
-m_lineHeight
/3-2;
1097 item
->m_height
= m_lineHeight
;
1099 if (item
->NumberOfVisibleChildren() == 0) return;
1101 wxNode
*node
= item
->m_children
.First();
1104 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
1107 CalculateLevel( child
, dc
, level
+1, y
);
1109 node
= node
->Next();
1113 void wxTreeCtrl::CalculatePositions()
1118 wxClientDC
dc(this);
1121 dc
.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT
) );
1123 dc
.SetPen( m_dottedPen
);
1124 m_lineHeight
= (int)(dc
.GetCharHeight() + 4);
1126 int y
= m_lineHeight
/ 2 + 2;
1127 CalculateLevel( m_anchor
, dc
, 0, y
);
1130 wxGenericTreeItem
*wxTreeCtrl::FindItem( long itemId
) const
1132 if (!m_anchor
) return (wxGenericTreeItem
*) NULL
;
1133 return m_anchor
->FindItem( itemId
);
1136 void wxTreeCtrl::RefreshLine( wxGenericTreeItem
*item
)
1139 wxClientDC
dc(this);
1142 rect
.x
= dc
.LogicalToDeviceX( item
->m_x
-2 );
1143 rect
.y
= dc
.LogicalToDeviceY( item
->m_y
-2 );
1145 rect
.height
= dc
.GetCharHeight()+6;
1146 Refresh( TRUE
, &rect
);