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.
270 lines
5.4 KiB
C++
270 lines
5.4 KiB
C++
#include "stdafx.h"
|
|
#include "HandleDrawer.h"
|
|
#include "SigmaDoc.h"
|
|
#include <atltypes.h>
|
|
#include "DrawOperator\CurveEx.h"
|
|
|
|
#define HANDLE_SIZE 8
|
|
#define FOCUS_HANDLE_SIZE 12
|
|
|
|
static void GetXY(CCurveEx* pValue, int nIndex, dfPoint& point);
|
|
static CRect GetHandleRect(long x, long y, bool bFocus);
|
|
|
|
struct HandlePoint
|
|
{
|
|
HandlePoint();
|
|
int index;
|
|
dfPoint ptW; //世界坐标
|
|
CPoint ptS; //屏幕坐标
|
|
bool bDraw;//未绘制 已经绘制了
|
|
};
|
|
|
|
HandlePoint::HandlePoint()
|
|
:index(-1),
|
|
bDraw(false)
|
|
{
|
|
}
|
|
|
|
HandleDrawer::HandleDrawer(CSigmaDoc * pDoc)
|
|
: m_pDoc(pDoc),
|
|
m_focusHandle(0)
|
|
{
|
|
m_colorHandles = RGB(255, 0, 0);
|
|
m_headColor = RGB(82, 255, 59);
|
|
m_focusHandle = new HandlePoint();
|
|
}
|
|
|
|
HandleDrawer::~HandleDrawer()
|
|
{
|
|
Release();
|
|
delete m_focusHandle;
|
|
m_focusHandle = 0;
|
|
}
|
|
|
|
bool HandleDrawer::Init(CCurveEx * pCurve)
|
|
{
|
|
if (pCurve == NULL)
|
|
return false;
|
|
Release();
|
|
m_focusHandle->index = -1;
|
|
|
|
dfPoint pt;
|
|
HandlePoint * handlePt = 0;
|
|
|
|
for (int i = 0; i < pCurve->num; i++)
|
|
{
|
|
//draw handle
|
|
GetXY(pCurve, i, pt);
|
|
|
|
handlePt = new HandlePoint;
|
|
handlePt->index = i;
|
|
handlePt->ptW = pt;
|
|
|
|
//TODO:去掉Handle点中的重复点
|
|
m_handlePts.push_back(handlePt);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void HandleDrawer::ClearAll(CDC * pDC)
|
|
{
|
|
DrawAllOrEreaseAll(pDC, false);
|
|
Release();
|
|
if (m_focusHandle->index != -1)
|
|
{
|
|
DrawOrEreaseOneHandle(pDC, m_focusHandle, false, true); //擦掉focus hanle
|
|
}
|
|
m_focusHandle->index = -1;
|
|
}
|
|
|
|
void HandleDrawer::DrawAll(CDC * pDC)
|
|
{
|
|
DrawAllOrEreaseAll(pDC, true);
|
|
}
|
|
|
|
void HandleDrawer::ReDrawAll(CDC * pDC)
|
|
{
|
|
DrawAllOrEreaseAll(pDC, false);
|
|
DrawAllOrEreaseAll(pDC, true);
|
|
}
|
|
|
|
void HandleDrawer::DrawOneHandle(CDC * pDC, int indexOfHandle)
|
|
{
|
|
if (indexOfHandle < 0 || indexOfHandle >= m_handlePts.size())
|
|
{
|
|
return;
|
|
}
|
|
|
|
DrawOrEreaseOneHandle(pDC, m_handlePts[indexOfHandle], true, false);
|
|
}
|
|
|
|
void HandleDrawer::DrawFocusHandle(CDC * pDC, int indexOfHandle)
|
|
{
|
|
if (indexOfHandle < 0 || indexOfHandle >= m_handlePts.size())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_focusHandle->index == -1) //第一次画 focusHanle
|
|
{
|
|
*m_focusHandle = *m_handlePts[indexOfHandle];
|
|
m_focusHandle->bDraw = false;
|
|
DrawOrEreaseOneHandle(pDC, m_focusHandle, true, true);
|
|
DrawOrEreaseOneHandle(pDC, m_handlePts[indexOfHandle], false, false); //擦去焦点Handle对应普通Handle
|
|
return;
|
|
}
|
|
|
|
if (m_focusHandle->index != indexOfHandle)
|
|
{
|
|
DrawOrEreaseOneHandle(pDC, m_focusHandle, false, true); //擦掉老的节点
|
|
DrawOrEreaseOneHandle(pDC, m_handlePts[indexOfHandle], false, false);
|
|
|
|
*m_focusHandle = *m_handlePts[indexOfHandle];
|
|
m_focusHandle->bDraw = false;
|
|
DrawOrEreaseOneHandle(pDC, m_focusHandle, true, true); //画上新的节点
|
|
return;
|
|
}
|
|
|
|
//是同一个节点
|
|
if (!m_focusHandle->bDraw)
|
|
{
|
|
DrawOrEreaseOneHandle(pDC, m_focusHandle, true, true);
|
|
DrawOrEreaseOneHandle(pDC, m_handlePts[indexOfHandle], false, false);
|
|
}
|
|
}
|
|
|
|
//返回擦除节点的索引
|
|
int HandleDrawer::EreaseFocusHandle(CDC * pDC)
|
|
{
|
|
if (pDC == 0)
|
|
return -1;
|
|
if (m_focusHandle->index == -1)
|
|
return -1;
|
|
|
|
if (m_focusHandle->bDraw)
|
|
{
|
|
DrawOrEreaseOneHandle(pDC, m_focusHandle, false, true);
|
|
}
|
|
int index = m_focusHandle->index;
|
|
m_focusHandle->index = -1;
|
|
m_focusHandle->bDraw = false;
|
|
|
|
return index;
|
|
}
|
|
|
|
void HandleDrawer::DrawAllOrEreaseAll(CDC * pDC, bool bDrawAll)
|
|
{
|
|
if (m_handlePts.size() == 0)
|
|
return;
|
|
|
|
size_t count = m_handlePts.size();
|
|
|
|
HandlePoint * handlePt = 0;
|
|
for (size_t i = 0; i < count; i++)
|
|
{
|
|
handlePt = m_handlePts[i];
|
|
if (bDrawAll)
|
|
{
|
|
if (!handlePt->bDraw)
|
|
{
|
|
DrawHandle(pDC, handlePt, false);
|
|
handlePt->bDraw = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (handlePt->bDraw) //已经画上的 Handle 在画一遍就擦掉了
|
|
{
|
|
DrawHandle(pDC, handlePt, false);
|
|
handlePt->bDraw = false;
|
|
}
|
|
}
|
|
} //end for
|
|
}
|
|
|
|
void HandleDrawer::DrawOrEreaseOneHandle(CDC * pDC, HandlePoint * handlePt, bool bDraw, bool bFocus)
|
|
{
|
|
if (bDraw)
|
|
{
|
|
if (!handlePt->bDraw)
|
|
{
|
|
DrawHandle(pDC, handlePt, bFocus);
|
|
handlePt->bDraw = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (handlePt->bDraw)
|
|
{
|
|
DrawHandle(pDC, handlePt, bFocus);
|
|
handlePt->bDraw = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandleDrawer::DrawHandle(CDC * pDC, HandlePoint * handlePt, bool bFocus)
|
|
{
|
|
if (handlePt == 0)
|
|
return;
|
|
if (handlePt->index == -1)
|
|
return;
|
|
|
|
long ptX = m_pDoc->GetDC().GetSX(handlePt->ptW.x0);
|
|
long ptY = m_pDoc->GetDC().GetSY(handlePt->ptW.y0);
|
|
|
|
CRect rect = GetHandleRect(ptX, ptY, bFocus);
|
|
|
|
int od = pDC->SetROP2(R2_NOTXORPEN);
|
|
CBrush brush, *pOldBrush;
|
|
pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
|
|
|
|
COLORREF color = m_colorHandles;
|
|
if (handlePt->index == 0) //使用不同的颜色绘制头节点
|
|
color = m_headColor;
|
|
|
|
CPen penHandles(PS_SOLID, 0, color);
|
|
CPen* op = (CPen*)pDC->SelectObject(&penHandles);
|
|
|
|
pDC->Ellipse(&rect);
|
|
|
|
pDC->SelectObject(pOldBrush);
|
|
pDC->SelectObject(op);
|
|
|
|
if (od >= 0)
|
|
pDC->SetROP2(od);
|
|
}
|
|
|
|
void HandleDrawer::Release()
|
|
{
|
|
auto ite = m_handlePts.begin();
|
|
auto iteEnd = m_handlePts.end();
|
|
|
|
for (; ite != iteEnd; ite++) {
|
|
delete (*ite);
|
|
}
|
|
|
|
m_handlePts.clear();
|
|
}
|
|
|
|
static CRect GetHandleRect(long x, long y, bool bFocus)
|
|
{
|
|
//m_HandleSize=::GetPreferences().WorkaroundHandle.m_nHandleSize;
|
|
|
|
int handleSize = HANDLE_SIZE;
|
|
if (bFocus)
|
|
handleSize = FOCUS_HANDLE_SIZE;
|
|
|
|
CRect rc; rc.SetRectEmpty();
|
|
rc.OffsetRect(x, y);
|
|
int d = handleSize / 2;
|
|
rc.InflateRect(d, d);
|
|
return rc;
|
|
}
|
|
|
|
static void GetXY(CCurveEx* pValue, int nIndex, dfPoint& point)
|
|
{
|
|
point.x0 = pValue->x[nIndex];
|
|
point.y0 = pValue->y[nIndex];
|
|
point.z0 = pValue->z[nIndex];
|
|
point.l = pValue->l[nIndex];
|
|
} |