/* GWEN Copyright (c) 2010 Facepunch Studios See license in Gwen.h */ #include "Gwen/Controls/TreeControl.h" #include "Gwen/Controls/ScrollControl.h" #include "Gwen/Utility.h" using namespace Gwen; using namespace Gwen::Controls; GWEN_CONTROL_CONSTRUCTOR( TreeControl ) { m_TreeControl = this; m_bUpdateScrollBar = 2; m_ToggleButton->DelayedDelete(); m_ToggleButton = NULL; m_Title->DelayedDelete(); m_Title = NULL; m_InnerPanel->DelayedDelete(); m_InnerPanel = NULL; m_bAllowMultipleSelection = false; m_ScrollControl = new ScrollControl( this ); m_ScrollControl->Dock( Pos::Fill ); m_ScrollControl->SetScroll( false, true ); m_ScrollControl->SetAutoHideBars( true ); m_ScrollControl->SetMargin( Margin( 1, 1, 1, 1 ) ); m_InnerPanel = m_ScrollControl; m_ScrollControl->SetInnerSize( 1000, 1000 ); } void TreeControl::Render( Skin::Base* skin ) { if ( ShouldDrawBackground() ) skin->DrawTreeControl( this ); } void TreeControl::ForceUpdateScrollBars() { m_ScrollControl->UpdateScrollBars(); } void TreeControl::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ ) { } void TreeControl::Clear() { m_ScrollControl->Clear(); } void TreeControl::Layout( Skin::Base* skin ) { BaseClass::BaseClass::Layout( skin ); } void TreeControl::PostLayout( Skin::Base* skin ) { BaseClass::BaseClass::PostLayout( skin ); } void TreeControl::OnNodeAdded( TreeNode* pNode ) { pNode->onNamePress.Add( this, &TreeControl::OnNodeSelection ); } void TreeControl::OnNodeSelection( Controls::Base* /*control*/ ) { //printf("TreeControl::OnNodeSelection\n"); if ( !m_bAllowMultipleSelection || !Gwen::Input::IsKeyDown( Key::Control ) ) DeselectAll(); } void TreeControl::iterate(int action, int* maxItem, int* curItem) { Base::List& children = m_InnerPanel->GetChildren(); for ( Base::List::iterator iter = children.begin(); iter != children.end(); ++iter ) { TreeNode* pChild = (*iter)->DynamicCastTreeNode(); if ( !pChild ) continue; pChild->iterate(action ,maxItem, curItem); } } bool TreeControl::OnKeyUp( bool bDown ) { if (bDown) { // int maxIndex = 0; int newIndex = 0; int maxItem=0; int curItem=-1; iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItem,&curItem); // maxIndex = maxItem; int targetItem = curItem; if (curItem>0) { maxItem=0; int deselectIndex = targetItem; targetItem--; newIndex = targetItem; iterate(ITERATE_ACTION_SELECT,&maxItem,&targetItem); if (targetItem<0) { maxItem=0; iterate(ITERATE_ACTION_DESELECT_INDEX,&maxItem,&deselectIndex); } curItem = newIndex; // float amount = float(newIndex)/float(maxIndex); float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize(); float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize(); float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount(); // float minCoordViewableWindow = curAmount*contSize; //float maxCoordViewableWindow = minCoordViewableWindow+viewSize; float minCoordSelectedItem = curItem*16.f; // float maxCoordSelectedItem = (curItem+1)*16.f; if (contSize!=viewSize) { { float newAmount = float(minCoordSelectedItem)/(contSize-viewSize); if (newAmountm_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } { int numItems = (viewSize)/16-1; float newAmount = float((curItem-numItems)*16)/(contSize-viewSize); if (newAmount>curAmount) { m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } } } } ForceUpdateScrollBars(); return true; } bool TreeControl::OnKeyDown( bool bDown ) { if (bDown) { // int maxIndex = 0; int newIndex = 0; int maxItem=0; int curItem=-1; iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItem,&curItem); // maxIndex = maxItem; int targetItem = curItem; if (curItem>=0) { maxItem=0; int deselectIndex = targetItem; targetItem++; newIndex = targetItem; iterate(ITERATE_ACTION_SELECT,&maxItem,&targetItem); if (targetItem<0) { maxItem=0; iterate(ITERATE_ACTION_DESELECT_INDEX,&maxItem,&deselectIndex); } curItem= newIndex; // float amount = (int)float(newIndex)/float(maxIndex); float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize(); float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize(); float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount(); // float minCoordViewableWindow = curAmount*contSize; //float maxCoordViewableWindow = minCoordViewableWindow+viewSize; float minCoordSelectedItem = curItem*16.f; //float maxCoordSelectedItem = (curItem+1)*16.f; if (contSize!=viewSize) { { float newAmount = float(minCoordSelectedItem)/(contSize-viewSize); if (newAmountm_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } { int numItems = (viewSize)/16-1; float newAmount = float((curItem-numItems)*16)/(contSize-viewSize); if (newAmount>curAmount) { m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } } } } ForceUpdateScrollBars(); return true; } extern int avoidUpdate; bool TreeControl::OnKeyRight( bool bDown ) { if (bDown) { avoidUpdate = -3; iterate(ITERATE_ACTION_OPEN,0,0); int maxItem=0; int curItem=0; iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItem,&curItem); // float amount = float(curItem)/float(maxItem); float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize(); float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize(); float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount(); // float minCoordViewableWindow = curAmount*contSize; // float maxCoordViewableWindow = minCoordViewableWindow+viewSize; float minCoordSelectedItem = curItem*16.f; // float maxCoordSelectedItem = (curItem+1)*16.f; if (contSize!=viewSize) { { float newAmount = float(minCoordSelectedItem)/(contSize-viewSize); if (newAmountm_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } { int numItems = (viewSize)/16-1; float newAmount = float((curItem-numItems)*16)/(contSize-viewSize); if (newAmount>curAmount) { m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } } Invalidate(); } ForceUpdateScrollBars(); return true; } bool TreeControl::OnKeyLeft( bool bDown ) { if (bDown) { avoidUpdate = -3; iterate(ITERATE_ACTION_CLOSE,0,0); int maxItems=0; int curItem=0; iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItems,&curItem); // float amount = float(curItem)/float(maxItems); // m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(amount,true); float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize(); float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize(); float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount(); // float minCoordViewableWindow = curAmount*contSize; // float maxCoordViewableWindow = minCoordViewableWindow+viewSize; float minCoordSelectedItem = curItem*16.f; // float maxCoordSelectedItem = (curItem+1)*16.f; if (contSize!=viewSize) { { float newAmount = float(minCoordSelectedItem)/(contSize-viewSize); if (newAmountm_VerticalScrollBar->SetScrolledAmount(newAmount,true); } } { int numItems = (viewSize)/16-1; float newAmount = float((curItem-numItems)*16)/(contSize-viewSize); if (newAmount>curAmount) { m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true); } Invalidate(); } } //viewSize/contSize //printf("!\n"); //this->Layout(0); } ForceUpdateScrollBars(); return true; }