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"
19 //-----------------------------------------------------------------------------
21 //-----------------------------------------------------------------------------
23 IMPLEMENT_DYNAMIC_CLASS(wxTreeItem
, wxObject
)
25 wxTreeItem::wxTreeItem()
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent
,wxCommandEvent
)
43 wxTreeEvent::wxTreeEvent( wxEventType commandType
, int id
) :
44 wxCommandEvent( commandType
, id
)
50 //-----------------------------------------------------------------------------
52 //-----------------------------------------------------------------------------
54 IMPLEMENT_DYNAMIC_CLASS(wxGenericTreeItem
,wxObject
)
56 wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem
*parent
)
63 wxGenericTreeItem::wxGenericTreeItem( wxGenericTreeItem
*parent
, const wxTreeItem
& item
, wxDC
*dc
)
71 void wxGenericTreeItem::SetItem( const wxTreeItem
&item
, wxDC
*dc
)
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
)
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
)
89 dc
->GetTextExtent( m_text
, &lw
, &lh
);
94 void wxGenericTreeItem::SetText( const wxString
&text
, wxDC
*dc
)
99 dc
->GetTextExtent( m_text
, &lw
, &lh
);
104 void wxGenericTreeItem::Reset()
110 m_selectedImage
= -1;
112 m_hasChildren
= FALSE
;
121 m_children
.DeleteContents( TRUE
);
122 m_isCollapsed
= TRUE
;
126 void wxGenericTreeItem::GetItem( wxTreeItem
&item
) const
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
;
142 bool wxGenericTreeItem::HasChildren()
144 return m_hasChildren
;
147 bool wxGenericTreeItem::HasPlus()
149 if ( !HasChildren() )
152 return !IsExpanded();
155 int wxGenericTreeItem::NumberOfVisibleDescendents()
157 int ret
= m_children
.Number();
158 wxNode
*node
= m_children
.First();
161 wxGenericTreeItem
*item
= (wxGenericTreeItem
*)node
->Data();
162 ret
+= item
->NumberOfVisibleDescendents();
168 int wxGenericTreeItem::NumberOfVisibleChildren()
170 return m_isCollapsed
? 0 : m_children
.Number();
173 wxGenericTreeItem
*wxGenericTreeItem::FindItem( long itemId
) const
175 if (m_itemId
== itemId
) return (wxGenericTreeItem
*)(this);
176 wxNode
*node
= m_children
.First();
179 wxGenericTreeItem
*item
= (wxGenericTreeItem
*)node
->Data();
180 wxGenericTreeItem
*res
= item
->FindItem( itemId
);
181 if (res
) return (wxGenericTreeItem
*)(res
);
187 void wxGenericTreeItem::AddChild( wxGenericTreeItem
*child
)
189 m_children
.Append( child
);
192 void wxGenericTreeItem::SetCross( int x
, int y
)
198 void wxGenericTreeItem::GetSize( int &x
, int &y
)
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();
206 wxGenericTreeItem
*item
= (wxGenericTreeItem
*)node
->Data();
207 item
->GetSize( x
, y
);
212 long wxGenericTreeItem::HitTest( const wxPoint
& point
, int &flags
)
214 if ((point
.y
> m_y
) && (point
.y
< m_y
+m_height
))
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) &&
222 flags
= wxTREE_HITTEST_ONITEMBUTTON
;
225 if ((point
.x
> m_x
) && (point
.x
< m_x
+m_width
))
227 flags
= wxTREE_HITTEST_ONITEMLABEL
;
232 flags
= wxTREE_HITTEST_ONITEMRIGHT
;
235 flags
= wxTREE_HITTEST_ONITEMINDENT
;
242 wxNode
*node
= m_children
.First();
245 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
246 long res
= child
->HitTest( point
, flags
);
247 if (res
!= -1) return res
;
255 void wxGenericTreeItem::PrepareEvent( wxTreeEvent
&event
)
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
;
266 event
.m_pointDrag
.x
= 0;
267 event
.m_pointDrag
.y
= 0;
270 void wxGenericTreeItem::SendKeyDown( wxWindow
*target
)
272 wxTreeEvent
event( wxEVT_COMMAND_TREE_KEY_DOWN
, target
->GetId() );
273 PrepareEvent( event
);
274 event
.SetEventObject( target
);
275 target
->ProcessEvent( event
);
278 void wxGenericTreeItem::SendSelected( wxWindow
*target
)
280 wxTreeEvent
event( wxEVT_COMMAND_TREE_SEL_CHANGED
, target
->GetId() );
281 PrepareEvent( event
);
282 event
.SetEventObject( target
);
283 target
->ProcessEvent( event
);
286 void wxGenericTreeItem::SendDelete( wxWindow
*target
)
288 wxTreeEvent
event( wxEVT_COMMAND_TREE_DELETE_ITEM
, target
->GetId() );
289 PrepareEvent( event
);
290 event
.SetEventObject( target
);
291 target
->ProcessEvent( event
);
294 void wxGenericTreeItem::SendExpand( wxWindow
*target
)
296 m_isCollapsed
= FALSE
;
298 wxTreeEvent
event( wxEVT_COMMAND_TREE_ITEM_EXPANDING
, target
->GetId() );
299 event
.SetEventObject( target
);
300 PrepareEvent( event
);
301 target
->ProcessEvent( event
);
303 event
.SetEventType(wxEVT_COMMAND_TREE_ITEM_EXPANDED
);
304 PrepareEvent( event
);
305 target
->ProcessEvent( event
);
308 void wxGenericTreeItem::SendCollapse( wxWindow
*target
)
310 m_isCollapsed
= TRUE
;
312 wxTreeEvent
event( wxEVT_COMMAND_TREE_ITEM_COLLAPSING
, target
->GetId() );
313 event
.SetEventObject( target
);
314 PrepareEvent( event
);
315 target
->ProcessEvent( event
);
317 event
.SetEventType(wxEVT_COMMAND_TREE_ITEM_COLLAPSED
);
318 PrepareEvent( event
);
319 target
->ProcessEvent( event
);
322 void wxGenericTreeItem::SetHilight( bool set
)
327 bool wxGenericTreeItem::HasHilight()
332 //-----------------------------------------------------------------------------
334 //-----------------------------------------------------------------------------
336 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl
,wxScrolledWindow
)
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
)
346 wxTreeCtrl::wxTreeCtrl()
358 m_hilightBrush
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID
);
360 m_smallImageList
= NULL
;
363 wxTreeCtrl::wxTreeCtrl(wxWindow
*parent
, wxWindowID id
,
364 const wxPoint
& pos
, const wxSize
& size
,
365 long style
, const wxString
& name
)
377 m_hilightBrush
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID
);
379 m_smallImageList
= NULL
;
380 Create( parent
, id
, pos
, size
, style
, name
);
383 wxTreeCtrl::~wxTreeCtrl()
385 if (m_dc
) delete m_dc
;
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
= 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( NULL
, &ch
);
454 rect
.x
= 0; rect
.y
= 0;
455 rect
.width
= 10000; rect
.height
= ch
;
458 if (p
->m_children
.Number() == 1)
460 rect
.y
= dc
.LogicalToDeviceY( p
->m_y
);
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
);
471 dc
.GetDeviceOrigin( &doX
, &doY
);
472 rect
.height
= ch
-rect
.y
-doY
;
474 AdjustMyScrollbars();
476 if (rect
.height
> 0) Refresh( FALSE
, &rect
);
480 AdjustMyScrollbars();
488 long wxTreeCtrl::InsertItem( long parent
, wxTreeItem
&info
, long WXUNUSED(insertAfter
) )
490 int oldMask
= info
.m_mask
;
491 wxGenericTreeItem
*p
= NULL
;
494 if (m_anchor
) return -1;
498 p
= FindItem( parent
);
501 printf( "TreeItem not found.\n" );
506 if ((info
.m_mask
& wxTREE_MASK_HANDLE
) == 0)
509 info
.m_itemId
= m_lastId
;
510 info
.m_mask
|= wxTREE_MASK_HANDLE
;
519 wxGenericTreeItem
*new_child
= new wxGenericTreeItem( p
, info
, &dc
);
521 p
->AddChild( new_child
);
523 m_anchor
= new_child
;
527 CalculatePositions();
529 if (!p
->HasChildren()) p
->m_hasChildren
= TRUE
;
532 GetClientSize( NULL
, &ch
);
535 rect
.x
= 0; rect
.y
= 0;
536 rect
.width
= 10000; rect
.height
= ch
;
539 if (p
->m_children
.Number() == 1)
541 rect
.y
= dc
.LogicalToDeviceY( p
->m_y
);
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
);
552 dc
.GetDeviceOrigin( &doX
, &doY
);
553 rect
.height
= ch
-rect
.y
-doY
;
555 AdjustMyScrollbars();
557 if (rect
.height
> 0) Refresh( FALSE
, &rect
);
561 AdjustMyScrollbars();
566 info
.m_mask
= oldMask
;
570 bool wxTreeCtrl::ExpandItem( long item
, int action
)
572 wxGenericTreeItem
*i
= FindItem( item
);
578 case wxTREE_EXPAND_EXPAND
:
580 i
->SendExpand( this );
584 case wxTREE_EXPAND_COLLAPSE_RESET
:
585 case wxTREE_EXPAND_COLLAPSE
:
587 wxNode
*node
= i
->m_children
.First();
590 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
591 if ( child
->IsExpanded() )
592 ExpandItem( child
->m_itemId
, wxTREE_EXPAND_COLLAPSE
);
596 CalculatePositions();
598 i
->SendCollapse( this );
602 case wxTREE_EXPAND_TOGGLE
:
604 if ( i
->IsExpanded() )
605 ExpandItem( item
, wxTREE_EXPAND_COLLAPSE
);
607 ExpandItem( item
, wxTREE_EXPAND_EXPAND
);
614 GetClientSize( &cw
, &ch
);
620 rect
.y
= dc
.LogicalToDeviceY( i
->m_y
);
623 dc
.GetDeviceOrigin( NULL
, &doY
);
624 rect
.height
= ch
-rect
.y
-doY
;
625 Refresh( TRUE
, &rect
);
627 AdjustMyScrollbars();
632 void wxTreeCtrl::DeleteItem( long item
)
634 wxGenericTreeItem
*pItem
= FindItem( item
);
635 wxCHECK_RET( pItem
!= NULL
, "wxTreeCtrl::DeleteItem: no such pItem." );
637 pItem
->m_parent
->m_children
.DeleteObject(pItem
);
642 void wxTreeCtrl::DeleteChildren( long item
)
644 wxGenericTreeItem
*pItem
= FindItem( item
);
645 wxCHECK_RET( pItem
!= NULL
, "wxTreeCtrl::DeleteChildren: no such pItem." );
647 pItem
->m_children
.Clear();
652 bool wxTreeCtrl::DeleteAllItems()
660 bool wxTreeCtrl::GetItem( wxTreeItem
&info
) const
662 wxGenericTreeItem
*i
= FindItem( info
.m_itemId
);
663 if (!i
) return FALSE
;
668 long wxTreeCtrl::GetItemData( long item
) const
670 wxGenericTreeItem
*i
= FindItem( item
);
675 wxString
wxTreeCtrl::GetItemText( long item
) const
677 wxGenericTreeItem
*i
= FindItem( item
);
682 int wxTreeCtrl::GetItemImage(long item
) const
684 wxGenericTreeItem
*i
= FindItem( item
);
685 return i
== 0 ? -1 : i
->GetImage();
688 long wxTreeCtrl::GetParent( long item
) const
690 wxGenericTreeItem
*i
= FindItem( item
);
694 return i
->m_parent
->m_itemId
;
697 long wxTreeCtrl::GetRootItem() const
699 if (m_anchor
) return m_anchor
->m_itemId
;
703 long wxTreeCtrl::GetSelection() const
705 return m_current
? m_current
->GetItemId() : -1;
708 bool wxTreeCtrl::SelectItem(long itemId
)
710 wxGenericTreeItem
*pItem
= FindItem(itemId
);
712 wxLogDebug("Can't select an item %d which doesn't exist.", itemId
);
722 void wxTreeCtrl::SelectItem(wxGenericTreeItem
*item
)
724 if (m_current
!= item
)
728 m_current
->SetHilight( FALSE
);
729 RefreshLine( m_current
);
732 m_current
->SetHilight( TRUE
);
733 RefreshLine( m_current
);
735 m_current
->SendSelected( this );
739 bool wxTreeCtrl::ItemHasChildren( long item
) const
741 wxGenericTreeItem
*i
= FindItem( item
);
742 if (!i
) return FALSE
;
743 return i
->m_hasChildren
;
746 void wxTreeCtrl::SetIndent( int indent
)
752 int wxTreeCtrl::GetIndent() const
757 bool wxTreeCtrl::SetItem( wxTreeItem
&info
)
759 wxGenericTreeItem
*i
= FindItem( info
.m_itemId
);
760 if (!i
) return FALSE
;
762 i
->SetItem( info
, &dc
);
767 bool wxTreeCtrl::SetItemData( long item
, long data
)
769 wxGenericTreeItem
*i
= FindItem( item
);
770 if (!i
) return FALSE
;
775 bool wxTreeCtrl::SetItemText( long item
, const wxString
&text
)
777 wxGenericTreeItem
*i
= FindItem( item
);
778 if (!i
) return FALSE
;
780 i
->SetText( text
, &dc
);
784 void wxTreeCtrl::SetItemImage(long item
, int image
, int imageSel
) const
786 wxGenericTreeItem
*i
= FindItem( item
);
789 i
->SetSelectedImage(imageSel
);
793 long wxTreeCtrl::HitTest( const wxPoint
& point
, int &flags
)
796 if (!m_anchor
) return -1;
797 return m_anchor
->HitTest( point
, flags
);
800 wxImageList
*wxTreeCtrl::GetImageList( int which
) const
802 if (which
== wxIMAGE_LIST_NORMAL
) return m_imageList
;
803 return m_smallImageList
;
806 void wxTreeCtrl::SetImageList( wxImageList
*imageList
, int which
)
808 if (which
== wxIMAGE_LIST_NORMAL
)
810 if (m_imageList
) delete m_imageList
;
811 m_imageList
= imageList
;
815 if (m_smallImageList
) delete m_smallImageList
;
816 m_smallImageList
= imageList
;
820 void wxTreeCtrl::AdjustMyScrollbars()
826 m_anchor
->GetSize( x
, y
);
828 int x_pos
= GetScrollPos( wxHORIZONTAL
);
829 int y_pos
= GetScrollPos( wxVERTICAL
);
830 SetScrollbars( 10, 10, x
/10, y
/10, x_pos
, y_pos
);
834 SetScrollbars( 0, 0, 0, 0 );
838 void wxTreeCtrl::PaintLevel( wxGenericTreeItem
*item
, wxPaintDC
&dc
, int level
, int &y
)
840 int horizX
= level
*m_indent
;
842 item
->m_x
= horizX
+33;
843 item
->m_y
= y
-m_lineHeight
/3;
844 item
->m_height
= m_lineHeight
;
846 item
->SetCross( horizX
+15, y
);
850 if (IsExposed( 0, item
->m_y
-2, 10000, m_lineHeight
+4 ))
853 int endX
= horizX
+ 10;
855 if (!item
->HasChildren()) endX
+= 20;
856 dc
.DrawLine( startX
, y
, endX
, y
);
858 if (item
->HasChildren())
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
);
866 dc
.DrawLine( horizX
+15, y
-2, horizX
+15, y
+3 );
869 if (item
->HasHilight())
871 dc
.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT
) );
872 dc
.SetBrush( *m_hilightBrush
);
874 dc
.GetTextExtent( item
->m_text
, &tw
, &th
);
877 dc
.SetPen( *wxBLACK_PEN
);
878 dc
.DrawRectangle( item
->m_x
-2, item
->m_y
-2, tw
+4, th
+4 );
882 dc
.SetPen( *wxTRANSPARENT_PEN
);
883 dc
.DrawRectangle( item
->m_x
-2, item
->m_y
-2, tw
+4, th
+4 );
885 dc
.DrawText( item
->m_text
, item
->m_x
, item
->m_y
);
887 dc
.SetPen( *wxBLACK_PEN
);
888 dc
.SetTextForeground( *wxBLACK
);
889 dc
.SetBrush( *wxWHITE_BRUSH
);
893 dc
.SetPen( *wxTRANSPARENT_PEN
);
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
);
902 if (item
->NumberOfVisibleChildren() == 0) return;
906 wxNode
*node
= item
->m_children
.First();
909 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
914 PaintLevel( child
, dc
, level
+1, y
);
919 dc
.DrawLine( horizX
+15, oldY
+5, horizX
+15, semiOldY
);
922 void wxTreeCtrl::OnPaint( const wxPaintEvent
&WXUNUSED(event
) )
924 if (!m_anchor
) return;
928 m_dc
= new wxPaintDC(this);
932 m_dc
->SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT
) );
934 m_dc
->SetPen( m_dottedPen
);
935 m_lineHeight
= (int)(m_dc
->GetCharHeight() + 4);
937 int y
= m_lineHeight
/ 2 + 2;
938 PaintLevel( m_anchor
, *m_dc
, 0, y
);
941 void wxTreeCtrl::OnSetFocus( const wxFocusEvent
&WXUNUSED(event
) )
944 if (m_current
) RefreshLine( m_current
);
947 void wxTreeCtrl::OnKillFocus( const wxFocusEvent
&WXUNUSED(event
) )
950 if (m_current
) RefreshLine( m_current
);
953 void wxTreeCtrl::OnChar( wxKeyEvent
&event
)
958 void wxTreeCtrl::OnMouse( const wxMouseEvent
&event
)
960 if (!event
.LeftDown() &&
961 !event
.LeftDClick()) return;
965 long x
= dc
.DeviceToLogicalX( (long)event
.GetX() );
966 long y
= dc
.DeviceToLogicalY( (long)event
.GetY() );
969 long id
= HitTest( wxPoint(x
,y
), flag
);
972 wxGenericTreeItem
*item
= FindItem( id
);
975 if ((flag
!= wxTREE_HITTEST_ONITEMBUTTON
) &&
976 (flag
!= wxTREE_HITTEST_ONITEMLABEL
)) return;
980 if (event
.LeftDClick())
981 m_current
->SendKeyDown( this );
983 if (flag
== wxTREE_HITTEST_ONITEMBUTTON
)
985 ExpandItem( item
->m_itemId
, wxTREE_EXPAND_TOGGLE
);
990 void wxTreeCtrl::CalculateLevel( wxGenericTreeItem
*item
, wxPaintDC
&dc
, int level
, int &y
)
992 int horizX
= level
*m_indent
;
994 item
->m_x
= horizX
+33;
995 item
->m_y
= y
-m_lineHeight
/3-2;
996 item
->m_height
= m_lineHeight
;
998 if (item
->NumberOfVisibleChildren() == 0) return;
1000 wxNode
*node
= item
->m_children
.First();
1003 wxGenericTreeItem
*child
= (wxGenericTreeItem
*)node
->Data();
1006 CalculateLevel( child
, dc
, level
+1, y
);
1008 node
= node
->Next();
1012 void wxTreeCtrl::CalculatePositions()
1017 wxClientDC
dc(this);
1020 dc
.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT
) );
1022 dc
.SetPen( m_dottedPen
);
1023 m_lineHeight
= (int)(dc
.GetCharHeight() + 4);
1025 int y
= m_lineHeight
/ 2 + 2;
1026 CalculateLevel( m_anchor
, dc
, 0, y
);
1029 wxGenericTreeItem
*wxTreeCtrl::FindItem( long itemId
) const
1031 if (!m_anchor
) return NULL
;
1032 return m_anchor
->FindItem( itemId
);
1035 void wxTreeCtrl::RefreshLine( wxGenericTreeItem
*item
)
1038 wxClientDC
dc(this);
1041 rect
.x
= dc
.LogicalToDeviceX( item
->m_x
-2 );
1042 rect
.y
= dc
.LogicalToDeviceY( item
->m_y
-2 );
1044 rect
.height
= dc
.GetCharHeight()+4;
1045 Refresh( TRUE
, &rect
);