//------------------------------------------------------------------------------
// $Workfile: DesignViewController.cpp $
// $Header: /SbjDev/SbjCore/DesignViewController.cpp 10 11/12/08 2:22p Steve $
//
// Copyright � 2008 SbjCat
// All rights reserved.
//
//
// *** Authors ***
// Steve Johnson
//
// $Revision: 10 $
//
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "Resource.h"
#include "DesignViewController.h"
#include "DesignViewItem.h"
#include "DesignViewDrawAction.h"
#include "DesignViewDrawActionHandler.h"
#include "DesignViewInsertActionHandler.h"
#include "ModelController.h"
#include "DocEvents.h"
#include "ModelEvents.h"
#include "WndMsgHandler.h"
#include "GDIUtils.h"
#include "RectTracker.h"
#include "MultiRectTracker.h"
#include "MultiRectTrackerEvents.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
namespace localNS
{
// Event Handlers ////////////////////////////////////////////////////////
class FileOpenEventHandler : public SbjCore::EventMgr::EventHandler
{
SbjCore::Mvc::DesignView::Controller* pTheCtrlr;
public:
FileOpenEventHandler() :
SbjCore::EventMgr::EventHandler(SbjCore::Mvc::Doc::Events::EVID_FILE_OPEN),
pTheCtrlr(NULL)
{
}
virtual ~FileOpenEventHandler()
{
}
void Init(SbjCore::Mvc::DesignView::Controller* p)
{
pTheCtrlr = p;
}
private:
virtual void OnHandle(SbjCore::EventMgr::Event* pEvent)
{
ASSERT(pTheCtrlr != NULL);
if (pTheCtrlr != NULL)
{
SbjCore::Mvc::Doc::Events::FileOpen* pTheEvent = dynamic_cast<SbjCore::Mvc::Doc::Events::FileOpen*>(pEvent);
const SbjCore::Mvc::Model::Controller* pModelCtrlr = pTheEvent->pCtrlr;
pTheCtrlr->LoadDesign(pModelCtrlr, pTheEvent->hItemRoot);
}
}
};
/////////////////////////////////////////////////////////////////////////
class DocModifiedEventHandler : public SbjCore::EventMgr::EventHandler
{
CView* pView;
public:
DocModifiedEventHandler() :
SbjCore::EventMgr::EventHandler(SbjCore::Mvc::Doc::Events::EVID_DOC_MODIFIED),
pView(NULL)
{
}
void SetView(CView* p)
{
pView = p;
}
private:
virtual void OnHandle(SbjCore::EventMgr::Event* pEvent)
{
SbjCore::EventMgr::Event* pTheEvent = dynamic_cast<SbjCore::EventMgr::Event*>(pEvent);
ASSERT(pTheEvent != NULL);
if (pTheEvent != NULL)
{
pView->Invalidate();
}
}
};
/////////////////////////////////////////////////////////////////////////
class RemoveSelectedEventHandler : public SbjCore::EventMgr::EventHandler
{
SbjCore::Mvc::DesignView::Controller* pTheCtrlr;
public:
RemoveSelectedEventHandler() :
SbjCore::EventMgr::EventHandler(SbjCore::Mvc::Model::Events::EVID_ITEM_REMOVED)
{
}
void SetCtrlr(SbjCore::Mvc::DesignView::Controller* pCtrlr)
{
pTheCtrlr = pCtrlr;
}
private:
virtual void OnHandle(SbjCore::EventMgr::Event* pEvent)
{
ASSERT(pTheCtrlr != NULL);
SbjCore::Mvc::Model::Events::ItemRemove* pTheEvent = dynamic_cast<SbjCore::Mvc::Model::Events::ItemRemove*>(pEvent);
ASSERT(pTheEvent != NULL);
if (pTheEvent != NULL)
{
SbjCore::Mvc::DesignView::Item* pItem = pTheCtrlr->GetItem(pTheEvent->hItem);
if (pItem != NULL)
{
pTheCtrlr->DeleteItem(pItem);
}
((CView*)pTheCtrlr->GetWnd())->Invalidate();
}
}
};
class InsertItemEventHandler : public SbjCore::EventMgr::EventHandler
{
SbjCore::Mvc::DesignView::Controller* pTheCtrlr;
public:
InsertItemEventHandler() :
SbjCore::EventMgr::EventHandler(SbjCore::Mvc::Model::Events::EVID_ITEM_INSERTED),
pTheCtrlr(NULL)
{
}
void Init(SbjCore::Mvc::DesignView::Controller* p)
{
pTheCtrlr = p;
}
private:
virtual void OnHandle(SbjCore::EventMgr::Event* pEvent)
{
ASSERT(pTheCtrlr != NULL);
if (pTheCtrlr != NULL)
{
SbjCore::Mvc::Model::Events::ItemInsert* pTheEvent = dynamic_cast<SbjCore::Mvc::Model::Events::ItemInsert*>(pEvent);
const SbjCore::Mvc::Model::Controller* pModelCtrlr = pTheEvent->pCtrlr;
pTheCtrlr->InsertDesign(pModelCtrlr, pTheEvent->hChild, pTheEvent->hAfter);
}
}
};
/////////////////////////////////////////////////////////////////////////
class SelCountChangedEventHandler : public SbjCore::EventMgr::EventHandler
{
SbjCore::Mvc::DesignView::Controller* pTheCtrlr;
public:
SelCountChangedEventHandler() :
SbjCore::EventMgr::EventHandler(SbjCore::Mvc::MTE::EVID_SELCOUNT_CHANGED),
pTheCtrlr(NULL)
{
}
void Init(SbjCore::Mvc::DesignView::Controller* p)
{
pTheCtrlr = p;
}
private:
virtual void OnHandle(SbjCore::EventMgr::Event* pEvent)
{
ASSERT(pTheCtrlr != NULL);
if (pTheCtrlr != NULL)
{
SbjCore::Mvc::MTE::SelCountChangedEvent* pTheEvent = dynamic_cast<SbjCore::Mvc::MTE::SelCountChangedEvent*>(pEvent);
ASSERT(pTheEvent != NULL);
if (pTheEvent != NULL)
{
SbjCore::Mvc::MultiRectTracker* pTracker = dynamic_cast<SbjCore::Mvc::MultiRectTracker*>(pTheEvent->GetData());
if (pTracker != NULL)
{
SbjCore::Mvc::MultiRectTracker::t_RectTrackers rts;
int nCount = pTracker->GetSelectedRectTrackers(rts);
if (nCount > 0)
{
SbjCore::Mvc::Model::ItemHandles selItems;
for (SbjCore::Mvc::MultiRectTracker::t_RectTrackers::iterator iter = rts.begin(); iter != rts.end(); iter++)
{
SbjCore::Mvc::RectTracker* p = dynamic_cast<SbjCore::Mvc::RectTracker*>(*iter);
selItems.push_back(p->GetModelItemHandle());
}
SbjCore::Mvc::Model::Controller* pModelCtrlr = SbjCore::Mvc::Model::GetCurController();
pModelCtrlr->SetSelectedItems(selItems);
}
}
}
}
}
};
/////////////////////////////////////////////////////////////////////////////////////
class ItemChangedEventHandler : public SbjCore::EventMgr::EventHandler
{
SbjCore::Mvc::DesignView::Controller* pTheCtrlr;
public:
ItemChangedEventHandler() :
SbjCore::EventMgr::EventHandler(SbjCore::Mvc::Model::Events::EVID_ITEM_CHANGED),
pTheCtrlr(NULL)
{
}
void Init(SbjCore::Mvc::DesignView::Controller* p)
{
pTheCtrlr = p;
}
private:
virtual void OnHandle(SbjCore::EventMgr::Event* pEvent)
{
ASSERT(pTheCtrlr != NULL);
if (pTheCtrlr != NULL)
{
SbjCore::Mvc::Model::Events::ItemChange* pTheEvent = dynamic_cast<SbjCore::Mvc::Model::Events::ItemChange*>(pEvent);
ASSERT(pTheEvent != NULL);
if (pTheEvent != NULL)
{
SbjCore::Mvc::DesignView::Item* pItem = pTheCtrlr->GetItem(pTheEvent->hItem);
SbjCore::Mvc::RectTracker* pTracker = pItem->GetRectTracker();
if (pTracker != NULL)
{
pTracker->Update();
}
}
}
}
};
// Message Handlers /////////////////////////////////////////////////////////////////////
class OnCreateHandler : public SbjCore::Mvc::WndMsgHandler
{
CALL_DEFAULT_FIRST()
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
wParam;
lParam;
*pResult = 0;
LRESULT lRslt = -1;
SbjCore::Mvc::Controller* p = GetController();
if (p != NULL)
{
p->Initialize();
lRslt = 0;
}
return lRslt;
}
};
class OnEraseBkgndHandler : public SbjCore::Mvc::WndMsgHandler
{
// CALL_DEFAULT_FIRST() // comment out to handle message before default
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
wParam;
lParam;
*pResult = 0;
LRESULT lRslt = 1;
return lRslt;
}
};
class LButtonDownMsgHandler : public SbjCore::Mvc::WndMsgHandler
{
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
pResult;
UINT nFlags = (UINT)wParam;
CPoint pt = CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
SbjCore::Mvc::DesignView::Controller* pTheCtrlr = dynamic_cast<SbjCore::Mvc::DesignView::Controller*>(GetController());
if (pTheCtrlr != NULL)
{
pTheCtrlr->GetTracker()->Track(pt, nFlags);
}
return 0;
}
};
class RButtonDownMsgHandler : public SbjCore::Mvc::WndMsgHandler
{
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
wParam;
pResult;
CPoint pt = CPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
SbjCore::Mvc::DesignView::Controller* pTheCtrlr = dynamic_cast<SbjCore::Mvc::DesignView::Controller*>(GetController());
if (pTheCtrlr != NULL)
{
// pTheCtrlr->GetTracker()->Track(pt, nFlags);
/*
SbjCore::Mvc::RectTracker* pTheTracker = pTheCtrlr->GetTracker()->GetTrackerFromPoint(pt);
if (pTheTracker != NULL)
{
}
*/
}
return 0;
}
};
class SetCursorMsgHandler : public SbjCore::Mvc::WndMsgHandler
{
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
wParam;
lParam;
pResult;
LRESULT lRslt = 0;
SbjCore::Mvc::DesignView::Controller* pTheCtrlr = dynamic_cast<SbjCore::Mvc::DesignView::Controller*>(GetController());
if (pTheCtrlr != NULL)
{
lRslt = (LRESULT)pTheCtrlr->GetTracker()->SetCursor(LOWORD(lParam), HIWORD(lParam));
}
return lRslt;
}
};
class SetFocusHandler : public SbjCore::Mvc::WndMsgHandler
{
// CALL_DEFAULT_FIRST() // comment out to handle message before default
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
wParam;
lParam;
*pResult = 0;
LRESULT lRslt = 1;
SbjCore::Mvc::WndController* pCtrlr = GetController();
CWnd* pWnd = pCtrlr->GetWnd();
pWnd->Invalidate();
return lRslt;
}
};
class KillFocusHandler : public SbjCore::Mvc::WndMsgHandler
{
// CALL_DEFAULT_FIRST() // comment out to handle message before default
virtual LRESULT OnHandleWndMsg(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
wParam;
lParam;
*pResult = 0;
LRESULT lRslt = 1;
SbjCore::Mvc::DesignView::Controller* pCtrlr = dynamic_cast<SbjCore::Mvc::DesignView::Controller*>(GetController());
SbjCore::Mvc::MultiRectTracker* pTracker = pCtrlr->GetTracker();
pTracker->DeselectAll();
CWnd* pWnd = pCtrlr->GetWnd();
pWnd->Invalidate();
return lRslt;
}
};
}
///////////////////////////////////////////////////////////////////////////////
namespace SbjCore
{
namespace Mvc
{
namespace DesignView
{
struct ControllerImpl
{
SbjCore::Mvc::MultiRectTracker theTracker;
typedef std::map<HANDLE, Item*> HandleToItem;
typedef HandleToItem::iterator HandleToItemIter;
HandleToItem theItems;
typedef std::map<CString, CRuntimeClass*> ItemRTCMap;
typedef ItemRTCMap::iterator ItemRTCMapIter;
ItemRTCMap theItemRTCMap;
localNS::FileOpenEventHandler theFileOpenEventHandler;
localNS::InsertItemEventHandler theInsertItemEventHandler;
localNS::SelCountChangedEventHandler theSelCountChangedEventHandler;
localNS::ItemChangedEventHandler theItemChangedHandler;
localNS::DocModifiedEventHandler theDocModifiedEventHandler;
localNS::RemoveSelectedEventHandler theRemoveSelectedEventHandler;
localNS::OnCreateHandler theOnCreateHandler;
localNS::OnEraseBkgndHandler theOnEraseBkgndHandler;
localNS::LButtonDownMsgHandler theLButtonDownHandler;
localNS::RButtonDownMsgHandler theRButtonDownHandler;
localNS::SetCursorMsgHandler theSetCursorHandler;
localNS::SetFocusHandler theSetFocusHandler;
localNS::KillFocusHandler theKillFocusHandler;
ControllerImpl()
{
}
virtual ~ControllerImpl()
{
DeleteAllItems();
}
void DeleteAllItems()
{
for (HandleToItemIter iter = theItems.begin(); iter != theItems.end(); iter++)
{
Item* pItem = iter->second;
if (pItem != NULL)
{
if (pItem->IsTrackable())
{
theTracker.Remove(pItem->GetRectTracker());
}
delete pItem;
}
}
theItems.clear();
theTracker.RemoveAll();
}
void DeleteItem(Item* pItem)
{
if (pItem != NULL)
{
if (pItem->IsTrackable())
{
theTracker.Remove(pItem->GetRectTracker());
HANDLE hItem = pItem->GetModelItemHandle();
theItems.erase(hItem);
}
delete pItem;
}
}
void OnDraw(Controller* pCtrlr, CDC* pDC)
{
SbjCore::Utils::GDI::CMemDC dc(pDC);
DrawAction theAction(SbjCore::Mvc::Model::GetCurController(), pCtrlr, &dc, NULL, RUNTIME_CLASS(DrawActionHandler));
if (theItems.size() > 0)
{
theAction.Apply(theItems.begin()->first);
theTracker.Draw(&dc);
}
}
SbjCore::Utils::Menu::ItemRange OnPrepareCtxMenu( CMenu& ctxMenu )
{
SbjCore::Utils::Menu::ItemRange menuItems;
SbjCore::Mvc::MultiRectTracker::t_RectTrackers rts;
int nCount = theTracker.GetSelectedRectTrackers(rts);
if (nCount > 0)
{
menuItems.nFirst = (int)ctxMenu.GetMenuItemCount()-1;
menuItems.nLast = menuItems.nFirst;
if (SbjCore::Utils::Menu::InsertSeparator(ctxMenu, menuItems.nLast))
{
menuItems.nLast++;
}
(void)ctxMenu.InsertMenu(menuItems.nLast, MF_BYPOSITION, ID_SBJCORE_CTX_DELETE, _T("Delete Selected"));
}
return menuItems;
}
Item* GetItemFromPoint(const CPoint& pt) const
{
pt;
return NULL;
}
};
/////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(Controller, WndController)
Controller::Controller(void) :
m_pImpl(new ControllerImpl)
{
m_pImpl->theTracker.SetController(this);
AddHandler(WM_CREATE, &m_pImpl->theOnCreateHandler);
AddHandler(WM_ERASEBKGND, &m_pImpl->theOnEraseBkgndHandler);
AddHandler(WM_LBUTTONDOWN, &m_pImpl->theLButtonDownHandler);
AddHandler(WM_RBUTTONDOWN, &m_pImpl->theRButtonDownHandler);
AddHandler(WM_SETCURSOR, &m_pImpl->theSetCursorHandler);
AddHandler(WM_SETFOCUS, &m_pImpl->theSetFocusHandler);
AddHandler(WM_KILLFOCUS, &m_pImpl->theKillFocusHandler);
}
Controller::~Controller(void)
{
try
{
delete m_pImpl;
}
catch(...)
{
ASSERT(FALSE);
}
}
void Controller::OnInitialize()
{
CView* pView = (CView*)GetWnd();
m_pImpl->theDocModifiedEventHandler.SetView(pView);
m_pImpl->theFileOpenEventHandler.Init(this);
m_pImpl->theInsertItemEventHandler.Init(this);
m_pImpl->theSelCountChangedEventHandler.Init(this);
m_pImpl->theItemChangedHandler.Init(this);
m_pImpl->theRemoveSelectedEventHandler.SetCtrlr(this);
}
void Controller::MapItemRTCToModelTypeName(LPCTSTR lpszName, CRuntimeClass* pRTC )
{
m_pImpl->theItemRTCMap[lpszName] = pRTC;
}
Item* Controller::CreateItem(const SbjCore::Mvc::Model::Controller* pModelCtrlr, HANDLE hModelItem )
{
Item* pItem = NULL;
CString sItemType = pModelCtrlr->GetItemTypeName(hModelItem);
if (!sItemType.IsEmpty())
{
CRuntimeClass* pRTC = m_pImpl->theItemRTCMap[sItemType];
if (pRTC != NULL)
{
pItem = dynamic_cast<Item*>(pRTC->CreateObject());
pItem->SetController(this);
pItem->SetModelItemHandle(hModelItem);
m_pImpl->theItems[hModelItem] = pItem;
if (pItem->IsTrackable())
{
m_pImpl->theTracker.Add(pItem->GetRectTracker());
}
}
}
return pItem;
}
void Controller::DeleteAllItems()
{
m_pImpl->DeleteAllItems();
}
void Controller::DeleteItem( Item* pItem )
{
m_pImpl->DeleteItem(pItem);
}
SbjCore::Mvc::MultiRectTracker* Controller::GetTracker() const
{
return &m_pImpl->theTracker;
}
Item* Controller::GetItemFromPoint( const CPoint& pt ) const
{
return m_pImpl->GetItemFromPoint(pt);
}
Item* Controller::GetItem( const HANDLE hItem ) const
{
return m_pImpl->theItems[hItem];
}
void Controller::Draw(CDC* pDC)
{
OnDraw(pDC);
}
void Controller::OnDraw(CDC* pDC)
{
m_pImpl->OnDraw(this, pDC);
}
SbjCore::Utils::Menu::ItemRange Controller::OnPrepareCtxMenu( CMenu& ctxMenu )
{
return m_pImpl->OnPrepareCtxMenu(ctxMenu);
}
void Controller::LoadDesign(const SbjCore::Mvc::Model::Controller* pModelCtrlr, HANDLE hItem )
{
m_pImpl->DeleteAllItems();
InsertDesign(pModelCtrlr, hItem);
}
void Controller::InsertDesign(const SbjCore::Mvc::Model::Controller* pModelCtrlr, HANDLE hItem, HANDLE hAfter /*= NULL*/)
{
hAfter;
Action theAction(pModelCtrlr, this, NULL, RUNTIME_CLASS(InsertActionHandler));
theAction.Apply(hItem);
}
}
}
}
//*** Modification History ***
// $Log: /SbjDev/SbjCore/DesignViewController.cpp $
//
// 10 11/12/08 2:22p Steve
// Finished Generalization of Model v2.0.1
//
// 9 10/26/08 9:19a Steve
//
// 8 10/24/08 9:03a Steve
//
// 7 10/20/08 11:06a Steve
// Removed source parameter from Event and replaced with EventT data
//
// 6 10/16/08 2:41a Steve
// Ready for publishing
//
// 5 10/14/08 1:12p Steve
// Implemented Deletes