Newer
Older
Import / projects / Gameloft / bne_lib / code / GUI / ViewCtrl.cpp
#include "ViewCtrl.h"
#include "../GameSWF/GameSWFHelper.h"

#include <Utils/DeleteFunctor.h>

#include <CasualCore.h>
#include <algorithm>
#include <functional>
#include <RKFile.h>
#include <RKDevice.h>

ViewCtrl::ViewCtrl()
  : m_bBresentingModalViewCtrl(false)
  , m_parentCtrl(0)
  , m_pFlash(0)
  , m_handle()
  , m_strName("")
{
}

ViewCtrl::ViewCtrl(const gameswf::CharacterHandle& handle)
  : m_bBresentingModalViewCtrl(false)
  , m_parentCtrl(0)
  , m_pFlash(0)
  , m_handle(handle)
  , m_strName("")
{
}

ViewCtrl::ViewCtrl(const string& flashSourceFile)
  : m_bBresentingModalViewCtrl(false)
  , m_parentCtrl(0)
  , m_pFlash(0)
  , m_strName("")
{
  char fileName[128];
  snprintf(fileName, sizeof(fileName), "%s.swf", flashSourceFile.c_str());
  m_strName = flashSourceFile.c_str();
#ifndef GAME_BOT
  m_pFlash = gameswf::load(fileName);
  m_handle = m_pFlash->getRootHandle();
#endif
}

ViewCtrl::~ViewCtrl()
{
  if (m_handle.isValid())
  {
    m_handle.setVisible(false);
  }

  if (m_pFlash)
    gameswf::unload(m_pFlash);

  for_each(m_children.begin(), m_children.end(), DeleteFunctor<ViewCtrl>());
  m_children.clear();
}

void ViewCtrl::AddChildViewCtrl(ViewCtrl * pVC)
{
  if (pVC)
  {
    pVC->SetParentViewCtrl(this);
    pVC->SetVisible(this->m_handle.isVisible());
    m_children.push_back(pVC);
    NotifyFlashOrderChange();
  }
}

void ViewCtrl::RemoveChildViewCtrl(ViewCtrl * pVC)
{
  if (pVC)
  {
    std::vector<ViewCtrl*>::iterator it = find_if(m_children.begin(), m_children.end(), std::bind1st(std::equal_to<ViewCtrl*>(), pVC));
    if (it != m_children.end())
    {
      m_childrenToBeRemoved.push_back(pVC);
    }
  }
}

bool ViewCtrl::PresentModalViewCtrl(ViewCtrl * pVC)
{
  if (pVC && !m_bBresentingModalViewCtrl)
  {
    SetPresentingModalViewCtrl(true);
    pVC->SetParentViewCtrl(this);
    m_children.push_back(pVC);
    NotifyFlashOrderChange();
    Hide();
    return true;
  }
  return false;
}

void ViewCtrl::DismissModalViewCtrl()
{
  RKASSERT(m_parentCtrl, "No parent controller in ViewCtrl::DismissModalViewCtrl");
  if (m_parentCtrl)
  {
    m_parentCtrl->DismissModalViewCtrl(this);
  }
}

void ViewCtrl::Update(float time_elapsed)
{
  TryRemoveChildren();

  for_each(m_children.begin(), m_children.end(), std::bind2nd(std::mem_fun(&ViewCtrl::Update), time_elapsed));
}

void ViewCtrl::SetVisible(bool isVisible)
{
  if (m_handle.isValid())
  {
    m_handle.setVisible(isVisible);
  }
  for_each(m_children.begin(), m_children.end(), std::bind2nd(std::mem_fun(&ViewCtrl::SetVisible), isVisible));
}

void ViewCtrl::Show()
{
  if (m_pFlash != nullptr) {
    m_handle.setVisible(true);
  }
}

void ViewCtrl::Hide()
{
  if (m_pFlash != nullptr) {
    m_handle.setVisible(false);
  }
}

void ViewCtrl::SetEnable(bool isEnabled)
{
  if (m_handle.isValid())
  {
    m_handle.setEnabled(isEnabled);
  }
  for_each(m_children.begin(), m_children.end(), std::bind2nd(std::mem_fun(&ViewCtrl::SetEnable), isEnabled));
}

struct RemoveChild
{
  std::vector<ViewCtrl*>& m_children;
  explicit RemoveChild(std::vector<ViewCtrl*>& children) : m_children(children){}
  void operator()(ViewCtrl* pVC)
  {
    std::vector<ViewCtrl*>& items = m_children;
    std::vector<ViewCtrl*>::iterator it = find_if(items.begin(), items.end(), std::bind1st(std::equal_to<ViewCtrl*>(), pVC));
    if (it != items.end())
    {
      items.erase(it);
      RKDELETE(pVC);
    }
  }
};

void ViewCtrl::TryRemoveChildren()
{
  std::vector<ViewCtrl*>& items = m_childrenToBeRemoved;
  if (items.size() > 0)
  {
    for_each(items.begin(), items.end(), RemoveChild(m_children));

    items.clear();
    NotifyFlashOrderChange();
  }
}

void ViewCtrl::DismissModalViewCtrl(ViewCtrl * pVC)
{
  if (pVC)
  {
    RemoveChildViewCtrl(pVC);
    SetPresentingModalViewCtrl(false);
    Show();
  }
}

void ViewCtrl::SetPresentingModalViewCtrl(bool b)
{
  m_bBresentingModalViewCtrl = b;
  if (m_parentCtrl)
    m_parentCtrl->SetPresentingModalViewCtrl(b);
}

void ViewCtrl::NotifyFlashOrderChange()
{
  if (m_parentCtrl)
  {
    if (m_parentCtrl->m_parentCtrl == this) {
      RKASSERT(false, "ViewCtrl's parent is also its child; breaking to prevent stack overflow");
    }
    else {
      m_parentCtrl->NotifyFlashOrderChange();
    }
  }
  else
  {
    CommitFlashOrderChange();
  }
}

bool ViewCtrl::SetCustomizedOrder(int aOrder)
{
  if (m_pFlash)
  {
    CGAME->GetFlashManager()->SetFlashOrder(m_pFlash, aOrder);
    return true;
  }
  else
  {
    return false;
  }
}

int ViewCtrl::GetCustomizedOrder()
{
  return m_pFlash ? CGAME->GetFlashManager()->GetFlashOrder(m_pFlash) : 0;
}

struct IncreaseOrder
{
  int m_currentOrder;
  IncreaseOrder() { m_currentOrder = 0; }
  explicit IncreaseOrder(int a_startIndex) { m_currentOrder = a_startIndex; }

  void operator()(ViewCtrl* pVC)
  {
    if (pVC->SetCustomizedOrder(m_currentOrder))
      m_currentOrder++;
    pVC->UpdateFlashOrder(*this);
  }
};

void ViewCtrl::CommitFlashOrderChange()
{
  IncreaseOrder increaseOrder(GetCustomizedOrder());
  increaseOrder(this);
}

void ViewCtrl::UpdateFlashOrder(const IncreaseOrder &aIncreaseOrder)
{
  for_each(m_children.begin(), m_children.end(), aIncreaseOrder);
}