]> git.saurik.com Git - wxWidgets.git/blame - src/generic/treectrl.cpp
added "access" parameter to wxFile::Create and Open. The default value is
[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;
357 m_dc = NULL;
358 m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
e2414cbe
RR
359 m_imageList = NULL;
360 m_smallImageList = NULL;
c801d85f
KB
361};
362
debe6624 363wxTreeCtrl::wxTreeCtrl(wxWindow *parent, wxWindowID id,
4c681997 364 const wxPoint& pos, const wxSize& size,
74bedbeb 365 long style, const wxString& name )
c801d85f
KB
366{
367 m_current = NULL;
368 m_anchor = NULL;
369 m_hasFocus = FALSE;
370 m_xScroll = 0;
371 m_yScroll = 0;
372 m_lastId = 0;
373 m_lineHeight = 10;
374 m_indent = 15;
375 m_isCreated = FALSE;
376 m_dc = NULL;
377 m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
e2414cbe
RR
378 m_imageList = NULL;
379 m_smallImageList = NULL;
c801d85f
KB
380 Create( parent, id, pos, size, style, name );
381};
382
74bedbeb 383wxTreeCtrl::~wxTreeCtrl()
c801d85f
KB
384{
385 if (m_dc) delete m_dc;
386};
387
debe6624 388bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id,
4c681997
RR
389 const wxPoint& pos, const wxSize& size,
390 long style, const wxString& name )
c801d85f
KB
391{
392 wxScrolledWindow::Create( parent, id, pos, size, style, name );
393 SetBackgroundColour( *wxWHITE );
394 m_dottedPen = wxPen( *wxBLACK, 0, 0 );
395 return TRUE;
396};
397
74bedbeb 398int wxTreeCtrl::GetCount() const
c801d85f
KB
399{
400 if (!m_anchor) return 0;
401 return m_anchor->NumberOfVisibleDescendents();
402};
403
74bedbeb
VZ
404long wxTreeCtrl::InsertItem( long parent, const wxString& label, int image,
405 int selImage, long WXUNUSED(insertAfter) )
c801d85f
KB
406{
407 wxGenericTreeItem *p = NULL;
408 if (parent == 0)
409 {
410 if (m_anchor) return -1;
411 }
412 else
413 {
414 p = FindItem( parent );
415 if (!p) return -1;
416 };
417 wxTreeItem item;
418 m_lastId++;
419 item.m_mask = wxTREE_MASK_HANDLE;
420 item.m_itemId = m_lastId;
421 if (!label.IsNull() || (label == ""))
422 {
423 item.m_text = label;
424 item.m_mask |= wxTREE_MASK_TEXT;
425 };
426 if (image >= 0)
427 {
428 item.m_image = image;
429 item.m_mask |= wxTREE_MASK_IMAGE;
430 };
431 if (selImage >= 0)
432 {
433 item.m_selectedImage = selImage;
434 item.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
435 };
29d87bba 436
c801d85f
KB
437 wxClientDC dc(this);
438 wxGenericTreeItem *new_child = new wxGenericTreeItem( p, item, &dc );
29d87bba 439 if (p)
c801d85f
KB
440 p->AddChild( new_child );
441 else
442 m_anchor = new_child;
29d87bba 443
c801d85f
KB
444 if (p)
445 {
446 CalculatePositions();
29d87bba 447
e2414cbe 448 if (!p->HasChildren()) p->m_hasChildren = TRUE;
389cdc7a 449
c801d85f
KB
450 int ch = 0;
451 GetClientSize( NULL, &ch );
29d87bba 452
c801d85f
KB
453 wxRectangle rect;
454 rect.x = 0; rect.y = 0;
455 rect.width = 10000; rect.height = ch;
29d87bba 456
c801d85f
KB
457 PrepareDC( dc );
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
KB
469 long doX = 0;
470 long doY = 0;
471 dc.GetDeviceOrigin( &doX, &doY );
472 rect.height = ch-rect.y-doY;
29d87bba 473
c801d85f 474 AdjustMyScrollbars();
29d87bba 475
c801d85f
KB
476 if (rect.height > 0) Refresh( FALSE, &rect);
477 }
478 else
479 {
480 AdjustMyScrollbars();
29d87bba 481
c801d85f
KB
482 Refresh();
483 };
29d87bba 484
c801d85f
KB
485 return m_lastId;
486};
487
74bedbeb 488long wxTreeCtrl::InsertItem( long parent, wxTreeItem &info, long WXUNUSED(insertAfter) )
c801d85f
KB
489{
490 int oldMask = info.m_mask;
491 wxGenericTreeItem *p = NULL;
492 if (parent == 0)
493 {
494 if (m_anchor) return -1;
495 }
496 else
497 {
498 p = FindItem( parent );
499 if (!p)
500 {
501 printf( "TreeItem not found.\n" );
502 return -1;
503 };
504 };
505 long ret = 0;
506 if ((info.m_mask & wxTREE_MASK_HANDLE) == 0)
507 {
508 m_lastId++;
509 info.m_itemId = m_lastId;
510 info.m_mask |= wxTREE_MASK_HANDLE;
511 ret = m_lastId;
512 }
513 else
514 {
515 ret = info.m_itemId;
516 };
29d87bba 517
c801d85f
KB
518 wxClientDC dc(this);
519 wxGenericTreeItem *new_child = new wxGenericTreeItem( p, info, &dc );
29d87bba 520 if (p)
c801d85f
KB
521 p->AddChild( new_child );
522 else
523 m_anchor = new_child;
29d87bba 524
c801d85f
KB
525 if (p)
526 {
527 CalculatePositions();
389cdc7a 528
e2414cbe 529 if (!p->HasChildren()) p->m_hasChildren = TRUE;
29d87bba 530
c801d85f
KB
531 int ch = 0;
532 GetClientSize( NULL, &ch );
29d87bba 533
c801d85f
KB
534 wxRectangle rect;
535 rect.x = 0; rect.y = 0;
536 rect.width = 10000; rect.height = ch;
29d87bba 537
c801d85f
KB
538 PrepareDC( dc );
539 if (p->m_children.Number() == 1)
540 {
541 rect.y = dc.LogicalToDeviceY( p->m_y );
542 }
543 else
544 {
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 );
548 };
29d87bba 549
c801d85f
KB
550 long doX = 0;
551 long doY = 0;
552 dc.GetDeviceOrigin( &doX, &doY );
553 rect.height = ch-rect.y-doY;
29d87bba 554
c801d85f 555 AdjustMyScrollbars();
29d87bba 556
c801d85f
KB
557 if (rect.height > 0) Refresh( FALSE, &rect);
558 }
559 else
560 {
561 AdjustMyScrollbars();
29d87bba 562
c801d85f
KB
563 Refresh();
564 };
29d87bba 565
c801d85f
KB
566 info.m_mask = oldMask;
567 return ret;
568};
569
74bedbeb 570bool wxTreeCtrl::ExpandItem( long item, int action )
c801d85f
KB
571{
572 wxGenericTreeItem *i = FindItem( item );
74bedbeb
VZ
573 if (!i)
574 return FALSE;
575
c801d85f
KB
576 switch (action)
577 {
578 case wxTREE_EXPAND_EXPAND:
579 {
580 i->SendExpand( this );
581 break;
74bedbeb
VZ
582 }
583
c801d85f
KB
584 case wxTREE_EXPAND_COLLAPSE_RESET:
585 case wxTREE_EXPAND_COLLAPSE:
586 {
587 wxNode *node = i->m_children.First();
588 while (node)
589 {
590 wxGenericTreeItem *child = (wxGenericTreeItem*)node->Data();
74bedbeb
VZ
591 if ( child->IsExpanded() )
592 ExpandItem( child->m_itemId, wxTREE_EXPAND_COLLAPSE );
593 node = node->Next();
c801d85f 594 };
29d87bba 595
e2414cbe 596 CalculatePositions();
389cdc7a 597
74bedbeb 598 i->SendCollapse( this );
c801d85f 599 break;
74bedbeb
VZ
600 }
601
c801d85f
KB
602 case wxTREE_EXPAND_TOGGLE:
603 {
74bedbeb 604 if ( i->IsExpanded() )
c801d85f 605 ExpandItem( item, wxTREE_EXPAND_COLLAPSE );
74bedbeb
VZ
606 else
607 ExpandItem( item, wxTREE_EXPAND_EXPAND );
608 return TRUE;
609 }
c801d85f 610 };
74bedbeb
VZ
611
612 int cw = 0;
613 int ch = 0;
614 GetClientSize( &cw, &ch );
615 wxRect rect;
616 rect.x = 0;
617 rect.width = cw;
618 wxClientDC dc(this);
619 PrepareDC(dc);
620 rect.y = dc.LogicalToDeviceY( i->m_y );
621
622 long doY = 0;
623 dc.GetDeviceOrigin( NULL, &doY );
624 rect.height = ch-rect.y-doY;
625 Refresh( TRUE, &rect );
626
627 AdjustMyScrollbars();
628
c801d85f
KB
629 return TRUE;
630};
631
a32dd690
VZ
632void wxTreeCtrl::DeleteItem( long item )
633{
634 wxGenericTreeItem *pItem = FindItem( item );
635 wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteItem: no such pItem." );
389cdc7a 636
a32dd690 637 pItem->m_parent->m_children.DeleteObject(pItem);
389cdc7a 638
4c681997
RR
639 Refresh();
640}
641
642void wxTreeCtrl::DeleteChildren( long item )
643{
644 wxGenericTreeItem *pItem = FindItem( item );
645 wxCHECK_RET( pItem != NULL, "wxTreeCtrl::DeleteChildren: no such pItem." );
389cdc7a 646
4c681997 647 pItem->m_children.Clear();
389cdc7a 648
a32dd690
VZ
649 Refresh();
650}
651
74bedbeb 652bool wxTreeCtrl::DeleteAllItems()
c801d85f
KB
653{
654 delete m_anchor;
655 m_anchor = NULL;
656 Refresh();
657 return TRUE;
658};
659
660bool wxTreeCtrl::GetItem( wxTreeItem &info ) const
661{
662 wxGenericTreeItem *i = FindItem( info.m_itemId );
663 if (!i) return FALSE;
664 i->GetItem( info );
665 return TRUE;
666};
667
74bedbeb 668long wxTreeCtrl::GetItemData( long item ) const
c801d85f
KB
669{
670 wxGenericTreeItem *i = FindItem( item );
671 if (!i) return 0;
672 return i->m_data;
673};
674
74bedbeb 675wxString wxTreeCtrl::GetItemText( long item ) const
c801d85f
KB
676{
677 wxGenericTreeItem *i = FindItem( item );
678 if (!i) return "";
679 return i->m_text;
680};
681
74bedbeb
VZ
682int wxTreeCtrl::GetItemImage(long item) const
683{
684 wxGenericTreeItem *i = FindItem( item );
685 return i == 0 ? -1 : i->GetImage();
686}
687
688long wxTreeCtrl::GetParent( long item ) const
c801d85f
KB
689{
690 wxGenericTreeItem *i = FindItem( item );
691 if (!i) return -1;
692 i = i->m_parent;
693 if (!i) return -1;
694 return i->m_parent->m_itemId;
695};
696
74bedbeb 697long wxTreeCtrl::GetRootItem() const
c801d85f
KB
698{
699 if (m_anchor) return m_anchor->m_itemId;
700 return -1;
701};
702
74bedbeb 703long wxTreeCtrl::GetSelection() const
c801d85f 704{
389cdc7a 705 return m_current ? m_current->GetItemId() : -1;
c801d85f
KB
706};
707
389cdc7a 708bool wxTreeCtrl::SelectItem(long itemId)
c801d85f 709{
389cdc7a
VZ
710 wxGenericTreeItem *pItem = FindItem(itemId);
711 if ( !pItem ) {
712 wxLogDebug("Can't select an item %d which doesn't exist.", itemId);
713
714 return FALSE;
715 }
716
717 SelectItem(pItem, FALSE /* no events */);
718
719 return TRUE;
c801d85f
KB
720};
721
389cdc7a
VZ
722void wxTreeCtrl::SelectItem(wxGenericTreeItem *item, bool bDoEvents)
723{
724 if (m_current != item)
725 {
726 if (m_current)
727 {
728 m_current->SetHilight( FALSE );
729 RefreshLine( m_current );
730 };
731 m_current = item;
732 m_current->SetHilight( TRUE );
733 RefreshLine( m_current );
734
735 if ( bDoEvents )
736 m_current->SendSelected( this );
737 }
738}
739
74bedbeb 740bool wxTreeCtrl::ItemHasChildren( long item ) const
c801d85f
KB
741{
742 wxGenericTreeItem *i = FindItem( item );
743 if (!i) return FALSE;
744 return i->m_hasChildren;
745};
746
74bedbeb 747void wxTreeCtrl::SetIndent( int indent )
c801d85f
KB
748{
749 m_indent = indent;
750 Refresh();
751};
752
74bedbeb 753int wxTreeCtrl::GetIndent() const
c801d85f
KB
754{
755 return m_indent;
756};
757
758bool wxTreeCtrl::SetItem( wxTreeItem &info )
759{
760 wxGenericTreeItem *i = FindItem( info.m_itemId );
761 if (!i) return FALSE;
762 wxClientDC dc(this);
763 i->SetItem( info, &dc );
74bedbeb 764 Refresh();
c801d85f
KB
765 return TRUE;
766};
767
74bedbeb 768bool wxTreeCtrl::SetItemData( long item, long data )
c801d85f
KB
769{
770 wxGenericTreeItem *i = FindItem( item );
771 if (!i) return FALSE;
772 i->m_data = data;
773 return TRUE;
774};
775
74bedbeb 776bool wxTreeCtrl::SetItemText( long item, const wxString &text )
c801d85f
KB
777{
778 wxGenericTreeItem *i = FindItem( item );
779 if (!i) return FALSE;
780 wxClientDC dc(this);
781 i->SetText( text, &dc );
782 return TRUE;
783};
784
74bedbeb
VZ
785void wxTreeCtrl::SetItemImage(long item, int image, int imageSel) const
786{
787 wxGenericTreeItem *i = FindItem( item );
788 if ( i != 0 ) {
789 i->SetImage(image);
790 i->SetSelectedImage(imageSel);
791 }
792}
793
c801d85f
KB
794long wxTreeCtrl::HitTest( const wxPoint& point, int &flags )
795{
796 flags = 0;
797 if (!m_anchor) return -1;
798 return m_anchor->HitTest( point, flags );
799};
800
e2414cbe
RR
801wxImageList *wxTreeCtrl::GetImageList( int which ) const
802{
803 if (which == wxIMAGE_LIST_NORMAL) return m_imageList;
804 return m_smallImageList;
805};
806
807void wxTreeCtrl::SetImageList( wxImageList *imageList, int which )
808{
809 if (which == wxIMAGE_LIST_NORMAL)
810 {
811 if (m_imageList) delete m_imageList;
812 m_imageList = imageList;
813 }
814 else
815 {
816 if (m_smallImageList) delete m_smallImageList;
817 m_smallImageList = imageList;
818 };
819};
820
74bedbeb 821void wxTreeCtrl::AdjustMyScrollbars()
c801d85f
KB
822{
823 if (m_anchor)
824 {
825 int x = 0;
826 int y = 0;
827 m_anchor->GetSize( x, y );
828 y += 2*m_lineHeight;
829 int x_pos = GetScrollPos( wxHORIZONTAL );
830 int y_pos = GetScrollPos( wxVERTICAL );
831 SetScrollbars( 10, 10, x/10, y/10, x_pos, y_pos );
832 }
833 else
834 {
835 SetScrollbars( 0, 0, 0, 0 );
836 };
837};
838
839void wxTreeCtrl::PaintLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y )
840{
4c681997 841 int horizX = level*m_indent;
389cdc7a 842
4c681997
RR
843 item->m_x = horizX+33;
844 item->m_y = y-m_lineHeight/3;
845 item->m_height = m_lineHeight;
389cdc7a 846
4c681997
RR
847 item->SetCross( horizX+15, y );
848
c801d85f 849 int oldY = y;
389cdc7a 850
4c681997 851 if (IsExposed( 0, item->m_y-2, 10000, m_lineHeight+4 ))
c801d85f 852 {
4c681997
RR
853 int startX = horizX;
854 int endX = horizX + 10;
29d87bba 855
4c681997 856 if (!item->HasChildren()) endX += 20;
389cdc7a 857 dc.DrawLine( startX, y, endX, y );
29d87bba 858
4c681997 859 if (item->HasChildren())
c801d85f
KB
860 {
861 dc.DrawLine( horizX+20, y, horizX+30, y );
862 dc.SetPen( *wxGREY_PEN );
863 dc.DrawRectangle( horizX+10, y-4, 11, 9 );
864 dc.SetPen( *wxBLACK_PEN );
4c681997
RR
865 dc.DrawLine( horizX+13, y, horizX+18, y );
866 if (item->HasPlus())
867 dc.DrawLine( horizX+15, y-2, horizX+15, y+3 );
c801d85f 868 };
c801d85f 869
4c681997 870 if (item->HasHilight())
c801d85f 871 {
29d87bba 872 dc.SetTextForeground( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
29d87bba 873 dc.SetBrush( *m_hilightBrush );
29d87bba 874 long tw, th;
4c681997 875 dc.GetTextExtent( item->m_text, &tw, &th );
e2414cbe 876 if (m_hasFocus)
389cdc7a 877 {
e2414cbe
RR
878 dc.SetPen( *wxBLACK_PEN );
879 dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 );
389cdc7a
VZ
880 }
881 else
882 {
883 dc.SetPen( *wxTRANSPARENT_PEN );
e2414cbe 884 dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 );
389cdc7a 885 }
4c681997 886 dc.DrawText( item->m_text, item->m_x, item->m_y );
29d87bba 887
29d87bba 888 dc.SetPen( *wxBLACK_PEN );
29d87bba 889 dc.SetTextForeground( *wxBLACK );
389cdc7a 890 dc.SetBrush( *wxWHITE_BRUSH );
29d87bba
VZ
891 }
892 else
4c681997 893 {
389cdc7a 894 dc.SetPen( *wxTRANSPARENT_PEN );
4c681997
RR
895 long tw, th;
896 dc.GetTextExtent( item->m_text, &tw, &th );
897 dc.DrawRectangle( item->m_x-2, item->m_y-2, tw+4, th+4 );
898 dc.DrawText( item->m_text, item->m_x, item->m_y );
899 dc.SetPen( *wxBLACK_PEN );
900 };
901 };
902
903 if (item->NumberOfVisibleChildren() == 0) return;
e2414cbe 904
389cdc7a
VZ
905 int semiOldY = y;
906
4c681997
RR
907 wxNode *node = item->m_children.First();
908 while (node)
909 {
910 wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data();
29d87bba 911
c801d85f 912 y += m_lineHeight;
e2414cbe 913 semiOldY = y;
389cdc7a 914
4c681997 915 PaintLevel( child, dc, level+1, y );
389cdc7a 916
c801d85f
KB
917 node = node->Next();
918 };
4c681997 919
e2414cbe 920 dc.DrawLine( horizX+15, oldY+5, horizX+15, semiOldY );
4c681997 921}
c801d85f
KB
922
923void wxTreeCtrl::OnPaint( const wxPaintEvent &WXUNUSED(event) )
924{
925 if (!m_anchor) return;
926
927 if (!m_dc)
29d87bba 928 {
c801d85f
KB
929 m_dc = new wxPaintDC(this);
930 PrepareDC( *m_dc );
931 };
29d87bba 932
c801d85f 933 m_dc->SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
29d87bba 934
c801d85f
KB
935 m_dc->SetPen( m_dottedPen );
936 m_lineHeight = (int)(m_dc->GetCharHeight() + 4);
29d87bba 937
c801d85f
KB
938 int y = m_lineHeight / 2 + 2;
939 PaintLevel( m_anchor, *m_dc, 0, y );
940};
941
942void wxTreeCtrl::OnSetFocus( const wxFocusEvent &WXUNUSED(event) )
943{
944 m_hasFocus = TRUE;
945 if (m_current) RefreshLine( m_current );
946};
947
948void wxTreeCtrl::OnKillFocus( const wxFocusEvent &WXUNUSED(event) )
949{
950 m_hasFocus = FALSE;
951 if (m_current) RefreshLine( m_current );
952};
953
954void wxTreeCtrl::OnChar( wxKeyEvent &event )
955{
956 event.Skip();
957};
958
959void wxTreeCtrl::OnMouse( const wxMouseEvent &event )
960{
961 if (!event.LeftDown() &&
962 !event.LeftDClick()) return;
29d87bba 963
c801d85f
KB
964 wxClientDC dc(this);
965 PrepareDC(dc);
966 long x = dc.DeviceToLogicalX( (long)event.GetX() );
967 long y = dc.DeviceToLogicalY( (long)event.GetY() );
29d87bba 968
c801d85f
KB
969 int flag = 0;
970 long id = HitTest( wxPoint(x,y), flag );
29d87bba
VZ
971 if (id == -1)
972 return;
c801d85f 973 wxGenericTreeItem *item = FindItem( id );
29d87bba 974
c801d85f
KB
975 if (!item) return;
976 if ((flag != wxTREE_HITTEST_ONITEMBUTTON) &&
977 (flag != wxTREE_HITTEST_ONITEMLABEL)) return;
29d87bba 978
389cdc7a 979 SelectItem(item);
29d87bba
VZ
980
981 if (event.LeftDClick())
982 m_current->SendKeyDown( this );
983
c801d85f
KB
984 if (flag == wxTREE_HITTEST_ONITEMBUTTON)
985 {
986 ExpandItem( item->m_itemId, wxTREE_EXPAND_TOGGLE );
987 return;
988 };
989};
990
991void wxTreeCtrl::CalculateLevel( wxGenericTreeItem *item, wxPaintDC &dc, int level, int &y )
992{
4c681997 993 int horizX = level*m_indent;
389cdc7a 994
4c681997
RR
995 item->m_x = horizX+33;
996 item->m_y = y-m_lineHeight/3-2;
997 item->m_height = m_lineHeight;
998
999 if (item->NumberOfVisibleChildren() == 0) return;
389cdc7a 1000
c801d85f
KB
1001 wxNode *node = item->m_children.First();
1002 while (node)
1003 {
1004 wxGenericTreeItem *child = (wxGenericTreeItem *)node->Data();
389cdc7a 1005
c801d85f 1006 y += m_lineHeight;
4c681997 1007 CalculateLevel( child, dc, level+1, y );
29d87bba 1008
c801d85f
KB
1009 node = node->Next();
1010 };
1011};
1012
74bedbeb 1013void wxTreeCtrl::CalculatePositions()
c801d85f 1014{
29d87bba
VZ
1015 if (!m_anchor)
1016 return;
1017
c801d85f
KB
1018 wxClientDC dc(this);
1019 PrepareDC( dc );
29d87bba 1020
c801d85f 1021 dc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_SYSTEM_FONT ) );
29d87bba 1022
c801d85f
KB
1023 dc.SetPen( m_dottedPen );
1024 m_lineHeight = (int)(dc.GetCharHeight() + 4);
29d87bba 1025
c801d85f
KB
1026 int y = m_lineHeight / 2 + 2;
1027 CalculateLevel( m_anchor, dc, 0, y );
1028};
1029
1030wxGenericTreeItem *wxTreeCtrl::FindItem( long itemId ) const
1031{
1032 if (!m_anchor) return NULL;
1033 return m_anchor->FindItem( itemId );
1034};
1035
1036void wxTreeCtrl::RefreshLine( wxGenericTreeItem *item )
1037{
1038 if (!item) return;
1039 wxClientDC dc(this);
1040 PrepareDC( dc );
1041 wxRect rect;
1042 rect.x = dc.LogicalToDeviceX( item->m_x-2 );
1043 rect.y = dc.LogicalToDeviceY( item->m_y-2 );
1044 rect.width = 1000;
1045 rect.height = dc.GetCharHeight()+4;
1046 Refresh( TRUE, &rect );
1047};
1048
1049
1050