engine/src/GUIManager/GUIManager.cpp
2013-02-05 20:17:58 +00:00

406 lines
9.1 KiB
C++

#include "include/Engine.h"
namespace SE
{
const std::string CONST_HOLD_SIGNAL_NAME = "OnHold";
const std::string CONST_CLICK_SIGNAL_NAME = "OnClick";
const std::string CONST_DRAG_SIGNAL_NAME = "OnDrag";
TGUIManager::~TGUIManager()
{
WidgetTrasfromTaskList.clear();
WidgetArr.clear();
*Console<<"GUI Manager deleting...";
}
void TGUIManager::AddWidget(std::shared_ptr<TInstancingWidgetAncestor> widgetAncestor, const std::string& name, const std::string& groupName, int order)
{
for (TWidgetArr::iterator i = WidgetArr.begin(); i != WidgetArr.end(); i++)
{
if (i->Name == name)
{
return;
}
}
WidgetArr.push_back(TWidgetStruct(name, groupName, widgetAncestor, order));
std::stable_sort(WidgetArr.begin(), WidgetArr.end());
}
void TGUIManager::DeleteWidget(std::string name)
{
for (TWidgetArr::iterator i = WidgetArr.begin(); i != WidgetArr.end(); i++)
{
if (i->Name == name)
{
WidgetArr.erase(i);
return;
}
}
}
void TGUIManager::DeleteWidgetGroup(std::string groupName)
{
bool widgetErased;
for (TWidgetArr::iterator i = WidgetArr.begin(); i != WidgetArr.end();)
{
widgetErased = false;
if (i->GroupName == groupName)
{
i = WidgetArr.erase(i);
widgetErased = true;
}
if (i != WidgetArr.end() & !widgetErased)
{
++i;
}
}
}
void TGUIManager::DeleteWidgetOnUpdate(const std::string& name)
{
PostUpdateSignal.connect(boost::bind(&TGUIManager::DeleteWidget, this, name));
}
void TGUIManager::DeleteWidgetGroupOnUpdate(const std::string& groupName)
{
PostUpdateSignal.connect(boost::bind(&TGUIManager::DeleteWidgetGroup, this, groupName));
}
void TGUIManager::AddWidgetTransformTask(TWidgetTransformTask widgetTransformTask)
{
WidgetTrasfromTaskList.push_back(widgetTransformTask);
}
void TGUIManager::Update(cardinal dt)
{
WidgetListMutex.lock();
for (TWidgetArr::iterator i = WidgetArr.begin(); i != WidgetArr.end(); ++i)
{
i->Widget->Update(dt);
if (i->IsMouseDown)
{
(*(i->SignalMap[CONST_HOLD_SIGNAL_NAME]))(TSignalParam(dt));
}
}
for (TWidgetTrasfromTaskList::iterator i = WidgetTrasfromTaskList.begin(); i != WidgetTrasfromTaskList.end(); )
{
int prevCurrentTime = i->CurrentTime;
i->CurrentTime += dt;
if (i->CurrentTime >= i->TotalTime)
{
i->CurrentTime = i->TotalTime;
}
vec2 oldPos;
vec2 newPos;
float t0 = clamp<float>((prevCurrentTime + 0.f)/i->TotalTime, 0, 1);
float t = clamp<float>((i->CurrentTime + 0.f)/i->TotalTime, 0, 1);
if (i->MoveStyle == TWidgetTransformTask::MS_LINEAR)
{
oldPos = InterpolateLinear<vec2>(vec2(0,0), i->PosTo, t0);
newPos = InterpolateLinear<vec2>(vec2(0,0), i->PosTo, t);
}
if (i->MoveStyle == TWidgetTransformTask::MS_SQR)
{
oldPos = InterpolateSqr<vec2>(vec2(0,0), i->PosTo, t0);
newPos = InterpolateSqr<vec2>(vec2(0,0), i->PosTo, t);
}
if (i->MoveStyle == TWidgetTransformTask::MS_SQRT)
{
oldPos = InterpolateSqrt<vec2>(vec2(0,0), i->PosTo, t0);
newPos = InterpolateSqrt<vec2>(vec2(0,0), i->PosTo, t);
}
vec2 moveDistance = newPos - oldPos;
for (TWidgetArr::iterator j = WidgetArr.begin(); j != WidgetArr.end(); ++j)
{
if (j->GroupName == i->GroupName)
{
MoveWidgetByIterator(j, moveDistance);
}
}
if (i->CurrentTime == i->TotalTime)
{
i = WidgetTrasfromTaskList.erase(i);
}
else
{
++i;
}
}
WidgetListMutex.unlock();
PostUpdateSignal();
PostUpdateSignal.disconnect_all_slots();
}
void TGUIManager::Draw()
{
TWidgetArr::iterator i;
for (i = WidgetArr.begin(); i != WidgetArr.end(); ++i)
{
TRenderPairList::iterator j;
for (j = i->Widget->TriangleListVector.begin(); j != i->Widget->TriangleListVector.end(); ++j)
{
TRenderParamsSetter paramSetter(j->first);
Renderer->DrawTriangleList(j->second);
CheckGlError("TGUIManager::Draw()");
}
}
}
TWidgetArr::iterator TGUIManager::FindWidgetInArr(const std::string& widgetName)
{
TWidgetArr::iterator i;
for (i = WidgetArr.begin(); i != WidgetArr.end(); ++i)
{
if (i->Name == widgetName)
{
break;
}
}
if (i == WidgetArr.end())
{
throw ErrorToLog("ERROR: widget not found: "+widgetName);
}
return i;
}
void TGUIManager::MoveWidgetByIterator(TWidgetArr::iterator widget, vec2 shift)
{
widget->Widget->LeftBottomPos += shift;
std::vector<vec3>::iterator i;
TRenderPairList::iterator itr;
for (itr = widget->Widget->TriangleListVector.begin(); itr != widget->Widget->TriangleListVector.end(); ++itr)
{
std::vector<vec3>& vertexCoordVec = itr->second.Data.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB];
for (i = vertexCoordVec.begin(); i != vertexCoordVec.end(); ++i)
{
*i += vec3(shift, 0);
}
itr->second.RefreshBuffer();
}
}
void TGUIManager::MoveWidget(const std::string& widgetName, vec2 shift)
{
TWidgetArr::iterator widget = FindWidgetInArr(widgetName);
MoveWidgetByIterator(widget, shift);
}
void TGUIManager::MoveWidgetGroup(const std::string& widgetGroupName, const std::string& exceptWidget, vec2 shift)
{
for (TWidgetArr::iterator i = WidgetArr.begin(); i != WidgetArr.end(); ++i)
{
if (i->GroupName == widgetGroupName && i->Name != exceptWidget)
{
MoveWidgetByIterator(i, shift);
}
}
}
void TGUIManager::OnMouseDown(vec2 pos)
{
//Xperimental - need to call widget methods and signals NOT IN "FOR" LOOP
WidgetListMutex.lock();
TWidgetArr::reverse_iterator i;
LastTapPos = pos;
TotalShift = vec2(0,0);
for (i = WidgetArr.rbegin(); i != WidgetArr.rend(); ++i)
{
if (i->Widget->CheckClick(pos))
{
bool isTransparentForInput = i->Widget->IsTransparentForInput();
i->Widget->OnTapDown(pos);
i->IsMouseDown = true;
if (! isTransparentForInput)
{
WidgetListMutex.unlock();
return;
}
}
}
WidgetListMutex.unlock();
}
void TGUIManager::OnMouseUp(vec2 pos)
{
//Xperimental - need to call widget methods and signals NOT IN "FOR" LOOP
WidgetListMutex.lock();
TWidgetArr::reverse_iterator i;
for (i = WidgetArr.rbegin(); i != WidgetArr.rend(); ++i)
{
if (i->Widget->CheckClick(pos))
{
bool isTransparentForInput = i->Widget->IsTransparentForInput();
i->Widget->OnTapUp(pos);
i->IsMouseDown = false;
(*(i->SignalMap[CONST_CLICK_SIGNAL_NAME]))(TSignalParam(pos));
if (! isTransparentForInput)
{
WidgetListMutex.unlock();
return;
}
}
}
WidgetListMutex.unlock();
}
void TGUIManager::OnMove(vec2 shift)
{
//Xperimental - need to call widget methods and signals NOT IN "FOR" LOOP
TWidgetArr::reverse_iterator i;
bool moveIsProcessed = false;
bool moveOutIsProcessed = false;
TotalShift += shift;
for (i = WidgetArr.rbegin(); i != WidgetArr.rend(); ++i)
{
if (!moveIsProcessed && i->Widget->CheckClick(LastTapPos-TotalShift))
{
bool isTransparentForInput = i->Widget->IsTransparentForInput();
i->Widget->OnMove(shift);
(*(i->SignalMap[CONST_DRAG_SIGNAL_NAME]))(TSignalParam(shift));
if (! isTransparentForInput)
{
moveIsProcessed = true;
}
}
}
for (i = WidgetArr.rbegin(); i != WidgetArr.rend(); ++i)
{
if (!moveOutIsProcessed && i->Widget->CheckClick(LastTapPos) && !i->Widget->CheckClick(LastTapPos-TotalShift))
{
bool isTransparentForInput = i->Widget->IsTransparentForInput();
i->Widget->OnMoveOut();
i->IsMouseDown = false;
if (! isTransparentForInput)
{
moveOutIsProcessed = true;
}
}
}
}
void TGUIManager::PrintWidgetList()
{
TWidgetArr::iterator i;
for (i = WidgetArr.begin(); i != WidgetArr.end(); ++i)
{
std::string widgetRow = i->Name + " (" + tostr(i->Widget->LeftBottomPos.v[0]) + ", " + tostr(i->Widget->LeftBottomPos.v[1]) + ")";
Console->PrintImmediate(widgetRow);
}
}
std::shared_ptr<boost::signal<void (TSignalParam)>> TGUIManager::GetOnClickSignal(const std::string& widgetName)
{
TWidgetArr::iterator i = FindWidgetInArr(widgetName);
return i->SignalMap[CONST_CLICK_SIGNAL_NAME];
}
std::shared_ptr<boost::signal<void (TSignalParam)>> TGUIManager::GetOnHoldSignal(const std::string& widgetName)
{
TWidgetArr::iterator i = FindWidgetInArr(widgetName);
return i->SignalMap[CONST_HOLD_SIGNAL_NAME];
}
std::shared_ptr<boost::signal<void (TSignalParam)>> TGUIManager::GetSignal(const std::string& signalName, const std::string& widgetName)
{
TWidgetArr::iterator i = FindWidgetInArr(widgetName);
if (i->SignalMap.count(signalName) == 0)
{
throw ErrorToLog("Illegal signal: "+signalName);
}
return i->SignalMap[signalName];
}
void TGUIManager::SQ_MoveWidget(const SQChar *widgetName, float x, float y)
{
MoveWidget(std::string(widgetName), vec2(x,y));
}
void TGUIManager::BindFunctions()
{
ResourceManager->ScriptManager.AddFunction("pwl",
TScriptInfo("PrintWidgetList"),
ResourceManager->GUIManager,
&TGUIManager::PrintWidgetList);
ResourceManager->ScriptManager.AddFunction("mw",
TScriptInfo("MoveWidget"),
ResourceManager->GUIManager,
&TGUIManager::SQ_MoveWidget);
}
} //namespace SE