#include "stdafx.h" #include "HSimpleTracker.h" #include "SigmaDoc.h" #include "ScaleMotionGraphDrawer.h" #include "PanMotionGraphDrawer.h" bool GraphItemTransform(Gdiplus::Matrix * pMat, CPositionList & selectionSet, CSigmaDoc * pDoc); //Tracker的状态 //未拖拽状态 //拖拽状态 //未拖拽状态的条件:用户刚选中图元 //拖拽状态: //进入拖拽状态的条件:[鼠标左键单击]且[选择集不空]且[击中Handle],简化为:[鼠标左键单击]且[击中Handle] //退出拖拽状态的条件:[鼠标左键松开]/[鼠标移动]且[未击中Handle] //隐藏状态的条件:[鼠标左键下按或抬起]且[未击中Handle] CHSimpleTracker::CHSimpleTracker() :m_status(HTRACKER_STATUS_HIDE), m_pDoc(NULL), m_motionCount(0), m_transformKind(HTRACKER_TRANSFORM_KIND_SCALE) { m_pScaleMotionGraphDrawer = new ScaleMotionGraphDrawer(); m_pPanMotionGraphDrawer = new PanMotionGraphDrawer(); m_pTMGDrawer = m_pScaleMotionGraphDrawer; } CHSimpleTracker::~CHSimpleTracker() { delete m_pScaleMotionGraphDrawer; m_pScaleMotionGraphDrawer = NULL; delete m_pPanMotionGraphDrawer; m_pPanMotionGraphDrawer = NULL; } bool CHSimpleTracker::Create(CSigmaDoc * pDoc, CRect boundRect) { if (boundRect.IsRectEmpty()) return false; m_boundRect = boundRect; //m_boundRect.SetRectEmpty(); m_pDoc = pDoc; m_motionCount = 0; m_drawer.Reset(); m_transformKind = HTRACKER_TRANSFORM_KIND_SCALE; m_pTMGDrawer = m_pScaleMotionGraphDrawer; m_pTMGDrawer->CopyMatrix(m_trackerTransform.GetMatrix()); m_handleCalctor.Calculate(m_boundRect); return true; } void CHSimpleTracker::LButtonDown(int mouseX, int mouseY) { HTRACKER_HANDLE_KIND handleKind = HitTest(mouseX, mouseY); m_motionCount = 0; if (handleKind == HTRACKER_HANDLE_KIND_INVALID) { m_status = HTRACKER_STATUS_HIDE; return; } m_pTMGDrawer->LButtonDown(mouseX, mouseY); //击中Handle,进入拖拽状态 m_status = HTRACKER_STATUS_DRAGING; CPoint mousePt(mouseX, mouseY); m_trackerTransform.Init((int)handleKind, m_boundRect, mousePt); //缩放或平移变换 m_transformKind = JudgeTransformKind(handleKind); ChangeGraphDrawer(); ChangeHtrackerDrawerState(); } void CHSimpleTracker::MouseMove(CDC * pDC, int mouseX, int mouseY) { if (m_status == HTRACKER_STATUS_HIDE) return; if (m_status == HTRACKER_STATUS_NOT_DRAG) return; CPoint mousePt(mouseX, mouseY); m_trackerTransform.SetKind(this->m_transformKind); m_trackerTransform.Draging(mousePt); //之前处于拖拽状态 //判断退出拖拽状态的条件 //1、鼠标左键处于释放状态 //2、鼠标点不在Handle上 //一旦判断出不在拖拽状态,则说明刚推出拖拽状态 HTRACKER_HANDLE_KIND handleKind = HitTest(mouseX, mouseY); SHORT lbttonStatus = ::GetAsyncKeyState(VK_LBUTTON); if (handleKind == HTRACKER_HANDLE_KIND_INVALID && lbttonStatus == 0) { m_status = HTRACKER_STATUS_NOT_DRAG; //保持未拖拽状态的原因是,程序要继续绘制出tracker. //GraphItemTransform(m_trackerTransform.GetMatrix(), m_selectionSet, m_pDoc); m_trackerTransform.EndDrag(); return; } Draw(pDC); //m_pTMGDrawer->FirstDraw(pDC, m_trackerTransform.GetMatrix(), mouseX, mouseY); //m_motionCount++; //if (m_motionCount == 1) //{ // m_drawer.Draw(pDC, m_boundRect); //擦掉tracker // m_pTMGDrawer->FirstDraw(pDC, m_trackerTransform.GetMatrix(), mouseX, mouseY); //} //else // m_pTMGDrawer->Draw(pDC, m_trackerTransform.GetMatrix(), mouseX, mouseY); } void CHSimpleTracker::LButtonUp(int mouseX, int mouseY, CDC * pDC) { //进入旋转切错状态的条件: //在Handle上先按左键.在鼠标抬起时,鼠标没有移动. HTRACKER_HANDLE_KIND handleKind = HitTest(mouseX, mouseY); if (m_motionCount == 0) { m_transformKind = JudgeTransformKind(handleKind); } ChangeGraphDrawer(); ChangeHtrackerDrawerState(); //***更新tracker的范围 //m_bound.CreateBoundRect(m_pDoc, m_selectionSet, m_boundRect); TranslateBoundRect(m_boundRect); m_trackerTransform.EndDrag(); if (m_motionCount != 0) { m_pTMGDrawer->Erease(pDC); //擦除橡皮框 m_drawer.Draw(pDC, m_boundRect); //再画上Tracker m_handleCalctor.Calculate(m_boundRect); } m_status = HTRACKER_STATUS_NOT_DRAG; m_motionCount = 0; } void CHSimpleTracker::Draw(CDC * pDC) { if (m_boundRect.IsRectEmpty()) return; CRect boundRect; TranslateBoundRect(boundRect); m_drawer.Draw(pDC, boundRect); m_handleCalctor.Calculate(boundRect); } void CHSimpleTracker::Reset() { m_status = HTRACKER_STATUS_HIDE; m_boundRect.SetRectEmpty(); m_handleCalctor.Reset(); m_trackerTransform.EndDrag(); m_motionCount = 0; } HTRACKER_HANDLE_KIND CHSimpleTracker::HitTest(int mouseX, int mouseY) { CPoint point(mouseX, mouseY); int i = -1; for (i = 0; i < 9; i++) { if (m_handleCalctor.GetHandleRect(i).PtInRect(point)) break; } if (i == -1) return HTRACKER_HANDLE_KIND_INVALID; //i的取值范围:[0,8] return HTRACKER_HANDLE_KIND(i); } CRect CHSimpleTracker::GetBoundRect() { return m_boundRect; } void CHSimpleTracker::TranslateBoundRect(CRect & boundRectOut) { //角点与索引的对应关系 // 0----------1 // | | // | | // 3----------2 Gdiplus::Point cornerPts[4]; cornerPts[0].X = cornerPts[3].X = m_boundRect.left; cornerPts[0].Y = cornerPts[1].Y = m_boundRect.top; cornerPts[1].X = cornerPts[2].X = m_boundRect.right; cornerPts[2].Y = cornerPts[3].Y = m_boundRect.bottom; Gdiplus::Matrix * matrix = m_trackerTransform.GetMatrix(); matrix->TransformPoints(cornerPts, 4); boundRectOut.SetRect(cornerPts[0].X, cornerPts[0].Y, cornerPts[2].X, cornerPts[2].Y); } //只有在LButtonDown和LButtonUp中有效 HTRACKER_TRANSFORM_KIND CHSimpleTracker::JudgeTransformKind(HTRACKER_HANDLE_KIND kind) { if (kind == HTRACKER_HANDLE_KIND_INVALID) return HTRACKER_TRANSFORM_KIND_SCALE; if (kind == HTRACKER_HANDLE_KIND_CENTER) return HTRACKER_TRANSFORM_KIND_MOVE; return HTRACKER_TRANSFORM_KIND_SCALE; } void CHSimpleTracker::ChangeGraphDrawer() { switch (m_transformKind) { case HTRACKER_TRANSFORM_KIND_SCALE: m_pTMGDrawer = m_pScaleMotionGraphDrawer; break; case HTRACKER_TRANSFORM_KIND_MOVE: m_pTMGDrawer = m_pPanMotionGraphDrawer; break; default: m_pTMGDrawer = m_pScaleMotionGraphDrawer; } m_pTMGDrawer->CopyMatrix(m_trackerTransform.GetMatrix()); m_pTMGDrawer->SetBoundRect(m_boundRect); } //TODO:直接使用函数内代码.删除此函数. void CHSimpleTracker::ChangeHtrackerDrawerState() { m_drawer.SetRotateAndShearState(false); }