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