#include "stdafx.h" #include "HandleDrawer.h" #include "SigmaDoc.h" #include #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]; }