aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp1101
1 files changed, 1101 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp
new file mode 100644
index 0000000..779b8cd
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUITreeView.cpp
@@ -0,0 +1,1101 @@
1// This file is part of the "Irrlicht Engine".
2// written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de
3// expaned by burningwater
4
5#include "CGUITreeView.h"
6
7#ifdef _IRR_COMPILE_WITH_GUI_
8
9#include "IGUISkin.h"
10#include "IGUIEnvironment.h"
11#include "IVideoDriver.h"
12#include "IGUIFont.h"
13#include "CGUIScrollBar.h"
14#include "os.h"
15
16namespace irr
17{
18namespace gui
19{
20
21CGUITreeViewNode::CGUITreeViewNode( CGUITreeView* owner, CGUITreeViewNode* parent )
22 : Owner(owner), Parent(parent), ImageIndex(-1), SelectedImageIndex(-1),
23 Data(0), Data2(0), Expanded(false)
24{
25#ifdef _DEBUG
26 setDebugName( "CGUITreeView" );
27#endif
28}
29
30CGUITreeViewNode::~CGUITreeViewNode()
31{
32 if( Owner && this == Owner->getSelected() )
33 {
34 setSelected( false );
35 }
36
37 clearChildren();
38
39 if( Data2 )
40 {
41 Data2->drop();
42 }
43}
44
45IGUITreeView* CGUITreeViewNode::getOwner() const
46{
47 return Owner;
48}
49
50IGUITreeViewNode* CGUITreeViewNode::getParent() const
51{
52 return Parent;
53}
54
55void CGUITreeViewNode::setText( const wchar_t* text )
56{
57 Text = text;
58}
59
60void CGUITreeViewNode::setIcon( const wchar_t* icon )
61{
62 Icon = icon;
63}
64
65void CGUITreeViewNode::clearChildren()
66{
67 core::list<CGUITreeViewNode*>::Iterator it;
68
69 for( it = Children.begin(); it != Children.end(); it++ )
70 {
71 ( *it )->drop();
72 }
73 Children.clear();
74}
75
76IGUITreeViewNode* CGUITreeViewNode::addChildBack(
77 const wchar_t* text,
78 const wchar_t* icon /*= 0*/,
79 s32 imageIndex /*= -1*/,
80 s32 selectedImageIndex /*= -1*/,
81 void* data /*= 0*/,
82 IReferenceCounted* data2 /*= 0*/ )
83{
84 CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
85
86 Children.push_back( newChild );
87 newChild->Text = text;
88 newChild->Icon = icon;
89 newChild->ImageIndex = imageIndex;
90 newChild->SelectedImageIndex = selectedImageIndex;
91 newChild->Data = data;
92 newChild->Data2 = data2;
93 if( data2 )
94 {
95 data2->grab();
96 }
97 return newChild;
98}
99
100IGUITreeViewNode* CGUITreeViewNode::addChildFront(
101 const wchar_t* text,
102 const wchar_t* icon /*= 0*/,
103 s32 imageIndex /*= -1*/,
104 s32 selectedImageIndex /*= -1*/,
105 void* data /*= 0*/,
106 IReferenceCounted* data2 /*= 0*/ )
107{
108 CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
109
110 Children.push_front( newChild );
111 newChild->Text = text;
112 newChild->Icon = icon;
113 newChild->ImageIndex = imageIndex;
114 newChild->SelectedImageIndex = selectedImageIndex;
115 newChild->Data = data;
116 newChild->Data2 = data2;
117 if( data2 )
118 {
119 data2->grab();
120 }
121 return newChild;
122}
123
124IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
125 IGUITreeViewNode* other,
126 const wchar_t* text,
127 const wchar_t* icon /*= 0*/,
128 s32 imageIndex /*= -1*/,
129 s32 selectedImageIndex /*= -1*/,
130 void* data /*= 0*/,
131 IReferenceCounted* data2/* = 0*/ )
132{
133 core::list<CGUITreeViewNode*>::Iterator itOther;
134 CGUITreeViewNode* newChild = 0;
135
136 for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
137 {
138 if( other == *itOther )
139 {
140 newChild = new CGUITreeViewNode( Owner, this );
141 newChild->Text = text;
142 newChild->Icon = icon;
143 newChild->ImageIndex = imageIndex;
144 newChild->SelectedImageIndex = selectedImageIndex;
145 newChild->Data = data;
146 newChild->Data2 = data2;
147 if( data2 )
148 {
149 data2->grab();
150 }
151 Children.insert_after( itOther, newChild );
152 break;
153 }
154 }
155 return newChild;
156}
157
158IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
159 IGUITreeViewNode* other,
160 const wchar_t* text,
161 const wchar_t* icon /*= 0*/,
162 s32 imageIndex /*= -1*/,
163 s32 selectedImageIndex /*= -1*/,
164 void* data /*= 0*/,
165 IReferenceCounted* data2/* = 0*/ )
166{
167 core::list<CGUITreeViewNode*>::Iterator itOther;
168 CGUITreeViewNode* newChild = 0;
169
170 for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
171 {
172 if( other == *itOther )
173 {
174 newChild = new CGUITreeViewNode( Owner, this );
175 newChild->Text = text;
176 newChild->Icon = icon;
177 newChild->ImageIndex = imageIndex;
178 newChild->SelectedImageIndex = selectedImageIndex;
179 newChild->Data = data;
180 newChild->Data2 = data2;
181 if( data2 )
182 {
183 data2->grab();
184 }
185 Children.insert_before( itOther, newChild );
186 break;
187 }
188 }
189 return newChild;
190}
191
192IGUITreeViewNode* CGUITreeViewNode::getFirstChild() const
193{
194 if( Children.empty() )
195 {
196 return 0;
197 }
198 else
199 {
200 return *( Children.begin() );
201 }
202}
203
204IGUITreeViewNode* CGUITreeViewNode::getLastChild() const
205{
206 if( Children.empty() )
207 {
208 return 0;
209 }
210 else
211 {
212 return *( Children.getLast() );
213 }
214}
215
216IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const
217{
218 core::list<CGUITreeViewNode*>::Iterator itThis;
219 core::list<CGUITreeViewNode*>::Iterator itOther;
220 CGUITreeViewNode* other = 0;
221
222 if( Parent )
223 {
224 for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
225 {
226 if( this == *itThis )
227 {
228 if( itThis != Parent->Children.begin() )
229 {
230 other = *itOther;
231 }
232 break;
233 }
234 itOther = itThis;
235 }
236 }
237 return other;
238}
239
240IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const
241{
242 core::list<CGUITreeViewNode*>::Iterator itThis;
243 CGUITreeViewNode* other = 0;
244
245 if( Parent )
246 {
247 for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
248 {
249 if( this == *itThis )
250 {
251 if( itThis != Parent->Children.getLast() )
252 {
253 other = *( ++itThis );
254 }
255 break;
256 }
257 }
258 }
259 return other;
260}
261
262IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
263{
264 IGUITreeViewNode* next = 0;
265 IGUITreeViewNode* node = 0;
266
267 node = const_cast<CGUITreeViewNode*>( this );
268
269 if( node->getExpanded() && node->hasChildren() )
270 {
271 next = node->getFirstChild();
272 }
273 else
274 {
275 next = node->getNextSibling();
276 }
277 while( !next && node->getParent() )
278 {
279 next = node->getParent()->getNextSibling();
280 if( !next )
281 {
282 node = node->getParent();
283 }
284 }
285
286 return next;
287}
288
289bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* child )
290{
291 core::list<CGUITreeViewNode*>::Iterator itChild;
292 bool deleted = false;
293
294 for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
295 {
296 if( child == *itChild )
297 {
298 child->drop();
299 Children.erase( itChild );
300 deleted = true;
301 break;
302 }
303 }
304 return deleted;
305}
306
307bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* child )
308{
309 core::list<CGUITreeViewNode*>::Iterator itChild;
310 core::list<CGUITreeViewNode*>::Iterator itOther;
311 CGUITreeViewNode* nodeTmp;
312 bool moved = false;
313
314 for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
315 {
316 if( child == *itChild )
317 {
318 if( itChild != Children.begin() )
319 {
320 nodeTmp = *itChild;
321 *itChild = *itOther;
322 *itOther = nodeTmp;
323 moved = true;
324 }
325 break;
326 }
327 itOther = itChild;
328 }
329 return moved;
330}
331
332bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* child )
333{
334 core::list<CGUITreeViewNode*>::Iterator itChild;
335 core::list<CGUITreeViewNode*>::Iterator itOther;
336 CGUITreeViewNode* nodeTmp;
337 bool moved = false;
338
339 for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
340 {
341 if( child == *itChild )
342 {
343 if( itChild != Children.getLast() )
344 {
345 itOther = itChild;
346 ++itOther;
347 nodeTmp = *itChild;
348 *itChild = *itOther;
349 *itOther = nodeTmp;
350 moved = true;
351 }
352 break;
353 }
354 }
355 return moved;
356}
357
358void CGUITreeViewNode::setExpanded( bool expanded )
359{
360 Expanded = expanded;
361}
362
363void CGUITreeViewNode::setSelected( bool selected )
364{
365 if( Owner )
366 {
367 if( selected )
368 {
369 Owner->Selected = this;
370 }
371 else
372 {
373 if( Owner->Selected == this )
374 {
375 Owner->Selected = 0;
376 }
377 }
378 }
379}
380
381bool CGUITreeViewNode::getSelected() const
382{
383 if( Owner )
384 {
385 return Owner->Selected == (IGUITreeViewNode*)this;
386 }
387 else
388 {
389 return false;
390 }
391}
392
393bool CGUITreeViewNode::isRoot() const
394{
395 return ( Owner && ( this == Owner->Root ) );
396}
397
398s32 CGUITreeViewNode::getLevel() const
399{
400 if( Parent )
401 {
402 return Parent->getLevel() + 1;
403 }
404 else
405 {
406 return 0;
407 }
408}
409
410bool CGUITreeViewNode::isVisible() const
411{
412 if( Parent )
413 {
414 return Parent->getExpanded() && Parent->isVisible();
415 }
416 else
417 {
418 return true;
419 }
420}
421
422
423//! constructor
424CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
425 s32 id, core::rect<s32> rectangle, bool clip,
426 bool drawBack,bool scrollBarVertical, bool scrollBarHorizontal)
427 : IGUITreeView( environment, parent, id, rectangle ),
428 Root(0), Selected(0),
429 ItemHeight( 0 ),
430 IndentWidth( 0 ),
431 TotalItemHeight( 0 ),
432 TotalItemWidth ( 0 ),
433 Font( 0 ),
434 IconFont( 0 ),
435 ScrollBarH( 0 ),
436 ScrollBarV( 0 ),
437 ImageList( 0 ),
438 LastEventNode( 0 ),
439 LinesVisible( true ),
440 Selecting( false ),
441 Clip( clip ),
442 DrawBack( drawBack ),
443 ImageLeftOfIcon( true )
444{
445#ifdef _DEBUG
446 setDebugName( "CGUITreeView" );
447#endif
448
449 IGUISkin* skin = Environment->getSkin();
450 s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE );
451
452 if ( scrollBarVertical )
453 {
454 ScrollBarV = new CGUIScrollBar( false, Environment, this, 0,
455 core::rect<s32>( RelativeRect.getWidth() - s,
456 0,
457 RelativeRect.getWidth(),
458 RelativeRect.getHeight() - (scrollBarHorizontal ? s : 0 )
459 ),
460 !clip );
461 ScrollBarV->drop();
462
463 ScrollBarV->setSubElement(true);
464 ScrollBarV->setPos( 0 );
465 ScrollBarV->grab();
466 }
467
468 if ( scrollBarHorizontal )
469 {
470 ScrollBarH = new CGUIScrollBar( true, Environment, this, 1,
471 core::rect<s32>( 0, RelativeRect.getHeight() - s, RelativeRect.getWidth() - s, RelativeRect.getHeight() ),
472 !clip );
473 ScrollBarH->drop();
474
475 ScrollBarH->setSubElement(true);
476 ScrollBarH->setPos( 0 );
477 ScrollBarH->grab();
478 }
479
480 Root = new CGUITreeViewNode( this, 0 );
481 Root->Expanded = true;
482
483 recalculateItemHeight();
484}
485
486
487//! destructor
488CGUITreeView::~CGUITreeView()
489{
490 if( ScrollBarV )
491 {
492 ScrollBarV->drop();
493 }
494
495 if( ScrollBarH )
496 {
497 ScrollBarH->drop();
498 }
499
500 if( Font )
501 {
502 Font->drop();
503 }
504
505 if( IconFont )
506 {
507 IconFont->drop();
508 }
509
510 if( ImageList )
511 {
512 ImageList->drop();
513 }
514
515 if( Root )
516 {
517 Root->drop();
518 }
519}
520
521void CGUITreeView::recalculateItemHeight()
522{
523 IGUISkin* skin = Environment->getSkin();
524 IGUITreeViewNode* node;
525
526 if( Font != skin->getFont() )
527 {
528 if( Font )
529 {
530 Font->drop();
531 }
532
533 Font = skin->getFont();
534 ItemHeight = 0;
535
536 if( Font )
537 {
538 ItemHeight = Font->getDimension( L"A" ).Height + 4;
539 Font->grab();
540 }
541
542 if( IconFont )
543 {
544 s32 height = IconFont->getDimension( L" " ).Height;
545 if( height > ItemHeight )
546 {
547 ItemHeight = height;
548 }
549 }
550 if( ImageList )
551 {
552 if( ImageList->getImageSize().Height + 1 > ItemHeight )
553 {
554 ItemHeight = ImageList->getImageSize().Height + 1;
555 }
556 }
557 }
558
559 IndentWidth = ItemHeight;
560 if( IndentWidth < 9 )
561 {
562 IndentWidth = 9;
563 }
564 else if( IndentWidth > 15 )
565 {
566 IndentWidth = 15;
567 }
568 else
569 {
570 if( ( ( IndentWidth >> 1 ) << 1 ) - IndentWidth == 0 )
571 {
572 --IndentWidth;
573 }
574 }
575
576 TotalItemHeight = 0;
577 TotalItemWidth = AbsoluteRect.getWidth() * 2;
578 node = Root->getFirstChild();
579 while( node )
580 {
581 TotalItemHeight += ItemHeight;
582 node = node->getNextVisible();
583 }
584
585 if ( ScrollBarV )
586 ScrollBarV->setMax( core::max_(0,TotalItemHeight - AbsoluteRect.getHeight()) );
587
588 if ( ScrollBarH )
589 ScrollBarH->setMax( core::max_(0, TotalItemWidth - AbsoluteRect.getWidth()) );
590
591}
592
593//! called if an event happened.
594bool CGUITreeView::OnEvent( const SEvent &event )
595{
596 if ( isEnabled() )
597 {
598 switch( event.EventType )
599 {
600 case EET_GUI_EVENT:
601 switch( event.GUIEvent.EventType )
602 {
603 case gui::EGET_SCROLL_BAR_CHANGED:
604 if( event.GUIEvent.Caller == ScrollBarV || event.GUIEvent.Caller == ScrollBarH )
605 {
606 //s32 pos = ( ( gui::IGUIScrollBar* )event.GUIEvent.Caller )->getPos();
607 return true;
608 }
609 break;
610 case gui::EGET_ELEMENT_FOCUS_LOST:
611 {
612 Selecting = false;
613 return false;
614 }
615 break;
616 default:
617 break;
618 }
619 break;
620 case EET_MOUSE_INPUT_EVENT:
621 {
622 core::position2d<s32> p( event.MouseInput.X, event.MouseInput.Y );
623
624 switch( event.MouseInput.Event )
625 {
626 case EMIE_MOUSE_WHEEL:
627 if ( ScrollBarV )
628 ScrollBarV->setPos( ScrollBarV->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1) * -10 );
629 return true;
630 break;
631
632 case EMIE_LMOUSE_PRESSED_DOWN:
633
634 if (Environment->hasFocus(this) && !AbsoluteClippingRect.isPointInside(p) )
635 {
636 Environment->removeFocus(this);
637 return false;
638 }
639
640 if( Environment->hasFocus( this ) &&
641 ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) ||
642 ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) )
643 )
644 )
645 {
646 return true;
647 }
648
649 Selecting = true;
650 Environment->setFocus( this );
651 return true;
652 break;
653
654 case EMIE_LMOUSE_LEFT_UP:
655 if( Environment->hasFocus( this ) &&
656 ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) ||
657 ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) )
658 )
659 )
660 {
661 return true;
662 }
663
664 Selecting = false;
665 Environment->removeFocus( this );
666 mouseAction( event.MouseInput.X, event.MouseInput.Y );
667 return true;
668 break;
669
670 case EMIE_MOUSE_MOVED:
671 if( Selecting )
672 {
673 if( getAbsolutePosition().isPointInside( p ) )
674 {
675 mouseAction( event.MouseInput.X, event.MouseInput.Y, true );
676 return true;
677 }
678 }
679 break;
680 default:
681 break;
682 }
683 }
684 break;
685 default:
686 break;
687 }
688 }
689
690 return Parent ? Parent->OnEvent( event ) : false;
691}
692
693/*!
694*/
695void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ )
696{
697 IGUITreeViewNode* oldSelected = Selected;
698 IGUITreeViewNode* hitNode = 0;
699 s32 selIdx=-1;
700 s32 n;
701 IGUITreeViewNode* node;
702 SEvent event;
703
704 event.EventType = EET_GUI_EVENT;
705 event.GUIEvent.Caller = this;
706 event.GUIEvent.Element = 0;
707
708 xpos -= AbsoluteRect.UpperLeftCorner.X;
709 ypos -= AbsoluteRect.UpperLeftCorner.Y;
710
711 // find new selected item.
712 if( ItemHeight != 0 && ScrollBarV )
713 {
714 selIdx = ( ( ypos - 1 ) + ScrollBarV->getPos() ) / ItemHeight;
715 }
716
717 hitNode = 0;
718 node = Root->getFirstChild();
719 n = 0;
720 while( node )
721 {
722 if( selIdx == n )
723 {
724 hitNode = node;
725 break;
726 }
727 node = node->getNextVisible();
728 ++n;
729 }
730
731 if( hitNode && xpos > hitNode->getLevel() * IndentWidth )
732 {
733 Selected = hitNode;
734 }
735
736 if( hitNode && !onlyHover
737 && xpos < hitNode->getLevel() * IndentWidth
738 && xpos > ( hitNode->getLevel() - 1 ) * IndentWidth
739 && hitNode->hasChildren() )
740 {
741 hitNode->setExpanded( !hitNode->getExpanded() );
742
743 // post expand/collaps news
744 if( hitNode->getExpanded() )
745 {
746 event.GUIEvent.EventType = EGET_TREEVIEW_NODE_EXPAND;
747 }
748 else
749 {
750 event.GUIEvent.EventType = EGET_TREEVIEW_NODE_COLLAPS;
751 }
752 LastEventNode = hitNode;
753 Parent->OnEvent( event );
754 LastEventNode = 0;
755 }
756
757 if( Selected && !Selected->isVisible() )
758 {
759 Selected = 0;
760 }
761
762 // post selection news
763
764 if( Parent && !onlyHover && Selected != oldSelected )
765 {
766 if( oldSelected )
767 {
768 event.GUIEvent.EventType = EGET_TREEVIEW_NODE_DESELECT;
769 LastEventNode = oldSelected;
770 Parent->OnEvent( event );
771 LastEventNode = 0;
772 }
773 if( Selected )
774 {
775 event.GUIEvent.EventType = EGET_TREEVIEW_NODE_SELECT;
776 LastEventNode = Selected;
777 Parent->OnEvent( event );
778 LastEventNode = 0;
779 }
780 }
781}
782
783
784//! draws the element and its children
785void CGUITreeView::draw()
786{
787 if( !IsVisible )
788 {
789 return;
790 }
791
792 recalculateItemHeight(); // if the font changed
793
794 IGUISkin* skin = Environment->getSkin();
795 irr::video::IVideoDriver* driver = Environment->getVideoDriver();
796
797 core::rect<s32>* clipRect = 0;
798 if( Clip )
799 {
800 clipRect = &AbsoluteClippingRect;
801 }
802
803 // draw background
804 core::rect<s32> frameRect( AbsoluteRect );
805
806 if( DrawBack )
807 {
808 driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect,
809 clipRect );
810 }
811
812 // draw the border
813 frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1;
814 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect,
815 clipRect );
816
817 frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y;
818 frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1;
819 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect,
820 clipRect );
821
822 frameRect = AbsoluteRect;
823 frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1;
824 driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect,
825 clipRect );
826
827 frameRect = AbsoluteRect;
828 frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1;
829 frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y;
830 driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect,
831 clipRect );
832
833
834 // draw items
835
836 core::rect<s32> clientClip( AbsoluteRect );
837 clientClip.UpperLeftCorner.Y += 1;
838 clientClip.UpperLeftCorner.X += 1;
839 clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X;
840 clientClip.LowerRightCorner.Y -= 1;
841
842 if ( ScrollBarV )
843 clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE );
844 if ( ScrollBarH )
845 clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE );
846
847 if( clipRect )
848 {
849 clientClip.clipAgainst( *clipRect );
850 }
851
852 frameRect = AbsoluteRect;
853 frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE );
854 frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
855
856 if ( ScrollBarV )
857 {
858 frameRect.UpperLeftCorner.Y -= ScrollBarV->getPos();
859 frameRect.LowerRightCorner.Y -= ScrollBarV->getPos();
860 }
861
862 if ( ScrollBarH )
863 {
864 frameRect.UpperLeftCorner.X -= ScrollBarH->getPos();
865 frameRect.LowerRightCorner.X -= ScrollBarH->getPos();
866 }
867
868 IGUITreeViewNode* node = Root->getFirstChild();
869 while( node )
870 {
871 frameRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + 1 + node->getLevel() * IndentWidth;
872
873 if( frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y
874 && frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y )
875 {
876 if( node == Selected )
877 {
878 driver->draw2DRectangle( skin->getColor( EGDC_HIGH_LIGHT ), frameRect, &clientClip );
879 }
880
881 if( node->hasChildren() )
882 {
883 core::rect<s32> rc;
884 core::rect<s32> expanderRect;
885
886 expanderRect.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth + 2;
887 expanderRect.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() - ( IndentWidth - 4 ) ) >> 1 );
888 expanderRect.LowerRightCorner.X = expanderRect.UpperLeftCorner.X + IndentWidth - 4;
889 expanderRect.LowerRightCorner.Y = expanderRect.UpperLeftCorner.Y + IndentWidth - 4;
890
891 // box upper line
892 rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X;
893 rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y;
894 rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X;
895 rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
896 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
897 clipRect );
898
899 // box left line
900 rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X;
901 rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y;
902 rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
903 rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y;
904 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
905 clipRect );
906
907 // box right line
908 rc.UpperLeftCorner.X = expanderRect.LowerRightCorner.X - 1;
909 rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y;
910 rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
911 rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y;
912 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
913 clipRect );
914
915 // box bottom line
916 rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X;
917 rc.UpperLeftCorner.Y = expanderRect.LowerRightCorner.Y - 1;
918 rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X;
919 rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
920 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
921 clipRect );
922
923 // horizontal '-' line
924 rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + 2;
925 rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + ( expanderRect.getHeight() >> 1 );
926 rc.LowerRightCorner.X = rc.UpperLeftCorner.X + expanderRect.getWidth() - 4;
927 rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
928 driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc,
929 clipRect );
930
931 if( !node->getExpanded() )
932 {
933 // vertical '+' line
934 rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + ( expanderRect.getWidth() >> 1 );
935 rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + 2;
936 rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
937 rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + expanderRect.getHeight() - 4;
938 driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc,
939 clipRect );
940 }
941 }
942
943 core::rect<s32> textRect = frameRect;
944
945 if( Font )
946 {
947 EGUI_DEFAULT_COLOR textCol = EGDC_GRAY_TEXT;
948 if ( isEnabled() )
949 textCol = ( node == Selected ) ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT;
950
951 s32 iconWidth = 0;
952 for( s32 n = 0; n < 2; ++n )
953 {
954 s32 index = node->getImageIndex();
955 if( ( ImageList && index >= 0 )
956 && ( ( ImageLeftOfIcon && n == 0 )
957 || ( !ImageLeftOfIcon && n == 1 ) ) )
958 {
959 index = node->getSelectedImageIndex();
960 if( node != Selected || index < 0 )
961 {
962 index = node->getImageIndex();
963 }
964 ImageList->draw(
965 index,
966 core::position2d<s32>(
967 textRect.UpperLeftCorner.X,
968 textRect.UpperLeftCorner.Y + ( ( textRect.getHeight() - ImageList->getImageSize().Height ) >> 1 ) ),
969 &clientClip );
970 iconWidth += ImageList->getImageSize().Width + 3;
971 textRect.UpperLeftCorner.X += ImageList->getImageSize().Width + 3;
972 }
973 else if( ( IconFont && reinterpret_cast<CGUITreeViewNode*>( node )->Icon.size() )
974 && ( ( ImageLeftOfIcon && n == 1 )
975 || ( !ImageLeftOfIcon && n == 0 ) ) )
976 {
977 IconFont->draw( node->getIcon(), textRect, skin->getColor(textCol), false, true, &clientClip );
978 iconWidth += IconFont->getDimension( node->getIcon() ).Width + 3;
979 textRect.UpperLeftCorner.X += IconFont->getDimension( node->getIcon() ).Width + 3;
980 }
981 }
982
983 Font->draw( node->getText(), textRect, skin->getColor(textCol), false, true, &clientClip );
984
985 textRect.UpperLeftCorner.X -= iconWidth;
986 }
987
988 // draw the lines if neccessary
989 if( LinesVisible )
990 {
991 core::rect<s32> rc;
992
993 // horizontal line
994 rc.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth - ( IndentWidth >> 1 ) - 1;
995 rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() ) >> 1 );
996 if( node->hasChildren() )
997 {
998 rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - IndentWidth;
999 }
1000 else
1001 {
1002 rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - 2;
1003 }
1004 rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
1005 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
1006 clipRect );
1007
1008 if( node->getParent() != Root )
1009 {
1010 // vertical line
1011 if( node == node->getParent()->getFirstChild() )
1012 {
1013 rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( ( frameRect.getHeight() - IndentWidth ) >> 1 );
1014 }
1015 else
1016 {
1017 rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 );
1018 }
1019 rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
1020 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
1021 clipRect );
1022
1023 // the vertical lines of all parents
1024 IGUITreeViewNode* nodeTmp = node->getParent();
1025 rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 );
1026 for( s32 n = 0; n < node->getLevel() - 2; ++n )
1027 {
1028 rc.UpperLeftCorner.X -= IndentWidth;
1029 rc.LowerRightCorner.X -= IndentWidth;
1030 if( nodeTmp != nodeTmp->getParent()->getLastChild() )
1031 {
1032 driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
1033 clipRect );
1034 }
1035 nodeTmp = nodeTmp->getParent();
1036 }
1037 }
1038 }
1039 }
1040
1041 frameRect.UpperLeftCorner.Y += ItemHeight;
1042 frameRect.LowerRightCorner.Y += ItemHeight;
1043
1044 node = node->getNextVisible();
1045 }
1046
1047 IGUIElement::draw();
1048}
1049
1050//! Sets the font which should be used as icon font. This font is set to the Irrlicht engine
1051//! built-in-font by default. Icons can be displayed in front of every list item.
1052//! An icon is a string, displayed with the icon font. When using the build-in-font of the
1053//! Irrlicht engine as icon font, the icon strings defined in GUIIcons.h can be used.
1054void CGUITreeView::setIconFont( IGUIFont* font )
1055{
1056 s32 height;
1057
1058 if ( font )
1059 font->grab();
1060 if ( IconFont )
1061 {
1062 IconFont->drop();
1063 }
1064
1065 IconFont = font;
1066 if( IconFont )
1067 {
1068 height = IconFont->getDimension( L" " ).Height;
1069 if( height > ItemHeight )
1070 {
1071 ItemHeight = height;
1072 }
1073 }
1074}
1075
1076//! Sets the image list which should be used for the image and selected image of every node.
1077//! The default is 0 (no images).
1078void CGUITreeView::setImageList( IGUIImageList* imageList )
1079{
1080 if (imageList )
1081 imageList->grab();
1082 if( ImageList )
1083 {
1084 ImageList->drop();
1085 }
1086
1087 ImageList = imageList;
1088 if( ImageList )
1089 {
1090 if( ImageList->getImageSize().Height + 1 > ItemHeight )
1091 {
1092 ItemHeight = ImageList->getImageSize().Height + 1;
1093 }
1094 }
1095}
1096
1097} // end namespace gui
1098} // end namespace irr
1099
1100
1101#endif // _IRR_COMPILE_WITH_GUI_