This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
MyGameFramework/lib/gwen/controls/gwen_scrollcontrol.cpp
Gered c5cdddbeaa initial commit
current versions of all of my basic framework sources, build configurations/scripts, and supporting assets
2013-01-31 12:53:05 -05:00

275 lines
6.8 KiB
C++

/*
GWEN
Copyright (c) 2010 Facepunch Studios
See license in Gwen.h
*/
#include "gwen_scrollcontrol.h"
#include "gwen_scrollbar.h"
#include "gwen_verticalscrollbar.h"
#include "gwen_horizontalscrollbar.h"
#include "../gwen_utility.h"
using namespace Gwen;
using namespace Gwen::Controls;
using namespace Gwen::ControlsInternal;
GWEN_CONTROL_CONSTRUCTOR( ScrollControl )
{
SetMouseInputEnabled( false );
m_VerticalScrollBar = new VerticalScrollBar( this );
m_VerticalScrollBar->Dock( Pos::Right );
m_VerticalScrollBar->onBarMoved.Add( this, &ScrollControl::VBarMoved );
m_VerticalScrollBar->SetNudgeAmount( 30 );
m_bCanScrollV = true;
m_HorizontalScrollBar = new HorizontalScrollBar( this );
m_HorizontalScrollBar->Dock( Pos::Bottom );
m_HorizontalScrollBar->onBarMoved.Add( this, &ScrollControl::HBarMoved );
m_bCanScrollH = true;
m_HorizontalScrollBar->SetNudgeAmount( 30 );
m_InnerPanel = new Base( this );
m_InnerPanel->SetPos(0, 0);
m_InnerPanel->SetMargin( Margin(5,5,5,5));
m_InnerPanel->SendToBack();
m_InnerPanel->SetMouseInputEnabled( false );
m_bAutoHideBars = true;
}
void ScrollControl::SetScroll( bool h, bool v )
{
m_bCanScrollV = v;
m_bCanScrollH = h;
m_VerticalScrollBar->SetHidden( !m_bCanScrollV );
m_HorizontalScrollBar->SetHidden( !m_bCanScrollH );
}
void ScrollControl::SetInnerSize( int w, int h )
{
m_InnerPanel->SetSize( w, h );
}
void ScrollControl::VBarMoved( Controls::Base * /*control*/ )
{
Invalidate();
}
void ScrollControl::HBarMoved( Controls::Base * /*control*/ )
{
Invalidate();
}
void ScrollControl::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
{
UpdateScrollBars();
Invalidate();
}
void ScrollControl::Layout( Skin::Base* skin )
{
UpdateScrollBars();
BaseClass::Layout(skin);
}
bool ScrollControl::OnMouseWheeled( int iDelta )
{
if ( CanScrollV() && m_VerticalScrollBar->Visible() )
{
if ( m_VerticalScrollBar->SetScrolledAmount( m_VerticalScrollBar->GetScrolledAmount() - m_VerticalScrollBar->GetNudgeAmount() * ( (float)iDelta / 60.0f ), true) )
return true;
}
if ( CanScrollH() && m_HorizontalScrollBar->Visible() )
{
if ( m_HorizontalScrollBar->SetScrolledAmount( m_HorizontalScrollBar->GetScrolledAmount() - m_HorizontalScrollBar->GetNudgeAmount() * ( (float)iDelta / 60.0f ), true) )
return true;
}
return false;
}
void ScrollControl::Render( Skin::Base* skin )
{
#if 0
// Debug render - this shouldn't render ANYTHING REALLY - it should be up to the parent!
Gwen::Rect rect = GetRenderBounds();
Gwen::Renderer::Base* render = skin->GetRender();
render->SetDrawColor( Gwen::Color( 255, 255, 0, 100 ) );
render->DrawFilledRect( rect );
render->SetDrawColor( Gwen::Color( 255, 0, 0, 100 ) );
render->DrawFilledRect( m_InnerPanel->GetBounds() );
render->RenderText( skin->GetDefaultFont(), Gwen::Point( 0, 0 ), Utility::Format( "Offset: %i %i", m_InnerPanel->X(), m_InnerPanel->Y() ) );
#else //0
(void)skin;
#endif //0
}
bool ScrollControl::ContentsAreDocked()
{
if ( !m_InnerPanel )
return false;
for ( Base::List::iterator iter = m_InnerPanel->Children.begin(); iter != m_InnerPanel->Children.end(); ++iter )
{
Base* pChild = *iter;
if ( pChild->GetDock() == Pos::None )
return false;
}
return true;
}
void ScrollControl::UpdateScrollBars()
{
if ( !m_InnerPanel )
return;
if ( ContentsAreDocked() )
{
m_VerticalScrollBar->SetHidden( true );
m_HorizontalScrollBar->SetHidden( true );
m_InnerPanel->SetSize( GetSize() );
m_InnerPanel->SetPos( 0, 0 );
return;
}
int childrenWidth = 0;
int childrenHeight = 0;
//Get the max size of all our children together
for ( Base::List::iterator iter = m_InnerPanel->Children.begin(); iter != m_InnerPanel->Children.end(); ++iter )
{
Base* pChild = *iter;
childrenWidth = Utility::Max( childrenWidth, pChild->Right() );
childrenHeight = Utility::Max( childrenHeight, pChild->Bottom() );
}
if ( m_bCanScrollH )
{
m_InnerPanel->SetSize( Utility::Max( Width(), childrenWidth), Utility::Max( Height(), childrenHeight ) );
}
else
{
m_InnerPanel->SetSize( Width() - (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()-1), Utility::Max( Height(), childrenHeight ) );
}
float wPercent = (float)Width() / (float)(childrenWidth + (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()));
float hPercent = (float)Height() / (float)(childrenHeight + (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()));
if ( m_bCanScrollV )
SetVScrollRequired( hPercent >= 1 );
else
m_VerticalScrollBar->SetHidden( true );
if ( m_bCanScrollH )
SetHScrollRequired( wPercent >= 1 );
else
m_HorizontalScrollBar->SetHidden( true );
m_VerticalScrollBar->SetContentSize( m_InnerPanel->Height() );
m_VerticalScrollBar->SetViewableContentSize( Height() - (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()));
m_HorizontalScrollBar->SetContentSize( m_InnerPanel->Width() );
m_HorizontalScrollBar->SetViewableContentSize( Width() - (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()) );
int newInnerPanelPosX = 0;
int newInnerPanelPosY = 0;
if ( CanScrollV() && !m_VerticalScrollBar->Hidden() )
{
newInnerPanelPosY = -( ( m_InnerPanel->Height() ) - Height() + (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()) ) * m_VerticalScrollBar->GetScrolledAmount();
}
if ( CanScrollH() && !m_HorizontalScrollBar->Hidden() )
{
newInnerPanelPosX = - ( ( m_InnerPanel->Width() ) - Width() + (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width())) * m_HorizontalScrollBar->GetScrolledAmount();
}
m_InnerPanel->SetPos( newInnerPanelPosX , newInnerPanelPosY );
}
void ScrollControl::SetVScrollRequired(bool req)
{
if ( req )
{
m_VerticalScrollBar->SetScrolledAmount( 0, true );
m_VerticalScrollBar->SetDisabled( true );
if ( m_bAutoHideBars )
m_VerticalScrollBar->SetHidden( true );
}
else
{
m_VerticalScrollBar->SetHidden( false );
m_VerticalScrollBar->SetDisabled( false );
}
}
void ScrollControl::SetHScrollRequired(bool req)
{
if ( req )
{
m_HorizontalScrollBar->SetScrolledAmount( 0, true );
m_HorizontalScrollBar->SetDisabled( true );
if ( m_bAutoHideBars )
m_HorizontalScrollBar->SetHidden( true );
}
else
{
m_HorizontalScrollBar->SetHidden( false );
m_HorizontalScrollBar->SetDisabled( true );
}
}
void ScrollControl::ScrollToBottom()
{
if ( !CanScrollV() ) return;
UpdateScrollBars();
m_VerticalScrollBar->ScrollToBottom();
}
void ScrollControl::ScrollToTop()
{
if ( CanScrollV() )
{
UpdateScrollBars();
m_VerticalScrollBar->ScrollToTop();
}
}
void ScrollControl::ScrollToLeft()
{
if ( CanScrollH() )
{
UpdateScrollBars();
m_HorizontalScrollBar->ScrollToLeft();
}
}
void ScrollControl::ScrollToRight()
{
if ( CanScrollH() )
{
UpdateScrollBars();
m_HorizontalScrollBar->ScrollToRight();
}
}
void ScrollControl::Clear()
{
m_InnerPanel->RemoveAllChildren();
}