|
#include "stdafx.h"
#include "MultiRectTracker.h"
#include "RectTracker.h"
#include "ControlledCmdTargetT.h"
#include "WndController.h"
#include "MultiRectTrackerEvents.h"
namespace localNS
{
typedef std::vector<SbjCore::Mvc::RectTracker*> t_RectTrackerVector;
typedef t_RectTrackerVector::iterator t_RectTrackerVectorIter;
}
namespace SbjCore
{
namespace Mvc
{
struct MultiRectTrackerImpl
{
Mvc::WndController* pTheCtrlr;
MultiRectTracker* pMRT;
std::vector<RectTracker*> theRectTrackers;
int nSelCount;
MultiRectTrackerImpl() :
pTheCtrlr(NULL),
nSelCount(0),
pMRT(NULL)
{
}
MultiRectTrackerImpl(Mvc::WndController* p) :
pTheCtrlr(p)
{
}
virtual ~MultiRectTrackerImpl()
{
}
void Remove(RectTracker* pRectTracker)
{
for (localNS::t_RectTrackerVectorIter iter = theRectTrackers.begin(); iter != theRectTrackers.end(); ++ iter)
{
RectTracker* p = *iter;
if (p == pRectTracker)
{
theRectTrackers.erase(iter);
break;
}
}
if (nSelCount > 0)
{
MTE::SelCountChangedEvent event(MTE::EVID_SELCOUNT_CHANGED, pMRT);
}
nSelCount = 0;
}
void GetBoundingRect(CRect& rectBounding)
{
rectBounding.SetRectEmpty();
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
if (pRect->IsSelected())
{
if (rectBounding.IsRectEmpty())
{
rectBounding.CopyRect(pRect->m_rect);
}
if (pRect->m_rect.left < rectBounding.left)
{
rectBounding.left = pRect->m_rect.left;
}
if (pRect->m_rect.top < rectBounding.top)
{
rectBounding.top = pRect->m_rect.top;
}
if (pRect->m_rect.right > rectBounding.right)
{
rectBounding.right = pRect->m_rect.right;
}
if (pRect->m_rect.bottom > rectBounding.bottom)
{
rectBounding.bottom = pRect->m_rect.bottom;
}
}
}
}
void DeselectAll()
{
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
if (pRect->IsSelected())
{
pRect->SetSelected(false);
}
}
if (nSelCount > 0)
{
MTE::SelCountChangedEvent event(MTE::EVID_SELCOUNT_CHANGED, pMRT);
}
nSelCount = 0;
}
int HitTestRect(RectTracker* pRect, const CPoint& point, UINT nFlags)
{
int nHit = pRect->HitTest(point);
if (nHit != CRectTracker::hitNothing)
{
// this one got hit
if ((nFlags & MK_CONTROL) != 0)
{
if (pRect->IsSelected())
{
pRect->SetSelected(false);
nSelCount--;
}
else
{
pRect->SetSelected(true);
nSelCount++;
}
}
else if ((nFlags & MK_SHIFT) != 0)
{
pRect->SetSelected(true);
nSelCount++;
}
else
{
if (!pRect->IsSelected())
{
DeselectAll();
}
pRect->SetSelected(true);
nSelCount = 1;
if (nHit != CRectTracker::hitMiddle)
{
pRect->Track(pTheCtrlr, point);
}
}
MTE::SelCountChangedEvent event(MTE::EVID_SELCOUNT_CHANGED, pMRT);
}
return nHit;
}
int HitTestRects(const CPoint & point, UINT nFlags)
{
int nHit = CRectTracker::hitNothing;
int nCount = theRectTrackers.size();
for (int nIndex = nCount-1; nIndex >=0; nIndex--)
{
nHit = HitTestRect(theRectTrackers[nIndex], point, nFlags);
if (nHit != CRectTracker::hitNothing)
{
break;
}
}
return nHit;
}
RectTracker* GetTrackerFromPoint( const CPoint& pt )
{
RectTracker* pTheTracker = NULL;
int nHit = CRectTracker::hitNothing;
int nCount = theRectTrackers.size();
for (int nIndex = nCount-1; nIndex >=0; nIndex--)
{
nHit = theRectTrackers[nIndex]->HitTest(pt);
if (nHit != CRectTracker::hitNothing)
{
pTheTracker = theRectTrackers[nIndex];
break;
}
}
return pTheTracker;
}
void OffsetRects(const CPoint& pt)
{
CPoint thePoint = pt;
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
if (pRect->IsSelected())
{
pRect->OffsetRect(pt);
}
}
}
void SelectRects(CRect* pRectBounding)
{
CRect intersectRect;
nSelCount = 0;
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
intersectRect.IntersectRect(pRectBounding, &pRect->m_rect);
if (pRect->m_rect.EqualRect(&intersectRect))
{
pRect->SetSelected(true);
nSelCount++;
}
}
// just send once
MTE::SelCountChangedEvent event(MTE::EVID_SELCOUNT_CHANGED, pMRT);
}
BOOL SetCursor(UINT nHitTest)
{
bool bRslt = false;
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
bRslt = pRect->SetCursor(pTheCtrlr->GetWnd(), nHitTest);
if (bRslt)
{
break;
}
}
return bRslt;
}
void Draw(CDC* pDC)
{
if (pTheCtrlr->GetWnd() == CWnd::GetFocus())
{
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
if (pRect->IsSelected())
{
pRect->Draw(pDC); \
}
}
}
}
int GetSelectedRectTrackers(MultiRectTracker::t_RectTrackers& rts)
{
for (std::vector<RectTracker*>::iterator iter = theRectTrackers.begin(); iter != theRectTrackers.end(); iter++)
{
RectTracker* pRect = *iter;
if (pRect->IsSelected())
{
rts.push_back(pRect);
}
}
return rts.size();
}
};
/////////////////////////////////////////////////////////////////////////////
MultiRectTracker::MultiRectTracker() :
m_pImpl(new MultiRectTrackerImpl())
{
m_pImpl->pMRT = this;
}
MultiRectTracker::MultiRectTracker(SbjCore::Mvc::WndController* pCtrlr) :
m_pImpl(new MultiRectTrackerImpl(pCtrlr))
{
}
MultiRectTracker::~MultiRectTracker()
{
try
{
delete m_pImpl;
}
catch (...)
{
ASSERT(FALSE);
}
}
void MultiRectTracker::SetController(SbjCore::Mvc::WndController* pCtrlr)
{
m_pImpl->pTheCtrlr = pCtrlr;
}
void MultiRectTracker::Add(RectTracker* pRectTracker)
{
m_pImpl->theRectTrackers.push_back(pRectTracker);
}
void MultiRectTracker::Remove(RectTracker* pRectTracker)
{
m_pImpl->Remove(pRectTracker);
}
BOOL MultiRectTracker::Track(const CPoint & point, UINT nFlags , BOOL bTrackRubberBand)
{
bool bRslt = false;
int nHit = m_pImpl->HitTestRects(point, nFlags);
if (nHit == CRectTracker::hitMiddle)
{
CRect rectBounding(0,0,0,0);
m_pImpl->GetBoundingRect(rectBounding);
m_rect.CopyRect(&rectBounding);
bRslt = CRectTracker::Track(m_pImpl->pTheCtrlr->GetWnd(), point);
if (bRslt)
{
CPoint pt(m_rect.left - rectBounding.left, m_rect.top - rectBounding.top);
m_pImpl->OffsetRects(pt);
}
}
else if ((nHit == CRectTracker::hitNothing) && ((nFlags & MK_SHIFT) == 0) && ((nFlags & MK_CONTROL) == 0))
{
// Deselect all the controls
m_pImpl->DeselectAll();
if (bTrackRubberBand)
{
// Start the selection rect
bRslt = TrackRubberBand(m_pImpl->pTheCtrlr->GetWnd(), point);
if (bRslt)
{
m_rect.NormalizeRect();
m_pImpl->SelectRects(&m_rect);
}
}
}
m_pImpl->pTheCtrlr->GetWnd()->Invalidate();
return bRslt;
}
BOOL MultiRectTracker::SetCursor(UINT nHitTest, UINT message)
{
message;
return m_pImpl->SetCursor(nHitTest);
}
void MultiRectTracker::Draw(CDC* pDC)
{
m_pImpl->Draw(pDC);
}
int MultiRectTracker::GetSelectedRectTrackers( t_RectTrackers& rts ) const
{
return m_pImpl->GetSelectedRectTrackers(rts);
}
void MultiRectTracker::DeselectAll()
{
m_pImpl->DeselectAll();
}
RectTracker* MultiRectTracker::GetTrackerFromPoint( const CPoint& pt ) const
{
return m_pImpl->GetTrackerFromPoint(pt);
}
void MultiRectTracker::RemoveAll()
{
m_pImpl->theRectTrackers.clear();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Real name is Steve Johnson. Programming since 1979. Started on a Heathkit Micro with a DEC LSI-11 and UCSD Pascal. Moved to PCs & DOS as soon as Turbo Pascal became available. Did some Assembly, ISR, TSR etc. All this while working for a Manufacturing Co. for 8 years. Had my own solo Co. doing barcode labeling software for 4 years (terrible business man, all I wanted to do was code). Since then working for various software companies. Moved to Windows around the time of 3.1 with Borland C then C++. Then on to VC++ and MFC, and just about anything I could get my hands on or had to learn for my job, and been at it ever since. Of course recently I've been playing with .NET, ASP, C#, WPF etc.