mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-16 06:30:05 +00:00
343 lines
7.6 KiB
C++
343 lines
7.6 KiB
C++
/*
|
|
GWEN
|
|
Copyright (c) 2010 Facepunch Studios
|
|
See license in Gwen.h
|
|
*/
|
|
|
|
|
|
#include "Gwen/Gwen.h"
|
|
#include "Gwen/Skin.h"
|
|
#include "Gwen/Controls/DockBase.h"
|
|
#include "Gwen/Controls/DockedTabControl.h"
|
|
#include "Gwen/Controls/Highlight.h"
|
|
#include "Gwen/DragAndDrop.h"
|
|
#include "Gwen/Controls/Resizer.h"
|
|
|
|
using namespace Gwen;
|
|
using namespace Gwen::Controls;
|
|
|
|
|
|
GWEN_CONTROL_CONSTRUCTOR( DockBase )
|
|
{
|
|
SetPadding( Padding( 1, 1, 1, 1 ) );
|
|
SetSize( 200, 200 );
|
|
|
|
m_DockedTabControl = NULL;
|
|
m_Left = NULL;
|
|
m_Right = NULL;
|
|
m_Top = NULL;
|
|
m_Bottom = NULL;
|
|
|
|
m_bDrawHover = false;
|
|
}
|
|
|
|
TabControl* DockBase::GetTabControl()
|
|
{
|
|
return m_DockedTabControl;
|
|
}
|
|
|
|
void DockBase::SetupChildDock( int iPos )
|
|
{
|
|
if ( !m_DockedTabControl )
|
|
{
|
|
m_DockedTabControl = new DockedTabControl( this );
|
|
m_DockedTabControl->onLoseTab.Add( this, &DockBase::OnTabRemoved );
|
|
m_DockedTabControl->SetTabStripPosition( Pos::Bottom );
|
|
m_DockedTabControl->SetShowTitlebar( true );
|
|
}
|
|
|
|
Dock( iPos );
|
|
|
|
int iSizeDirection = Pos::Left;
|
|
if ( iPos == Pos::Left ) iSizeDirection = Pos::Right;
|
|
if ( iPos == Pos::Top ) iSizeDirection = Pos::Bottom;
|
|
if ( iPos == Pos::Bottom ) iSizeDirection = Pos::Top;
|
|
|
|
ControlsInternal::Resizer* sizer = new ControlsInternal::Resizer( this );
|
|
sizer->Dock( iSizeDirection );
|
|
sizer->SetResizeDir( iSizeDirection );
|
|
sizer->SetSize( 2, 2 );
|
|
sizer->SetTarget( this );
|
|
}
|
|
|
|
void DockBase::Render( Skin::Base* /*skin*/ )
|
|
{
|
|
//Gwen::Render->SetDrawColor( Colors::Black );
|
|
//Gwen::Render->DrawLinedRect( GetRenderBounds() );
|
|
}
|
|
|
|
DockBase** DockBase::GetChildDockPtr( int iPos )
|
|
{
|
|
if ( iPos == Pos::Left ) return &m_Left;
|
|
if ( iPos == Pos::Right ) return &m_Right;
|
|
if ( iPos == Pos::Top ) return &m_Top;
|
|
if ( iPos == Pos::Bottom ) return &m_Bottom;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DockBase* DockBase::GetChildDock( int iPos )
|
|
{
|
|
DockBase** pDock = GetChildDockPtr( iPos );
|
|
|
|
if ( !(*pDock) )
|
|
{
|
|
(*pDock) = new DockBase( this );
|
|
(*pDock)->SetupChildDock( iPos );
|
|
}
|
|
else
|
|
{
|
|
(*pDock)->SetHidden( false );
|
|
}
|
|
|
|
return *pDock;
|
|
}
|
|
|
|
int DockBase::GetDroppedTabDirection( int x, int y )
|
|
{
|
|
int w = Width();
|
|
int h = Height();
|
|
|
|
float top = (float)y / (float) h;
|
|
float left = (float)x / (float) w;
|
|
float right = (float)(w - x) /(float) w;
|
|
float bottom = (float)(h - y) / (float) h;
|
|
|
|
float minimum = GwenUtil_Min( GwenUtil_Min( GwenUtil_Min( top, left ), right ), bottom );
|
|
m_bDropFar = ( minimum < 0.2f );
|
|
if ( minimum > 0.3 ) return Pos::Fill;
|
|
|
|
if ( top == minimum && (!m_Top || m_Top->Hidden()) ) return Pos::Top;
|
|
if ( left == minimum && (!m_Left || m_Left->Hidden()) ) return Pos::Left;
|
|
if ( right == minimum && (!m_Right || m_Right->Hidden()) ) return Pos::Right;
|
|
if ( bottom == minimum && (!m_Bottom || m_Bottom->Hidden()) ) return Pos::Bottom;
|
|
|
|
return Pos::Fill;
|
|
}
|
|
|
|
bool DockBase::DragAndDrop_CanAcceptPackage( Gwen::DragAndDrop::Package* pPackage )
|
|
{
|
|
// A TAB button dropped
|
|
if ( pPackage->name == "TabButtonMove" )
|
|
return true;
|
|
|
|
// a TAB window dropped
|
|
if ( pPackage->name == "TabWindowMove" )
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void AddTabToDock( TabButton* pTabButton, DockedTabControl* pControl )
|
|
{
|
|
pControl->AddPage( pTabButton );
|
|
}
|
|
|
|
bool DockBase::DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* pPackage, int x, int y )
|
|
{
|
|
Gwen::Point pPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
|
int dir = GetDroppedTabDirection( pPos.x, pPos.y );
|
|
|
|
DockedTabControl* pAddTo = m_DockedTabControl;
|
|
if ( dir == Pos::Fill && pAddTo == NULL ) return false;
|
|
|
|
if ( dir != Pos::Fill )
|
|
{
|
|
DockBase* pDock = GetChildDock( dir );
|
|
pAddTo = pDock->m_DockedTabControl;
|
|
|
|
if ( !m_bDropFar ) pDock->BringToFront();
|
|
else pDock->SendToBack();
|
|
}
|
|
|
|
if ( pPackage->name == "TabButtonMove" )
|
|
{
|
|
TabButton* pTabButton = DragAndDrop::SourceControl->DynamicCastTabButton();
|
|
if ( !pTabButton ) return false;
|
|
|
|
AddTabToDock( pTabButton, pAddTo );
|
|
}
|
|
|
|
if ( pPackage->name == "TabWindowMove" )
|
|
{
|
|
DockedTabControl* pTabControl = DragAndDrop::SourceControl->DynamicCastDockedTabControl();
|
|
if ( !pTabControl ) return false;
|
|
if ( pTabControl == pAddTo ) return false;
|
|
|
|
pTabControl->MoveTabsTo( pAddTo );
|
|
}
|
|
|
|
Invalidate();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool DockBase::IsEmpty()
|
|
{
|
|
if ( m_DockedTabControl && m_DockedTabControl->TabCount() > 0 ) return false;
|
|
|
|
if ( m_Left && !m_Left->IsEmpty() ) return false;
|
|
if ( m_Right && !m_Right->IsEmpty() ) return false;
|
|
if ( m_Top && !m_Top->IsEmpty() ) return false;
|
|
if ( m_Bottom && !m_Bottom->IsEmpty() ) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void DockBase::OnTabRemoved( Gwen::Controls::Base* /*pControl*/ )
|
|
{
|
|
DoRedundancyCheck();
|
|
DoConsolidateCheck();
|
|
}
|
|
|
|
void DockBase::DoRedundancyCheck()
|
|
{
|
|
if ( !IsEmpty() ) return;
|
|
|
|
DockBase* pDockParent = GetParent()->DynamicCastDockBase();
|
|
if ( !pDockParent ) return;
|
|
|
|
pDockParent->OnRedundantChildDock( this );
|
|
}
|
|
|
|
void DockBase::DoConsolidateCheck()
|
|
{
|
|
if ( IsEmpty() ) return;
|
|
if ( !m_DockedTabControl ) return;
|
|
if ( m_DockedTabControl->TabCount() > 0 ) return;
|
|
|
|
if ( m_Bottom && !m_Bottom->IsEmpty() )
|
|
{
|
|
m_Bottom->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
|
return;
|
|
}
|
|
|
|
if ( m_Top && !m_Top->IsEmpty() )
|
|
{
|
|
m_Top->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
|
return;
|
|
}
|
|
|
|
if ( m_Left && !m_Left->IsEmpty() )
|
|
{
|
|
m_Left->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
|
return;
|
|
}
|
|
|
|
if ( m_Right && !m_Right->IsEmpty() )
|
|
{
|
|
m_Right->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
|
|
return;
|
|
}
|
|
}
|
|
|
|
void DockBase::OnRedundantChildDock( DockBase* pDockBase )
|
|
{
|
|
pDockBase->SetHidden( true );
|
|
DoRedundancyCheck();
|
|
DoConsolidateCheck();
|
|
}
|
|
|
|
void DockBase::DragAndDrop_HoverEnter( Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/ )
|
|
{
|
|
m_bDrawHover = true;
|
|
}
|
|
|
|
void DockBase::DragAndDrop_HoverLeave( Gwen::DragAndDrop::Package* /*pPackage*/ )
|
|
{
|
|
m_bDrawHover = false;
|
|
}
|
|
|
|
void DockBase::DragAndDrop_Hover( Gwen::DragAndDrop::Package* /*pPackage*/, int x, int y )
|
|
{
|
|
Gwen::Point pPos = CanvasPosToLocal( Gwen::Point( x, y ) );
|
|
int dir = GetDroppedTabDirection( pPos.x, pPos.y );
|
|
|
|
if ( dir == Pos::Fill )
|
|
{
|
|
if ( !m_DockedTabControl )
|
|
{
|
|
m_HoverRect = Gwen::Rect( 0, 0, 0, 0 );
|
|
return;
|
|
}
|
|
|
|
m_HoverRect = GetInnerBounds();
|
|
return;
|
|
}
|
|
|
|
m_HoverRect = GetRenderBounds();
|
|
|
|
int HelpBarWidth = 0;
|
|
|
|
if ( dir == Pos::Left )
|
|
{
|
|
HelpBarWidth = m_HoverRect.w * 0.25f;
|
|
m_HoverRect.w = HelpBarWidth;
|
|
}
|
|
|
|
if ( dir == Pos::Right )
|
|
{
|
|
HelpBarWidth = m_HoverRect.w * 0.25f;
|
|
m_HoverRect.x = m_HoverRect.w - HelpBarWidth;
|
|
m_HoverRect.w = HelpBarWidth;
|
|
}
|
|
|
|
if ( dir == Pos::Top )
|
|
{
|
|
HelpBarWidth = m_HoverRect.h * 0.25f;
|
|
m_HoverRect.h = HelpBarWidth;
|
|
}
|
|
|
|
if ( dir == Pos::Bottom )
|
|
{
|
|
HelpBarWidth = m_HoverRect.h * 0.25f;
|
|
m_HoverRect.y = m_HoverRect.h - HelpBarWidth;
|
|
m_HoverRect.h = HelpBarWidth;
|
|
}
|
|
|
|
if ( (dir == Pos::Top || dir == Pos::Bottom ) && !m_bDropFar )
|
|
{
|
|
if ( m_Left && m_Left->Visible() )
|
|
{
|
|
m_HoverRect.x += m_Left->Width();
|
|
m_HoverRect.w -= m_Left->Width();
|
|
}
|
|
|
|
if ( m_Right && m_Right->Visible() )
|
|
{
|
|
m_HoverRect.w -= m_Right->Width();
|
|
}
|
|
}
|
|
|
|
if ( (dir == Pos::Left || dir == Pos::Right ) && !m_bDropFar )
|
|
{
|
|
if ( m_Top && m_Top->Visible() )
|
|
{
|
|
m_HoverRect.y += m_Top->Height();
|
|
m_HoverRect.h -= m_Top->Height();
|
|
}
|
|
|
|
if ( m_Bottom && m_Bottom->Visible() )
|
|
{
|
|
m_HoverRect.h -= m_Bottom->Height();
|
|
}
|
|
}
|
|
}
|
|
|
|
void DockBase::RenderOver( Skin::Base* skin )
|
|
{
|
|
if ( !m_bDrawHover ) return;
|
|
|
|
Gwen::Renderer::Base* render = skin->GetRender();
|
|
|
|
render->SetDrawColor( Gwen::Color( 255, 100, 255, 20 ) );
|
|
render->DrawFilledRect( GetRenderBounds() );
|
|
|
|
if ( m_HoverRect.w == 0 ) return;
|
|
|
|
render->SetDrawColor( Gwen::Color( 255, 100, 255, 100 ) );
|
|
render->DrawFilledRect( m_HoverRect );
|
|
|
|
render->SetDrawColor( Gwen::Color( 255, 100, 255, 200 ) );
|
|
render->DrawLinedRect( m_HoverRect );
|
|
} |