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