1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102 |
- // This file is part of the "Irrlicht Engine".
- // written by Reinhard Ostermeier, reinhard@nospam.r-ostermeier.de
- // expaned by burningwater
- #include "CGUITreeView.h"
- #ifdef _IRR_COMPILE_WITH_GUI_
- #include "IGUISkin.h"
- #include "IGUIEnvironment.h"
- #include "IVideoDriver.h"
- #include "IGUIFont.h"
- #include "CGUIScrollBar.h"
- #include "os.h"
- namespace irr
- {
- namespace gui
- {
- CGUITreeViewNode::CGUITreeViewNode( CGUITreeView* owner, CGUITreeViewNode* parent )
- : Owner(owner), Parent(parent), ImageIndex(-1), SelectedImageIndex(-1),
- Data(0), Data2(0), Expanded(false)
- {
- #ifdef _DEBUG
- setDebugName( "CGUITreeView" );
- #endif
- }
- CGUITreeViewNode::~CGUITreeViewNode()
- {
- if( Owner && this == Owner->getSelected() )
- {
- setSelected( false );
- }
- clearChildren();
- if( Data2 )
- {
- Data2->drop();
- }
- }
- IGUITreeView* CGUITreeViewNode::getOwner() const
- {
- return Owner;
- }
- IGUITreeViewNode* CGUITreeViewNode::getParent() const
- {
- return Parent;
- }
- void CGUITreeViewNode::setText( const wchar_t* text )
- {
- Text = text;
- }
- void CGUITreeViewNode::setIcon( const wchar_t* icon )
- {
- Icon = icon;
- }
- void CGUITreeViewNode::clearChildren()
- {
- core::list<CGUITreeViewNode*>::Iterator it;
- for( it = Children.begin(); it != Children.end(); it++ )
- {
- ( *it )->drop();
- }
- Children.clear();
- }
- IGUITreeViewNode* CGUITreeViewNode::addChildBack(
- const wchar_t* text,
- const wchar_t* icon /*= 0*/,
- s32 imageIndex /*= -1*/,
- s32 selectedImageIndex /*= -1*/,
- void* data /*= 0*/,
- IReferenceCounted* data2 /*= 0*/ )
- {
- CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
- Children.push_back( newChild );
- newChild->Text = text;
- newChild->Icon = icon;
- newChild->ImageIndex = imageIndex;
- newChild->SelectedImageIndex = selectedImageIndex;
- newChild->Data = data;
- newChild->Data2 = data2;
- if( data2 )
- {
- data2->grab();
- }
- return newChild;
- }
- IGUITreeViewNode* CGUITreeViewNode::addChildFront(
- const wchar_t* text,
- const wchar_t* icon /*= 0*/,
- s32 imageIndex /*= -1*/,
- s32 selectedImageIndex /*= -1*/,
- void* data /*= 0*/,
- IReferenceCounted* data2 /*= 0*/ )
- {
- CGUITreeViewNode* newChild = new CGUITreeViewNode( Owner, this );
- Children.push_front( newChild );
- newChild->Text = text;
- newChild->Icon = icon;
- newChild->ImageIndex = imageIndex;
- newChild->SelectedImageIndex = selectedImageIndex;
- newChild->Data = data;
- newChild->Data2 = data2;
- if( data2 )
- {
- data2->grab();
- }
- return newChild;
- }
- IGUITreeViewNode* CGUITreeViewNode::insertChildAfter(
- IGUITreeViewNode* other,
- const wchar_t* text,
- const wchar_t* icon /*= 0*/,
- s32 imageIndex /*= -1*/,
- s32 selectedImageIndex /*= -1*/,
- void* data /*= 0*/,
- IReferenceCounted* data2/* = 0*/ )
- {
- core::list<CGUITreeViewNode*>::Iterator itOther;
- CGUITreeViewNode* newChild = 0;
- for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
- {
- if( other == *itOther )
- {
- newChild = new CGUITreeViewNode( Owner, this );
- newChild->Text = text;
- newChild->Icon = icon;
- newChild->ImageIndex = imageIndex;
- newChild->SelectedImageIndex = selectedImageIndex;
- newChild->Data = data;
- newChild->Data2 = data2;
- if( data2 )
- {
- data2->grab();
- }
- Children.insert_after( itOther, newChild );
- break;
- }
- }
- return newChild;
- }
- IGUITreeViewNode* CGUITreeViewNode::insertChildBefore(
- IGUITreeViewNode* other,
- const wchar_t* text,
- const wchar_t* icon /*= 0*/,
- s32 imageIndex /*= -1*/,
- s32 selectedImageIndex /*= -1*/,
- void* data /*= 0*/,
- IReferenceCounted* data2/* = 0*/ )
- {
- core::list<CGUITreeViewNode*>::Iterator itOther;
- CGUITreeViewNode* newChild = 0;
- for( itOther = Children.begin(); itOther != Children.end(); itOther++ )
- {
- if( other == *itOther )
- {
- newChild = new CGUITreeViewNode( Owner, this );
- newChild->Text = text;
- newChild->Icon = icon;
- newChild->ImageIndex = imageIndex;
- newChild->SelectedImageIndex = selectedImageIndex;
- newChild->Data = data;
- newChild->Data2 = data2;
- if( data2 )
- {
- data2->grab();
- }
- Children.insert_before( itOther, newChild );
- break;
- }
- }
- return newChild;
- }
- IGUITreeViewNode* CGUITreeViewNode::getFirstChild() const
- {
- if( Children.empty() )
- {
- return 0;
- }
- else
- {
- return *( Children.begin() );
- }
- }
- IGUITreeViewNode* CGUITreeViewNode::getLastChild() const
- {
- if( Children.empty() )
- {
- return 0;
- }
- else
- {
- return *( Children.getLast() );
- }
- }
- IGUITreeViewNode* CGUITreeViewNode::getPrevSibling() const
- {
- core::list<CGUITreeViewNode*>::Iterator itThis;
- core::list<CGUITreeViewNode*>::Iterator itOther;
- CGUITreeViewNode* other = 0;
- if( Parent )
- {
- for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
- {
- if( this == *itThis )
- {
- if( itThis != Parent->Children.begin() )
- {
- other = *itOther;
- }
- break;
- }
- itOther = itThis;
- }
- }
- return other;
- }
- IGUITreeViewNode* CGUITreeViewNode::getNextSibling() const
- {
- core::list<CGUITreeViewNode*>::Iterator itThis;
- CGUITreeViewNode* other = 0;
- if( Parent )
- {
- for( itThis = Parent->Children.begin(); itThis != Parent->Children.end(); itThis++ )
- {
- if( this == *itThis )
- {
- if( itThis != Parent->Children.getLast() )
- {
- other = *( ++itThis );
- }
- break;
- }
- }
- }
- return other;
- }
- IGUITreeViewNode* CGUITreeViewNode::getNextVisible() const
- {
- IGUITreeViewNode* next = 0;
- IGUITreeViewNode* node = 0;
- node = const_cast<CGUITreeViewNode*>( this );
- if( node->getExpanded() && node->hasChildren() )
- {
- next = node->getFirstChild();
- }
- else
- {
- next = node->getNextSibling();
- }
- while( !next && node->getParent() )
- {
- next = node->getParent()->getNextSibling();
- if( !next )
- {
- node = node->getParent();
- }
- }
- return next;
- }
- bool CGUITreeViewNode::deleteChild( IGUITreeViewNode* child )
- {
- core::list<CGUITreeViewNode*>::Iterator itChild;
- bool deleted = false;
- for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
- {
- if( child == *itChild )
- {
- child->drop();
- Children.erase( itChild );
- deleted = true;
- break;
- }
- }
- return deleted;
- }
- bool CGUITreeViewNode::moveChildUp( IGUITreeViewNode* child )
- {
- core::list<CGUITreeViewNode*>::Iterator itChild;
- core::list<CGUITreeViewNode*>::Iterator itOther;
- CGUITreeViewNode* nodeTmp;
- bool moved = false;
- for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
- {
- if( child == *itChild )
- {
- if( itChild != Children.begin() )
- {
- nodeTmp = *itChild;
- *itChild = *itOther;
- *itOther = nodeTmp;
- moved = true;
- }
- break;
- }
- itOther = itChild;
- }
- return moved;
- }
- bool CGUITreeViewNode::moveChildDown( IGUITreeViewNode* child )
- {
- core::list<CGUITreeViewNode*>::Iterator itChild;
- core::list<CGUITreeViewNode*>::Iterator itOther;
- CGUITreeViewNode* nodeTmp;
- bool moved = false;
- for( itChild = Children.begin(); itChild != Children.end(); itChild++ )
- {
- if( child == *itChild )
- {
- if( itChild != Children.getLast() )
- {
- itOther = itChild;
- ++itOther;
- nodeTmp = *itChild;
- *itChild = *itOther;
- *itOther = nodeTmp;
- moved = true;
- }
- break;
- }
- }
- return moved;
- }
- void CGUITreeViewNode::setExpanded( bool expanded )
- {
- Expanded = expanded;
- }
- void CGUITreeViewNode::setSelected( bool selected )
- {
- if( Owner )
- {
- if( selected )
- {
- Owner->Selected = this;
- }
- else
- {
- if( Owner->Selected == this )
- {
- Owner->Selected = 0;
- }
- }
- }
- }
- bool CGUITreeViewNode::getSelected() const
- {
- if( Owner )
- {
- return Owner->Selected == (IGUITreeViewNode*)this;
- }
- else
- {
- return false;
- }
- }
- bool CGUITreeViewNode::isRoot() const
- {
- return ( Owner && ( this == Owner->Root ) );
- }
- s32 CGUITreeViewNode::getLevel() const
- {
- if( Parent )
- {
- return Parent->getLevel() + 1;
- }
- else
- {
- return 0;
- }
- }
- bool CGUITreeViewNode::isVisible() const
- {
- if( Parent )
- {
- return Parent->getExpanded() && Parent->isVisible();
- }
- else
- {
- return true;
- }
- }
- //! constructor
- CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
- s32 id, core::rect<s32> rectangle, bool clip,
- bool drawBack,bool scrollBarVertical, bool scrollBarHorizontal)
- : IGUITreeView( environment, parent, id, rectangle ),
- Root(0), Selected(0),
- ItemHeight( 0 ),
- IndentWidth( 0 ),
- TotalItemHeight( 0 ),
- TotalItemWidth ( 0 ),
- Font( 0 ),
- IconFont( 0 ),
- ScrollBarH( 0 ),
- ScrollBarV( 0 ),
- ImageList( 0 ),
- LastEventNode( 0 ),
- LinesVisible( true ),
- Selecting( false ),
- Clip( clip ),
- DrawBack( drawBack ),
- ImageLeftOfIcon( true )
- {
- #ifdef _DEBUG
- setDebugName( "CGUITreeView" );
- #endif
- IGUISkin* skin = Environment->getSkin();
- s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE );
- if ( scrollBarVertical )
- {
- ScrollBarV = new CGUIScrollBar( false, Environment, this, 0,
- core::rect<s32>( RelativeRect.getWidth() - s,
- 0,
- RelativeRect.getWidth(),
- RelativeRect.getHeight() - (scrollBarHorizontal ? s : 0 )
- ),
- !clip );
- ScrollBarV->drop();
- ScrollBarV->setSubElement(true);
- ScrollBarV->setPos( 0 );
- ScrollBarV->grab();
- }
- if ( scrollBarHorizontal )
- {
- ScrollBarH = new CGUIScrollBar( true, Environment, this, 1,
- core::rect<s32>( 0, RelativeRect.getHeight() - s, RelativeRect.getWidth() - s, RelativeRect.getHeight() ),
- !clip );
- ScrollBarH->drop();
- ScrollBarH->setSubElement(true);
- ScrollBarH->setPos( 0 );
- ScrollBarH->grab();
- }
- Root = new CGUITreeViewNode( this, 0 );
- Root->Expanded = true;
- recalculateItemHeight();
- }
- //! destructor
- CGUITreeView::~CGUITreeView()
- {
- if( ScrollBarV )
- {
- ScrollBarV->drop();
- }
- if( ScrollBarH )
- {
- ScrollBarH->drop();
- }
- if( Font )
- {
- Font->drop();
- }
- if( IconFont )
- {
- IconFont->drop();
- }
- if( ImageList )
- {
- ImageList->drop();
- }
- if( Root )
- {
- Root->drop();
- }
- }
- void CGUITreeView::recalculateItemHeight()
- {
- IGUISkin* skin = Environment->getSkin();
- IGUITreeViewNode* node;
- if( Font != skin->getFont() )
- {
- if( Font )
- {
- Font->drop();
- }
- Font = skin->getFont();
- ItemHeight = 0;
- if( Font )
- {
- ItemHeight = Font->getDimension( L"A" ).Height + 4;
- Font->grab();
- }
- if( IconFont )
- {
- s32 height = IconFont->getDimension( L" " ).Height;
- if( height > ItemHeight )
- {
- ItemHeight = height;
- }
- }
- if( ImageList )
- {
- if( ImageList->getImageSize().Height + 1 > ItemHeight )
- {
- ItemHeight = ImageList->getImageSize().Height + 1;
- }
- }
- }
- IndentWidth = ItemHeight;
- if( IndentWidth < 9 )
- {
- IndentWidth = 9;
- }
- else if( IndentWidth > 15 )
- {
- IndentWidth = 15;
- }
- else
- {
- if( ( ( IndentWidth >> 1 ) << 1 ) - IndentWidth == 0 )
- {
- --IndentWidth;
- }
- }
- TotalItemHeight = 0;
- TotalItemWidth = AbsoluteRect.getWidth() * 2;
- node = Root->getFirstChild();
- while( node )
- {
- TotalItemHeight += ItemHeight;
- node = node->getNextVisible();
- }
- if ( ScrollBarV )
- ScrollBarV->setMax( core::max_(0,TotalItemHeight - AbsoluteRect.getHeight()) );
- if ( ScrollBarH )
- ScrollBarH->setMax( core::max_(0, TotalItemWidth - AbsoluteRect.getWidth()) );
- }
- //! called if an event happened.
- bool CGUITreeView::OnEvent( const SEvent &event )
- {
- if ( isEnabled() )
- {
- switch( event.EventType )
- {
- case EET_GUI_EVENT:
- switch( event.GUIEvent.EventType )
- {
- case gui::EGET_SCROLL_BAR_CHANGED:
- if( event.GUIEvent.Caller == ScrollBarV || event.GUIEvent.Caller == ScrollBarH )
- {
- //s32 pos = ( ( gui::IGUIScrollBar* )event.GUIEvent.Caller )->getPos();
- return true;
- }
- break;
- case gui::EGET_ELEMENT_FOCUS_LOST:
- {
- Selecting = false;
- return false;
- }
- break;
- default:
- break;
- }
- break;
- case EET_MOUSE_INPUT_EVENT:
- {
- core::position2d<s32> p( event.MouseInput.X, event.MouseInput.Y );
- switch( event.MouseInput.Event )
- {
- case EMIE_MOUSE_WHEEL:
- if ( ScrollBarV )
- ScrollBarV->setPos( ScrollBarV->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1) * -10 );
- return true;
- break;
- case EMIE_LMOUSE_PRESSED_DOWN:
- if (Environment->hasFocus(this) && !AbsoluteClippingRect.isPointInside(p) )
- {
- Environment->removeFocus(this);
- return false;
- }
- if( Environment->hasFocus( this ) &&
- ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) ||
- ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) )
- )
- )
- {
- return true;
- }
- Selecting = true;
- Environment->setFocus( this );
- return true;
- break;
- case EMIE_LMOUSE_LEFT_UP:
- if( Environment->hasFocus( this ) &&
- ( ( ScrollBarV && ScrollBarV->getAbsolutePosition().isPointInside( p ) && ScrollBarV->OnEvent( event ) ) ||
- ( ScrollBarH && ScrollBarH->getAbsolutePosition().isPointInside( p ) && ScrollBarH->OnEvent( event ) )
- )
- )
- {
- return true;
- }
- Selecting = false;
- Environment->removeFocus( this );
- mouseAction( event.MouseInput.X, event.MouseInput.Y );
- return true;
- break;
- case EMIE_MOUSE_MOVED:
- if( Selecting )
- {
- if( getAbsolutePosition().isPointInside( p ) )
- {
- mouseAction( event.MouseInput.X, event.MouseInput.Y, true );
- return true;
- }
- }
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- }
- return Parent ? Parent->OnEvent( event ) : false;
- }
- /*!
- */
- void CGUITreeView::mouseAction( s32 xpos, s32 ypos, bool onlyHover /*= false*/ )
- {
- IGUITreeViewNode* oldSelected = Selected;
- IGUITreeViewNode* hitNode = 0;
- s32 selIdx=-1;
- s32 n;
- IGUITreeViewNode* node;
- SEvent event;
- event.EventType = EET_GUI_EVENT;
- event.GUIEvent.Caller = this;
- event.GUIEvent.Element = 0;
- xpos -= AbsoluteRect.UpperLeftCorner.X;
- ypos -= AbsoluteRect.UpperLeftCorner.Y;
- // find new selected item.
- if( ItemHeight != 0 && ScrollBarV )
- {
- selIdx = ( ( ypos - 1 ) + ScrollBarV->getPos() ) / ItemHeight;
- }
- hitNode = 0;
- node = Root->getFirstChild();
- n = 0;
- while( node )
- {
- if( selIdx == n )
- {
- hitNode = node;
- break;
- }
- node = node->getNextVisible();
- ++n;
- }
- if( hitNode && xpos > hitNode->getLevel() * IndentWidth )
- {
- Selected = hitNode;
- }
- if( hitNode && !onlyHover
- && xpos < hitNode->getLevel() * IndentWidth
- && xpos > ( hitNode->getLevel() - 1 ) * IndentWidth
- && hitNode->hasChildren() )
- {
- hitNode->setExpanded( !hitNode->getExpanded() );
- // post expand/collaps news
- if( hitNode->getExpanded() )
- {
- event.GUIEvent.EventType = EGET_TREEVIEW_NODE_EXPAND;
- }
- else
- {
- event.GUIEvent.EventType = EGET_TREEVIEW_NODE_COLLAPS;
- }
- LastEventNode = hitNode;
- Parent->OnEvent( event );
- LastEventNode = 0;
- }
- if( Selected && !Selected->isVisible() )
- {
- Selected = 0;
- }
- // post selection news
- if( Parent && !onlyHover && Selected != oldSelected )
- {
- if( oldSelected )
- {
- event.GUIEvent.EventType = EGET_TREEVIEW_NODE_DESELECT;
- LastEventNode = oldSelected;
- Parent->OnEvent( event );
- LastEventNode = 0;
- }
- if( Selected )
- {
- event.GUIEvent.EventType = EGET_TREEVIEW_NODE_SELECT;
- LastEventNode = Selected;
- Parent->OnEvent( event );
- LastEventNode = 0;
- }
- }
- }
- //! draws the element and its children
- void CGUITreeView::draw()
- {
- if( !IsVisible )
- {
- return;
- }
- recalculateItemHeight(); // if the font changed
- IGUISkin* skin = Environment->getSkin();
- irr::video::IVideoDriver* driver = Environment->getVideoDriver();
- core::rect<s32>* clipRect = 0;
- if( Clip )
- {
- clipRect = &AbsoluteClippingRect;
- }
- // draw background
- core::rect<s32> frameRect( AbsoluteRect );
- if( DrawBack )
- {
- driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect,
- clipRect );
- }
- // draw the border
- frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect,
- clipRect );
- frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y;
- frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), frameRect,
- clipRect );
- frameRect = AbsoluteRect;
- frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X - 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect,
- clipRect );
- frameRect = AbsoluteRect;
- frameRect.UpperLeftCorner.Y = AbsoluteRect.LowerRightCorner.Y - 1;
- frameRect.LowerRightCorner.Y = AbsoluteRect.LowerRightCorner.Y;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect,
- clipRect );
- // draw items
- core::rect<s32> clientClip( AbsoluteRect );
- clientClip.UpperLeftCorner.Y += 1;
- clientClip.UpperLeftCorner.X += 1;
- clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X;
- clientClip.LowerRightCorner.Y -= 1;
- if ( ScrollBarV )
- clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE );
- if ( ScrollBarH )
- clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE );
- if( clipRect )
- {
- clientClip.clipAgainst( *clipRect );
- }
- frameRect = AbsoluteRect;
- frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE );
- frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
- if ( ScrollBarV )
- {
- frameRect.UpperLeftCorner.Y -= ScrollBarV->getPos();
- frameRect.LowerRightCorner.Y -= ScrollBarV->getPos();
- }
- if ( ScrollBarH )
- {
- frameRect.UpperLeftCorner.X -= ScrollBarH->getPos();
- frameRect.LowerRightCorner.X -= ScrollBarH->getPos();
- }
- IGUITreeViewNode* node = Root->getFirstChild();
- while( node )
- {
- frameRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + 1 + node->getLevel() * IndentWidth;
- if( frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y
- && frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y )
- {
- if( node == Selected )
- {
- driver->draw2DRectangle( skin->getColor( EGDC_HIGH_LIGHT ), frameRect, &clientClip );
- }
- if( node->hasChildren() )
- {
- core::rect<s32> rc;
- core::rect<s32> expanderRect;
- expanderRect.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth + 2;
- expanderRect.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() - ( IndentWidth - 4 ) ) >> 1 );
- expanderRect.LowerRightCorner.X = expanderRect.UpperLeftCorner.X + IndentWidth - 4;
- expanderRect.LowerRightCorner.Y = expanderRect.UpperLeftCorner.Y + IndentWidth - 4;
- // box upper line
- rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X;
- rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y;
- rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X;
- rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- // box left line
- rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X;
- rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y;
- rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
- rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- // box right line
- rc.UpperLeftCorner.X = expanderRect.LowerRightCorner.X - 1;
- rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y;
- rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
- rc.LowerRightCorner.Y = expanderRect.LowerRightCorner.Y;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- // box bottom line
- rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X;
- rc.UpperLeftCorner.Y = expanderRect.LowerRightCorner.Y - 1;
- rc.LowerRightCorner.X = expanderRect.LowerRightCorner.X;
- rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- // horizontal '-' line
- rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + 2;
- rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + ( expanderRect.getHeight() >> 1 );
- rc.LowerRightCorner.X = rc.UpperLeftCorner.X + expanderRect.getWidth() - 4;
- rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc,
- clipRect );
- if( !node->getExpanded() )
- {
- // vertical '+' line
- rc.UpperLeftCorner.X = expanderRect.UpperLeftCorner.X + ( expanderRect.getWidth() >> 1 );
- rc.UpperLeftCorner.Y = expanderRect.UpperLeftCorner.Y + 2;
- rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
- rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + expanderRect.getHeight() - 4;
- driver->draw2DRectangle( skin->getColor( EGDC_BUTTON_TEXT ), rc,
- clipRect );
- }
- }
- core::rect<s32> textRect = frameRect;
- if( Font )
- {
- EGUI_DEFAULT_COLOR textCol = EGDC_GRAY_TEXT;
- if ( isEnabled() )
- textCol = ( node == Selected ) ? EGDC_HIGH_LIGHT_TEXT : EGDC_BUTTON_TEXT;
- s32 iconWidth = 0;
- for( s32 n = 0; n < 2; ++n )
- {
- s32 index = node->getImageIndex();
- if( ( ImageList && index >= 0 )
- && ( ( ImageLeftOfIcon && n == 0 )
- || ( !ImageLeftOfIcon && n == 1 ) ) )
- {
- index = node->getSelectedImageIndex();
- if( node != Selected || index < 0 )
- {
- index = node->getImageIndex();
- }
- ImageList->draw(
- index,
- core::position2d<s32>(
- textRect.UpperLeftCorner.X,
- textRect.UpperLeftCorner.Y + ( ( textRect.getHeight() - ImageList->getImageSize().Height ) >> 1 ) ),
- &clientClip );
- iconWidth += ImageList->getImageSize().Width + 3;
- textRect.UpperLeftCorner.X += ImageList->getImageSize().Width + 3;
- }
- else if( ( IconFont && reinterpret_cast<CGUITreeViewNode*>( node )->Icon.size() )
- && ( ( ImageLeftOfIcon && n == 1 )
- || ( !ImageLeftOfIcon && n == 0 ) ) )
- {
- IconFont->draw( node->getIcon(), textRect, skin->getColor(textCol), false, true, &clientClip );
- iconWidth += IconFont->getDimension( node->getIcon() ).Width + 3;
- textRect.UpperLeftCorner.X += IconFont->getDimension( node->getIcon() ).Width + 3;
- }
- }
- Font->draw( node->getText(), textRect, skin->getColor(textCol), false, true, &clientClip );
- textRect.UpperLeftCorner.X -= iconWidth;
- }
- // draw the lines if neccessary
- if( LinesVisible )
- {
- core::rect<s32> rc;
- // horizontal line
- rc.UpperLeftCorner.X = frameRect.UpperLeftCorner.X - IndentWidth - ( IndentWidth >> 1 ) - 1;
- rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y + ( ( frameRect.getHeight() ) >> 1 );
- if( node->hasChildren() )
- {
- rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - IndentWidth;
- }
- else
- {
- rc.LowerRightCorner.X = frameRect.UpperLeftCorner.X - 2;
- }
- rc.LowerRightCorner.Y = rc.UpperLeftCorner.Y + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- if( node->getParent() != Root )
- {
- // vertical line
- if( node == node->getParent()->getFirstChild() )
- {
- rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( ( frameRect.getHeight() - IndentWidth ) >> 1 );
- }
- else
- {
- rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 );
- }
- rc.LowerRightCorner.X = rc.UpperLeftCorner.X + 1;
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- // the vertical lines of all parents
- IGUITreeViewNode* nodeTmp = node->getParent();
- rc.UpperLeftCorner.Y = frameRect.UpperLeftCorner.Y - ( frameRect.getHeight() >> 1 );
- for( s32 n = 0; n < node->getLevel() - 2; ++n )
- {
- rc.UpperLeftCorner.X -= IndentWidth;
- rc.LowerRightCorner.X -= IndentWidth;
- if( nodeTmp != nodeTmp->getParent()->getLastChild() )
- {
- driver->draw2DRectangle( skin->getColor( EGDC_3D_SHADOW ), rc,
- clipRect );
- }
- nodeTmp = nodeTmp->getParent();
- }
- }
- }
- }
- frameRect.UpperLeftCorner.Y += ItemHeight;
- frameRect.LowerRightCorner.Y += ItemHeight;
- node = node->getNextVisible();
- }
- IGUIElement::draw();
- }
- //! Sets the font which should be used as icon font. This font is set to the Irrlicht engine
- //! built-in-font by default. Icons can be displayed in front of every list item.
- //! An icon is a string, displayed with the icon font. When using the build-in-font of the
- //! Irrlicht engine as icon font, the icon strings defined in GUIIcons.h can be used.
- void CGUITreeView::setIconFont( IGUIFont* font )
- {
- s32 height;
- if ( font )
- font->grab();
- if ( IconFont )
- {
- IconFont->drop();
- }
- IconFont = font;
- if( IconFont )
- {
- height = IconFont->getDimension( L" " ).Height;
- if( height > ItemHeight )
- {
- ItemHeight = height;
- }
- }
- }
- //! Sets the image list which should be used for the image and selected image of every node.
- //! The default is 0 (no images).
- void CGUITreeView::setImageList( IGUIImageList* imageList )
- {
- if (imageList )
- imageList->grab();
- if( ImageList )
- {
- ImageList->drop();
- }
- ImageList = imageList;
- if( ImageList )
- {
- if( ImageList->getImageSize().Height + 1 > ItemHeight )
- {
- ItemHeight = ImageList->getImageSize().Height + 1;
- }
- }
- }
- } // end namespace gui
- } // end namespace irr
- #endif // _IRR_COMPILE_WITH_GUI_
|