Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
241 lines
5.1 KiB
C++
241 lines
5.1 KiB
C++
/*
|
|
GWEN
|
|
Copyright (c) 2010 Facepunch Studios
|
|
See license in Gwen.h
|
|
*/
|
|
|
|
#include "Gwen/Gwen.h"
|
|
#include "Gwen/Skin.h"
|
|
#include "Gwen/Controls/TabControl.h"
|
|
#include "Gwen/Controls/Highlight.h"
|
|
#include "Gwen/DragAndDrop.h"
|
|
#include "Gwen/Controls/WindowControl.h"
|
|
#include "Gwen/Controls/ScrollBarButton.h"
|
|
|
|
namespace Gwen
|
|
{
|
|
namespace Controls
|
|
{
|
|
class TabControlInner : public Base
|
|
{
|
|
public:
|
|
GWEN_CONTROL_INLINE(TabControlInner, Base)
|
|
{
|
|
m_ButtonRect = Gwen::Rect(0, 0, 0, 0);
|
|
}
|
|
|
|
void Render(Skin::Base* skin)
|
|
{
|
|
skin->DrawTabControl(this, m_ButtonRect);
|
|
}
|
|
|
|
void UpdateCurrentButton(Gwen::Rect rct)
|
|
{
|
|
m_ButtonRect = rct;
|
|
}
|
|
|
|
Gwen::Rect m_ButtonRect;
|
|
};
|
|
}; // namespace Controls
|
|
}; // namespace Gwen
|
|
|
|
using namespace Gwen;
|
|
using namespace Gwen::Controls;
|
|
|
|
GWEN_CONTROL_CONSTRUCTOR(TabControl)
|
|
{
|
|
m_iScrollOffset = 0;
|
|
|
|
m_pCurrentButton = NULL;
|
|
|
|
m_TabStrip = new TabStrip(this);
|
|
m_TabStrip->Dock(Pos::Top);
|
|
m_TabStrip->SetWidth(100);
|
|
m_TabStrip->SetHeight(20);
|
|
|
|
// Make this some special control?
|
|
m_pScroll[0] = new ControlsInternal::ScrollBarButton(this);
|
|
m_pScroll[0]->SetDirectionLeft();
|
|
m_pScroll[0]->onPress.Add(this, &TabControl::ScrollPressLeft);
|
|
m_pScroll[0]->SetSize(14, 16);
|
|
|
|
m_pScroll[1] = new ControlsInternal::ScrollBarButton(this);
|
|
m_pScroll[1]->SetDirectionRight();
|
|
m_pScroll[1]->onPress.Add(this, &TabControl::ScrollPressRight);
|
|
m_pScroll[1]->SetSize(14, 16);
|
|
|
|
m_InnerPanel = new TabControlInner(this);
|
|
m_InnerPanel->Dock(Pos::Fill);
|
|
|
|
SetTabable(false);
|
|
}
|
|
|
|
TabButton* TabControl::AddPage(const UnicodeString& strText, Controls::Base* pPage)
|
|
{
|
|
if (!pPage)
|
|
{
|
|
pPage = new Base(this);
|
|
}
|
|
else
|
|
{
|
|
pPage->SetParent(this);
|
|
}
|
|
|
|
TabButton* pButton = new TabButton(m_TabStrip);
|
|
pButton->SetText(strText);
|
|
pButton->SetPage(pPage);
|
|
pButton->SetTabable(false);
|
|
|
|
AddPage(pButton);
|
|
return pButton;
|
|
}
|
|
|
|
void TabControl::AddPage(TabButton* pButton)
|
|
{
|
|
Base* pPage = pButton->GetPage();
|
|
pPage->SetParent(this);
|
|
pPage->SetHidden(true);
|
|
pPage->SetMargin(Margin(6, 6, 6, 6));
|
|
pPage->Dock(Pos::Fill);
|
|
|
|
pButton->SetParent(m_TabStrip);
|
|
pButton->Dock(Pos::Left);
|
|
pButton->SizeToContents();
|
|
if (pButton->GetTabControl()) pButton->onPress.RemoveHandler(pButton->GetTabControl());
|
|
pButton->SetTabControl(this);
|
|
pButton->onPress.Add(this, &TabControl::OnTabPressed);
|
|
|
|
if (!m_pCurrentButton)
|
|
{
|
|
pButton->OnPress();
|
|
}
|
|
|
|
onAddTab.Call(this);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
void TabControl::OnTabPressed(Controls::Base* control)
|
|
{
|
|
if (!control)
|
|
return;
|
|
|
|
TabButton* pButton = control->DynamicCastTabButton();
|
|
if (!pButton) return;
|
|
|
|
Base* pPage = pButton->GetPage();
|
|
if (!pPage) return;
|
|
|
|
if (m_pCurrentButton == pButton)
|
|
return;
|
|
|
|
if (m_pCurrentButton)
|
|
{
|
|
Base* pPage = m_pCurrentButton->GetPage();
|
|
if (pPage)
|
|
{
|
|
pPage->SetHidden(true);
|
|
}
|
|
m_pCurrentButton = NULL;
|
|
}
|
|
|
|
m_pCurrentButton = pButton;
|
|
|
|
pPage->SetHidden(false);
|
|
|
|
m_TabStrip->Invalidate();
|
|
Invalidate();
|
|
}
|
|
|
|
void TabControl::PostLayout(Skin::Base* skin)
|
|
{
|
|
BaseClass::PostLayout(skin);
|
|
|
|
HandleOverflow();
|
|
|
|
if (m_TabStrip->Hidden())
|
|
{
|
|
m_InnerPanel->DynamicCastTabControlInner()->UpdateCurrentButton(Gwen::Rect(0, 0, 0, 0));
|
|
}
|
|
else if (m_pCurrentButton)
|
|
{
|
|
Gwen::Rect rct;
|
|
|
|
Gwen::Point p = m_pCurrentButton->LocalPosToCanvas(Gwen::Point(0, 0));
|
|
p = m_InnerPanel->CanvasPosToLocal(p);
|
|
|
|
rct = Gwen::Rect(p.x + 1, p.y + 1, m_pCurrentButton->Width() - 2, m_pCurrentButton->Height() - 2);
|
|
m_InnerPanel->DynamicCastTabControlInner()->UpdateCurrentButton(rct);
|
|
}
|
|
}
|
|
|
|
void TabControl::OnLoseTab(TabButton* pButton)
|
|
{
|
|
if (m_pCurrentButton == pButton)
|
|
m_pCurrentButton = NULL;
|
|
|
|
//TODO: Select a tab if any exist.
|
|
|
|
onLoseTab.Call(this);
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
int TabControl::TabCount(void)
|
|
{
|
|
return m_TabStrip->NumChildren();
|
|
}
|
|
|
|
void TabControl::SetTabStripPosition(int iDock)
|
|
{
|
|
m_TabStrip->SetTabPosition(iDock);
|
|
}
|
|
|
|
bool TabControl::DoesAllowDrag()
|
|
{
|
|
return m_TabStrip->AllowsTabReorder();
|
|
}
|
|
|
|
void TabControl::HandleOverflow()
|
|
{
|
|
Gwen::Point TabsSize = m_TabStrip->ChildrenSize();
|
|
|
|
// Only enable the scrollers if the tabs are at the top.
|
|
// This is a limitation we should explore.
|
|
// Really TabControl should have derivitives for tabs placed elsewhere where we could specialize
|
|
// some functions like this for each direction.
|
|
bool bNeeded = TabsSize.x > Width() && m_TabStrip->GetDock() == Pos::Top;
|
|
|
|
m_pScroll[0]->SetHidden(!bNeeded);
|
|
m_pScroll[1]->SetHidden(!bNeeded);
|
|
|
|
if (!bNeeded) return;
|
|
|
|
m_iScrollOffset = Gwen::Clamp(m_iScrollOffset, 0, TabsSize.x - Width() + 32);
|
|
|
|
#if 0
|
|
//
|
|
// This isn't frame rate independent.
|
|
// Could be better. Get rid of m_iScrollOffset and just use m_TabStrip->GetMargin().left ?
|
|
// Then get a margin animation type and do it properly!
|
|
// TODO!
|
|
//
|
|
m_TabStrip->SetMargin( Margin( Gwen::Approach( m_TabStrip->GetMargin().left, m_iScrollOffset * -1, 2 ), 0, 0, 0 ) );
|
|
InvalidateParent();
|
|
#else
|
|
m_TabStrip->SetMargin(Margin(m_iScrollOffset * -1, 0, 0, 0));
|
|
#endif
|
|
|
|
m_pScroll[0]->SetPos(Width() - 30, 5);
|
|
m_pScroll[1]->SetPos(m_pScroll[0]->Right(), 5);
|
|
}
|
|
|
|
void TabControl::ScrollPressLeft(Base* pFrom)
|
|
{
|
|
m_iScrollOffset -= 120;
|
|
}
|
|
|
|
void TabControl::ScrollPressRight(Base* pFrom)
|
|
{
|
|
m_iScrollOffset += 120;
|
|
} |