⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multirecttracker.cpp

📁 A Model-View-Controller Framework that integrates with the MFC Doc/View architecture.
💻 CPP
字号:
#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();			
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -