You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/Module/GeoSigmaDraw/HSimpleTracker.cpp

247 lines
6.1 KiB
C++

#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);
}