|
|
#include "StdAfx.h"
|
|
|
#include "DCHelp.h"
|
|
|
#include "SigmaDoc.h"
|
|
|
#include ".\itemcurve.h"
|
|
|
|
|
|
#define PEN_WIDTH 2
|
|
|
|
|
|
CItemCurve::CItemCurve(CSigmaDoc * ppDoc)
|
|
|
: CItem(ppDoc)
|
|
|
, m_AddLineState(CURVE_STATE_LINE)
|
|
|
, m_bContinuePen(FALSE)
|
|
|
, m_bStretchStart(TRUE)
|
|
|
{
|
|
|
m_AddLineState = ppDoc->GetEditLineStatus() % 4;
|
|
|
|
|
|
this->SetType(ITEM_CURVE);
|
|
|
m_pen.CreatePen(PS_SOLID, PEN_WIDTH, PEN_COLOR);
|
|
|
m_oldLineState = 0;
|
|
|
m_bAuxiliaryCurveRedraw = FALSE;
|
|
|
}
|
|
|
|
|
|
CItemCurve::~CItemCurve(void)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 重置绘图状态到初始状态.
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::Reset(void)
|
|
|
{
|
|
|
EraseScreenLines();
|
|
|
PointList.RemoveAll();
|
|
|
m_bContinuePen = FALSE;
|
|
|
m_bStretchStart = TRUE;
|
|
|
}
|
|
|
|
|
|
void NItem::CItemCurve::OnCancel(void)
|
|
|
{
|
|
|
Reset();
|
|
|
}
|
|
|
|
|
|
bool NItem::CItemCurve::GetAngleAndDistance(double &angle, double &distance) const
|
|
|
{
|
|
|
if (std::isnan(m_angle) || std::isnan(m_distance))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
angle = m_angle;
|
|
|
distance = m_distance;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurve::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
|
{
|
|
|
if (this->IsEditState())
|
|
|
return FALSE;
|
|
|
//GetDoc()->GetCursor().SetCursor(CursorDrawCurve);
|
|
|
//return GetDoc()->GetCursor().SetCursor();
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
POSITION CItemCurve::InsertPointWithPointDistance(double x, double y)
|
|
|
{
|
|
|
if (PointList.GetCount() <= 1)
|
|
|
{
|
|
|
AddPointFromCoordinate(x, y);
|
|
|
return PointList.GetHeadPosition();
|
|
|
}
|
|
|
CCurveEx* pc = new CCurveEx;
|
|
|
pc->SetPoints(PointList, 2);
|
|
|
double x0, y0, z0, l0;
|
|
|
if (pc->PointDistance(x, y, l0) > 1e30)
|
|
|
{
|
|
|
delete pc;
|
|
|
return NULL;
|
|
|
}
|
|
|
pc->GetCoordinate(l0, x0, y0, z0);
|
|
|
int i = AfxGetPublicFunction()->BinarySearch(l0, pc->num, pc->l);
|
|
|
dfPoint dp;
|
|
|
dp.x0 = x0;
|
|
|
dp.y0 = y0;
|
|
|
POSITION pos = NULL;
|
|
|
if (i < 0)
|
|
|
{
|
|
|
pos = AddPoint(dp, TRUE);
|
|
|
REDO_ITEM item;
|
|
|
item.point = dp;
|
|
|
item.bHead = TRUE;
|
|
|
item.pos = pos;
|
|
|
UndoList.AddHead(item);
|
|
|
}
|
|
|
else if (i > pc->num - 1)
|
|
|
{
|
|
|
AddPointFromCoordinate(x0, y0);
|
|
|
pos = PointList.GetTailPosition();
|
|
|
}
|
|
|
pos = PointList.FindIndex(i);
|
|
|
if (pos != NULL)
|
|
|
{
|
|
|
pos = PointList.InsertAfter(pos, dp);
|
|
|
REDO_ITEM item;
|
|
|
item.point = dp;
|
|
|
item.bHead = FALSE;
|
|
|
item.pos = pos;
|
|
|
UndoList.AddHead(item);
|
|
|
}
|
|
|
|
|
|
delete pc;
|
|
|
return pos;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::AddPointFromCoordinate(double x, double y)
|
|
|
{
|
|
|
dfPoint dp;
|
|
|
dp.x0 = x;
|
|
|
dp.y0 = y;
|
|
|
AddPoint(dp);
|
|
|
}
|
|
|
|
|
|
void CItemCurve::AddPoint(dfPoint point)
|
|
|
{
|
|
|
POSITION pos = AddPoint(point, FALSE);
|
|
|
REDO_ITEM item;
|
|
|
item.point = point;
|
|
|
item.bHead = FALSE;
|
|
|
item.pos = pos;
|
|
|
UndoList.AddHead(item);
|
|
|
}
|
|
|
|
|
|
void NItem::CItemCurve::AutoClose(void)
|
|
|
{
|
|
|
if (PointList.IsEmpty()) return;
|
|
|
dfPoint dp = PointList.GetHead();
|
|
|
AddPoint(dp);
|
|
|
m_dpLastMousePos = dp;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::GetAnglePoint(dfPoint &ddp, double angle)
|
|
|
{
|
|
|
if (PointList.GetCount() < 2) return;
|
|
|
dfPoint pt, pp;
|
|
|
POSITION p = PointList.GetTailPosition();
|
|
|
pt = PointList.GetPrev(p);
|
|
|
pp = PointList.GetPrev(p);
|
|
|
CPoint2D cp; cp.x0 = pp.x0; cp.y0 = pp.y0;
|
|
|
cp.Rotate(pt.x0, pt.y0, angle);
|
|
|
if (fabs(angle - 90) < 1e-10 && fabs(pt.x0 - cp.x0) < 1e-10)
|
|
|
{
|
|
|
ddp.x0 = pt.x0;
|
|
|
return;
|
|
|
}
|
|
|
double k, b;
|
|
|
AfxGetPublicFunction()->GetKB(pt.x0, pt.y0, cp.x0, cp.y0, k, b); //y=kx+b;
|
|
|
double a = AfxGetPublicFunction()->GetAngle(pt.x0, pt.y0, pp.x0, pp.y0);
|
|
|
if (fabs(a) < 45.0 || fabs(a) < 135.0)
|
|
|
ddp.y0 = k * ddp.x0 + b;
|
|
|
else
|
|
|
ddp.x0 = (ddp.y0 - b) / k;
|
|
|
}
|
|
|
|
|
|
void NItem::CItemCurve::storeAngleAndDistance(dfPoint& point1, dfPoint& point2)
|
|
|
{
|
|
|
m_angle = AfxGetPublicFunction()->GetAngle(point1.x0, point1.y0, point2.x0, point2.y0);
|
|
|
if (m_angle < 0)
|
|
|
{
|
|
|
m_angle += 360;
|
|
|
}
|
|
|
|
|
|
double a = point2.x0 - point1.x0;
|
|
|
double b = point2.y0 - point1.y0;
|
|
|
m_distance = sqrt(a * a + b * b);
|
|
|
}
|
|
|
|
|
|
void NItem::CItemCurve::clearAngleAndDistance()
|
|
|
{
|
|
|
m_angle = std::numeric_limits<double>::quiet_NaN();
|
|
|
m_distance = std::numeric_limits<double>::quiet_NaN();
|
|
|
}
|
|
|
|
|
|
dfPoint CItemCurve::GetRealPoint(CPointList& pl, UINT nFlags, CPoint point)
|
|
|
{
|
|
|
dfPoint dp = GetReal(point);
|
|
|
if (pl.GetCount() > 0)
|
|
|
{
|
|
|
CurPoint = pl.GetTail();
|
|
|
//if(nFlags & MK_SHIFT)//if the SHIFT key is down
|
|
|
if (::IsKeyDown(VK_SHIFT)) // 按下 shift 时,左右以45度旋转
|
|
|
dp = GetShiftDownPoint(CurPoint.x0, CurPoint.y0, dp.x0, dp.y0);
|
|
|
}
|
|
|
if (m_AddLineState == CURVE_STATE_ANGLE)
|
|
|
GetAnglePoint(dp, 90.0);
|
|
|
|
|
|
if (GetDoc()->IsSnapEnabled())
|
|
|
{
|
|
|
if (m_pSpatialIndex == nullptr)
|
|
|
{
|
|
|
m_pSpatialIndex = std::make_unique<CSpatialIndex>(*GetDoc()->GetDraw());
|
|
|
}
|
|
|
|
|
|
std::optional<CPoint2D> snapPoint = m_pSpatialIndex->GetSnapPoint(dp, m_snapRange);
|
|
|
if (snapPoint)
|
|
|
{
|
|
|
dfPoint point;
|
|
|
point.x0 = snapPoint.value().x0;
|
|
|
point.y0 = snapPoint.value().y0;
|
|
|
return point;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return dp;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
|
{
|
|
|
dfPoint dp = GetRealPoint(PointList, nFlags, point);
|
|
|
if (fabs(dp.x0 - m_dpLastMousePos.x0) > ZERO || fabs(dp.y0 - m_dpLastMousePos.y0) > ZERO)
|
|
|
{
|
|
|
AddPoint(dp);
|
|
|
m_dpLastMousePos = dp;
|
|
|
}
|
|
|
NextCurve();
|
|
|
}
|
|
|
|
|
|
void CItemCurve::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk)
|
|
|
{
|
|
|
//按下鼠标后,如果用户未移动,不会触发绘制橡皮筋线,m_bStretchStart为TRUE
|
|
|
//擦除旧橡皮筋线,重置橡皮筋线尾点
|
|
|
if (!m_bStretchStart && PointList.GetCount() > 0)
|
|
|
{
|
|
|
EraseRubberLine();
|
|
|
m_bStretchStart = TRUE;
|
|
|
}
|
|
|
//添加点
|
|
|
dfPoint dp = GetRealPoint(PointList, nFlags, point);
|
|
|
AddPoint(dp);
|
|
|
//画新增辅助线段
|
|
|
DrawAssistantLineLastSegment();
|
|
|
m_dpLastMousePos = PointList.GetTail();
|
|
|
//清空重做列表
|
|
|
ClearRedoList();
|
|
|
}
|
|
|
|
|
|
int CItemCurve::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point)
|
|
|
{
|
|
|
SetScreenDC(pDC);
|
|
|
// 按下 shift 时,左右以45度旋转,会计算转换后的点
|
|
|
dfPoint dp = GetRealPoint(PointList, nFlags, point);
|
|
|
//连续画点
|
|
|
if (m_bContinuePen && (nFlags & MK_LBUTTON))
|
|
|
{
|
|
|
AddPoint(dp);
|
|
|
}
|
|
|
else if (!PointList.IsEmpty())
|
|
|
{
|
|
|
dfPoint dpTail = PointList.GetTail();
|
|
|
storeAngleAndDistance(dpTail, dp);
|
|
|
CPoint ptTail = GetDC()->GetScreen(dpTail);
|
|
|
// 不能使用point 因为当按shift键时 软件按正交或45度线计算点坐标 这个坐标不等于鼠标点
|
|
|
CPoint ptCur = GetDC()->GetScreen(dp);
|
|
|
CPoint ptPrev = GetDC()->GetScreen(m_dpLastMousePos);
|
|
|
if (m_bAuxiliaryCurveRedraw)
|
|
|
{
|
|
|
DrawRubberLine();
|
|
|
}
|
|
|
if (!m_bStretchStart)
|
|
|
{
|
|
|
DrawLineScreen(ptPrev.x, ptPrev.y, ptTail.x, ptTail.y);
|
|
|
}
|
|
|
DrawLineScreen(ptCur.x, ptCur.y, ptTail.x, ptTail.y);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
clearAngleAndDistance();
|
|
|
}
|
|
|
m_dpLastMousePos = dp;
|
|
|
m_bStretchStart = FALSE;
|
|
|
m_bAuxiliaryCurveRedraw = FALSE;
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::EraseAuxiliaryLines(CDC * pScreenDC)
|
|
|
{
|
|
|
CXyDC * pDC = GetDC();
|
|
|
if (pDC == 0)
|
|
|
return;
|
|
|
pDC->Create(pScreenDC);
|
|
|
if (PointList.GetCount() == 0)
|
|
|
return;
|
|
|
int od = pScreenDC->SetROP2(R2_NOTXORPEN);
|
|
|
CPen * pOld = pScreenDC->SelectObject(&m_pen);
|
|
|
dfPoint dp;
|
|
|
POSITION p = PointList.GetHeadPosition();
|
|
|
|
|
|
dp = PointList.GetNext(p);
|
|
|
pDC->MoveTo(dp.x0, dp.y0);
|
|
|
while (p)
|
|
|
{
|
|
|
dp = PointList.GetNext(p);
|
|
|
pDC->LineTo(dp.x0, dp.y0);
|
|
|
}
|
|
|
|
|
|
pScreenDC->SelectObject(pOld);
|
|
|
pScreenDC->SetROP2(od);
|
|
|
m_bAuxiliaryCurveRedraw = TRUE;
|
|
|
m_bStretchStart = TRUE;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::DrawAssistant(CDC * pScreenDC, int mouseX, int mouseY)
|
|
|
{
|
|
|
CXyDC * pDC = GetDC();
|
|
|
if (pDC == 0)
|
|
|
return;
|
|
|
pDC->Create(pScreenDC);
|
|
|
if (PointList.GetCount() == 0)
|
|
|
return;
|
|
|
|
|
|
CPen * pOld = pScreenDC->SelectObject(&m_pen);
|
|
|
dfPoint dp;
|
|
|
POSITION p = PointList.GetHeadPosition();
|
|
|
|
|
|
dp = PointList.GetNext(p);
|
|
|
pDC->MoveTo(dp.x0, dp.y0);
|
|
|
while (p)
|
|
|
{
|
|
|
dp = PointList.GetNext(p);
|
|
|
pDC->LineTo(dp.x0, dp.y0);
|
|
|
}
|
|
|
pScreenDC->SelectObject(pOld);
|
|
|
if (m_AddLineState != CURVE_STATE_SPLINE)
|
|
|
{
|
|
|
//画最后的橡皮筋线
|
|
|
dp = PointList.GetTail();
|
|
|
pDC->MoveTo(dp.x0, dp.y0);
|
|
|
pDC->LineTo(m_dpLastMousePos.x0, m_dpLastMousePos.y0);
|
|
|
}
|
|
|
m_bAuxiliaryCurveRedraw = TRUE;
|
|
|
m_bStretchStart = TRUE;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 屏幕刷新全图重绘后重绘辅助线.
|
|
|
*
|
|
|
* @param pDC
|
|
|
*/
|
|
|
void CItemCurve::OnDraw(CXyDC* pXyDC, CDC* pDC)
|
|
|
{
|
|
|
m_bStretchStart = TRUE;
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurve::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
|
{
|
|
|
dfPoint dp1;
|
|
|
switch (nChar)
|
|
|
{
|
|
|
case VK_RETURN://VK_RETURN
|
|
|
NextCurve();
|
|
|
break;
|
|
|
case VK_ESCAPE:
|
|
|
//Reset();
|
|
|
break;
|
|
|
case VK_BACK://VK_BACK 从点列表后向前删除
|
|
|
{
|
|
|
if (m_AddLineState != CURVE_STATE_LINE)break;
|
|
|
RemoveAssistantLineTailPoint();
|
|
|
}
|
|
|
break;
|
|
|
case VK_DELETE: //从点列表前向后删除
|
|
|
if (m_AddLineState != CURVE_STATE_LINE)break;
|
|
|
RemoveAssistantLineFirstPoint();
|
|
|
|
|
|
|
|
|
/*pos = PointList.GetHeadPosition();
|
|
|
if (pos == NULL)break;
|
|
|
dp1 = PointList.GetAt(pos);*/
|
|
|
//RemoveAt(pos);
|
|
|
//{
|
|
|
// REDO_ITEM item;
|
|
|
// item.point = dp1;
|
|
|
// item.bHead = TRUE;
|
|
|
// item.pos = NULL;
|
|
|
// UndoList.AddHead(item);
|
|
|
//}
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurve::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
|
{
|
|
|
if (nChar == VK_ESCAPE)
|
|
|
{
|
|
|
//Reset();
|
|
|
return TRUE;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
int CItemCurve::GetSubMenu()
|
|
|
{
|
|
|
return 4;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::Draw(CXyDC* pDC, CPointList& pl, COLORREF color)
|
|
|
{
|
|
|
if (pl.GetCount() <= 0) return;
|
|
|
CPen* pOld = pDC->GetDC()->SelectObject(&m_pen);
|
|
|
dfPoint dp;
|
|
|
POSITION p = pl.GetHeadPosition();
|
|
|
dp = pl.GetNext(p);
|
|
|
pDC->MoveTo(dp.x0, dp.y0);
|
|
|
pDC->LineTo(dp.x0, dp.y0);
|
|
|
while (p)
|
|
|
{
|
|
|
dp = pl.GetNext(p);
|
|
|
pDC->LineTo(dp.x0, dp.y0);
|
|
|
}
|
|
|
pDC->GetDC()->SelectObject(pOld);
|
|
|
}
|
|
|
|
|
|
void CItemCurve::RemoveAssistantLineTailPoint()
|
|
|
{
|
|
|
POSITION startPos = NULL;
|
|
|
POSITION endPos = NULL;
|
|
|
POSITION pos = NULL;
|
|
|
dfPoint startDp;
|
|
|
dfPoint endDp;
|
|
|
dfPoint dp;
|
|
|
CPoint startPt;
|
|
|
CPoint endPt;
|
|
|
|
|
|
int count = PointList.GetCount();
|
|
|
if (count > 1)
|
|
|
{
|
|
|
//擦除橡皮筋线
|
|
|
if (!m_bStretchStart) {
|
|
|
DrawRubberLine();
|
|
|
}
|
|
|
startPos = PointList.FindIndex(count - 2);
|
|
|
endPos = PointList.FindIndex(count - 1);
|
|
|
startDp = PointList.GetAt(startPos);
|
|
|
endDp = PointList.GetAt(endPos);
|
|
|
startPt = GetDC()->GetScreen(startDp);
|
|
|
endPt = GetDC()->GetScreen(endDp);
|
|
|
//擦除最后一个临时线段
|
|
|
CPen *pOld = m_pScreenDC->SelectObject(&m_pen);
|
|
|
DrawLineScreen(startPt.x, startPt.y, endPt.x, endPt.y);
|
|
|
m_pScreenDC->SelectObject(pOld);
|
|
|
////UNDO
|
|
|
//{
|
|
|
// REDO_ITEM item;
|
|
|
// item.point = endDp;
|
|
|
// item.bHead = FALSE;
|
|
|
// item.pos = NULL;
|
|
|
// UndoList.AddHead(item);
|
|
|
//}
|
|
|
PointList.RemoveTail();
|
|
|
//重画新橡皮筋线
|
|
|
DrawRubberLine();
|
|
|
m_bStretchStart = FALSE;
|
|
|
}
|
|
|
else if (count == 1)
|
|
|
{
|
|
|
pos = PointList.FindIndex(0);
|
|
|
dp = PointList.GetAt(pos);
|
|
|
|
|
|
////UNDO
|
|
|
//{
|
|
|
// REDO_ITEM item;
|
|
|
// item.point = dp;
|
|
|
// item.bHead = FALSE;
|
|
|
// item.pos = NULL;
|
|
|
// UndoList.AddHead(item);
|
|
|
//}
|
|
|
Reset();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 屏幕绘制的未加入到xy的临时绘制线.
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::DrawAssistantCurve()
|
|
|
{
|
|
|
int count = PointList.GetCount();
|
|
|
if (count < 2) return;
|
|
|
|
|
|
CPen* pOld = m_pScreenDC->SelectObject(&m_pen);
|
|
|
dfPoint dp;
|
|
|
POSITION p = PointList.GetHeadPosition();
|
|
|
dp = PointList.GetNext(p);
|
|
|
CPoint pt1 = GetDC()->GetScreen(dp.x0, dp.y0);
|
|
|
CPoint pt2;
|
|
|
while (p)
|
|
|
{
|
|
|
dp = PointList.GetNext(p);
|
|
|
pt2 = GetDC()->GetScreen(dp.x0, dp.y0);
|
|
|
DrawLineScreen(pt1.x, pt1.y, pt2.x, pt2.y);
|
|
|
pt1 = pt2;
|
|
|
}
|
|
|
m_pScreenDC->SelectObject(pOld);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 屏幕绘制的临时曲线的最后一段.
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::DrawAssistantLineLastSegment()
|
|
|
{
|
|
|
int count = PointList.GetCount();
|
|
|
//如果小于两个点,只画橡皮筋线
|
|
|
if (count < 2) return;
|
|
|
//使用自定义的颜色笔画
|
|
|
CPen* pOld = m_pScreenDC->SelectObject(&m_pen);
|
|
|
dfPoint dp1;
|
|
|
dfPoint dp2;
|
|
|
CPoint pt1;
|
|
|
CPoint pt2;
|
|
|
POSITION p1;
|
|
|
POSITION p2;
|
|
|
|
|
|
p1 = PointList.FindIndex(count - 1);
|
|
|
dp1 = PointList.GetNext(p1);
|
|
|
pt1 = GetDC()->GetScreen(dp1.x0, dp1.y0);
|
|
|
|
|
|
p2 = PointList.FindIndex(count - 2);
|
|
|
dp2 = PointList.GetNext(p2);
|
|
|
pt2 = GetDC()->GetScreen(dp2.x0, dp2.y0);
|
|
|
DrawLineScreen(pt1.x, pt1.y, pt2.x, pt2.y);
|
|
|
m_pScreenDC->SelectObject(pOld);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 擦除屏幕绘制的临时曲线的第一段.
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::RemoveAssistantLineFirstPoint()
|
|
|
{
|
|
|
int count = PointList.GetCount();
|
|
|
//只有一个点时,删除相当重置
|
|
|
if (count <= 1)
|
|
|
{
|
|
|
Reset();
|
|
|
return;
|
|
|
}
|
|
|
//擦除辅助线
|
|
|
CPen* pOld = m_pScreenDC->SelectObject(&m_pen);
|
|
|
dfPoint dp1;
|
|
|
dfPoint dp2;
|
|
|
CPoint pt1;
|
|
|
CPoint pt2;
|
|
|
POSITION p1;
|
|
|
POSITION p2;
|
|
|
|
|
|
p1 = PointList.FindIndex(0);
|
|
|
dp1 = PointList.GetNext(p1);
|
|
|
pt1 = GetDC()->GetScreen(dp1.x0, dp1.y0);
|
|
|
|
|
|
p2 = PointList.FindIndex(1);
|
|
|
dp2 = PointList.GetNext(p2);
|
|
|
pt2 = GetDC()->GetScreen(dp2.x0, dp2.y0);
|
|
|
DrawLineScreen(pt1.x, pt1.y, pt2.x, pt2.y);
|
|
|
m_pScreenDC->SelectObject(pOld);
|
|
|
PointList.RemoveHead();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* @brief 异或的方法画橡皮筋线,重画相当于清除,需要曲线的尾点和鼠标最后的位置
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::DrawRubberLine()
|
|
|
{
|
|
|
if (!m_pScreenDC)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
if (PointList.GetCount() <= 0)
|
|
|
return;
|
|
|
|
|
|
dfPoint p1 = PointList.GetTail();
|
|
|
CPoint ptT = GetDC()->GetScreen(p1);
|
|
|
CPoint ptPrev = GetDC()->GetScreen(m_dpLastMousePos);
|
|
|
DrawLineScreen(ptPrev.x, ptPrev.y, ptT.x, ptT.y);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 异或的方法画橡皮筋线,重画相当于清除.
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::EraseRubberLine()
|
|
|
{
|
|
|
if (!m_pScreenDC)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
if (PointList.GetCount() <= 0)
|
|
|
return;
|
|
|
|
|
|
dfPoint p1 = PointList.GetTail();
|
|
|
CPoint ptT = GetDC()->GetScreen(p1);
|
|
|
CPoint ptPrev = GetDC()->GetScreen(m_dpLastMousePos);
|
|
|
DrawLineScreen(ptPrev.x, ptPrev.y, ptT.x, ptT.y);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief 擦除所有屏幕上绘制的临时辅助线,包括橡皮筯线和标记辅助线.
|
|
|
*
|
|
|
*/
|
|
|
void CItemCurve::EraseScreenLines()
|
|
|
{
|
|
|
int count = PointList.GetCount();
|
|
|
if (!m_bStretchStart)
|
|
|
{
|
|
|
EraseRubberLine();
|
|
|
}
|
|
|
if (count > 1)
|
|
|
{
|
|
|
DrawAssistantCurve();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
POSITION CItemCurve::NextCurve(void)
|
|
|
{
|
|
|
if (PointList.GetCount() == 0) return NULL;
|
|
|
if (PointList.GetCount() <= 1)
|
|
|
{
|
|
|
Reset();
|
|
|
return NULL;
|
|
|
}
|
|
|
CCurveEx* pCurve = new CCurveEx();
|
|
|
pCurve->SetPoints(PointList, 2);
|
|
|
POSITION pos = AddElement(pCurve, DOUBLEFOX_CURVE);
|
|
|
Reset();
|
|
|
return pos;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::RedrawScreenLines()
|
|
|
{
|
|
|
int count = PointList.GetCount();
|
|
|
if (!m_bStretchStart)
|
|
|
{
|
|
|
DrawRubberLine();
|
|
|
}
|
|
|
if (count > 1)
|
|
|
{
|
|
|
DrawAssistantCurve();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void CItemCurve::Undo(void)
|
|
|
{
|
|
|
if (UndoList.GetCount() == 0) return;
|
|
|
REDO_ITEM item, it;
|
|
|
item = UndoList.RemoveHead();
|
|
|
int i = 0;
|
|
|
it = item;
|
|
|
while (1)
|
|
|
{
|
|
|
if (item.pos)//增加的点,需要删除
|
|
|
{
|
|
|
RemoveAt(it.pos);
|
|
|
it.pos = NULL;
|
|
|
}
|
|
|
else//删除的点,需要增加
|
|
|
{
|
|
|
it.pos = AddPoint(it.point, it.bHead);
|
|
|
}
|
|
|
RedoList.AddHead(it);
|
|
|
i++;
|
|
|
if (i >= item.num)break;
|
|
|
it = UndoList.RemoveHead();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void NItem::CItemCurve::ClearRedoList(void)
|
|
|
{
|
|
|
RedoList.RemoveAll();
|
|
|
}
|
|
|
|
|
|
void CItemCurve::Redo(void)
|
|
|
{
|
|
|
if (RedoList.GetCount() == 0) return;
|
|
|
REDO_ITEM item, it;
|
|
|
item = RedoList.RemoveHead();
|
|
|
int i = 0;
|
|
|
while (1)
|
|
|
{
|
|
|
it = item;
|
|
|
if (it.pos)
|
|
|
{
|
|
|
RemoveAt(it.pos);
|
|
|
it.pos = NULL;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
it.pos = AddPoint(it.point, it.bHead);
|
|
|
}
|
|
|
UndoList.AddHead(it);
|
|
|
i++;
|
|
|
if (i >= item.num) break;
|
|
|
it = RedoList.RemoveHead();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurve::IsCanUndo(void)
|
|
|
{
|
|
|
return (BOOL)UndoList.GetCount();
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurve::IsCanRedo(void)
|
|
|
{
|
|
|
return (BOOL)RedoList.GetCount();
|
|
|
}
|
|
|
|
|
|
int CItemCurve::RemoveAt(POSITION pos)
|
|
|
{
|
|
|
if (pos == NULL) return 0;
|
|
|
if (PointList.GetCount() == 0) return 0;
|
|
|
int result = 0;
|
|
|
POSITION pHead = PointList.GetHeadPosition();
|
|
|
POSITION pTail = PointList.GetTailPosition();
|
|
|
dfPoint dp1, dp2;
|
|
|
POSITION p = pos;
|
|
|
if (pos == pTail)//删除最后一个点
|
|
|
{
|
|
|
dp1 = PointList.GetPrev(p);
|
|
|
dp2 = dp1;
|
|
|
//DrawLine(dp1.x0,dp1.y0,PrevPoint.x0,PrevPoint.y0);
|
|
|
|
|
|
if (p)dp2 = PointList.GetPrev(p);
|
|
|
if (PointList.GetCount() > 1)
|
|
|
{
|
|
|
//CPen* pOld=GetDC()->GetDC()->SelectObject(&m_pen);
|
|
|
//DrawLine(dp1.x0,dp1.y0,dp2.x0,dp2.y0);
|
|
|
//GetDC()->GetDC()->SelectObject(pOld);
|
|
|
}
|
|
|
|
|
|
//if(PointList.GetCount()>1)
|
|
|
//DrawLine(dp2.x0,dp2.y0,PrevPoint.x0,PrevPoint.y0);
|
|
|
result = 3;
|
|
|
}
|
|
|
else if (pos == pHead)//删除第一个点
|
|
|
{
|
|
|
dp1 = PointList.GetNext(p);
|
|
|
dp2 = dp1;
|
|
|
if (p) dp2 = PointList.GetNext(p);
|
|
|
|
|
|
//if(PointList.GetCount()==1)
|
|
|
// DrawLine(dp1.x0,dp1.y0,PrevPoint.x0,PrevPoint.y0);
|
|
|
//else
|
|
|
//{
|
|
|
// CPen* pOld=GetDC()->GetDC()->SelectObject(&m_pen);
|
|
|
// DrawLine(dp1.x0,dp1.y0,dp2.x0,dp2.y0);
|
|
|
// GetDC()->GetDC()->SelectObject(pOld);
|
|
|
//}
|
|
|
result = 1;
|
|
|
}
|
|
|
else//删除中间点
|
|
|
{
|
|
|
dfPoint dp = PointList.GetAt(p);
|
|
|
dp1 = PointList.GetNext(p); if (p) dp1 = PointList.GetAt(p);
|
|
|
p = pos;
|
|
|
dp2 = PointList.GetPrev(p); if (p) dp2 = PointList.GetPrev(p);
|
|
|
|
|
|
//CPen* pOld=GetDC()->GetDC()->SelectObject(&m_pen);
|
|
|
//DrawLine(dp.x0,dp.y0,dp2.x0,dp2.y0);
|
|
|
//DrawLine(dp.x0,dp.y0,dp1.x0,dp1.y0);
|
|
|
//DrawLine(dp2.x0,dp2.y0,dp1.x0,dp1.y0);
|
|
|
//GetDC()->GetDC()->SelectObject(pOld);
|
|
|
result = 2;
|
|
|
}
|
|
|
PointList.RemoveAt(pos);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
POSITION CItemCurve::AddPoint(dfPoint point, BOOL bHead)
|
|
|
{
|
|
|
POSITION pos = NULL;
|
|
|
if (bHead)
|
|
|
{
|
|
|
pos = PointList.AddHead(point);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pos = PointList.AddTail(point);
|
|
|
}
|
|
|
return pos;
|
|
|
}
|
|
|
|
|
|
void CItemCurve::SetCurveState(int state, CDC * pDC)
|
|
|
{
|
|
|
m_oldLineState = m_AddLineState;
|
|
|
m_AddLineState = state;
|
|
|
m_bStretchStart = TRUE;
|
|
|
m_pDoc->SetEditLineStatus(m_AddLineState);
|
|
|
}
|
|
|
|
|
|
void CItemCurve::RestoreCurveState(void)
|
|
|
{
|
|
|
m_AddLineState = m_oldLineState;
|
|
|
m_pDoc->SetEditLineStatus(m_AddLineState);
|
|
|
}
|
|
|
|
|
|
BOOL NItem::CItemCurve::IsLineState(void)
|
|
|
{
|
|
|
if (m_AddLineState == CURVE_STATE_LINE)
|
|
|
return TRUE;
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
COne* CItemCurve::CreateOne()
|
|
|
{
|
|
|
CCurveEx* pCurve = new CCurveEx;
|
|
|
if (PointList.GetCount() <= 1)
|
|
|
{
|
|
|
PointList.RemoveAll();
|
|
|
return NULL;
|
|
|
}
|
|
|
pCurve->SetPoints(PointList, 2);
|
|
|
return m_pDoc->GetDraw()->CreateOne(pCurve, DOUBLEFOX_CURVE);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
int CItemCurve::PopupNameDialog(CXy* pxy, POSITION pos)
|
|
|
{
|
|
|
return 1;
|
|
|
/*
|
|
|
if(!::GetPreferences().WorkaroundEdit.m_bPopupNameDlg) return 0;
|
|
|
if(pos==NULL || pxy==NULL) return 0;
|
|
|
|
|
|
CDlgName dlg;
|
|
|
if(::GetPreferences().WorkaroundEdit.m_bContourAuto)
|
|
|
{
|
|
|
AfxGetPublicFunction()->FloatToString(dlg.m_strName, ::GetPreferences().WorkaroundEdit.m_dContourStart);
|
|
|
::GetPreferences().WorkaroundEdit.m_dContourStart += ::GetPreferences().WorkaroundEdit.m_dContourStep;
|
|
|
}
|
|
|
|
|
|
if(dlg.DoModal()!=IDOK) return 0;
|
|
|
|
|
|
COne* pOne=pxy->GetAt(pos);
|
|
|
pOne->SetName(dlg.m_strName);
|
|
|
|
|
|
if(::GetPreferences().WorkaroundEdit.m_bContourAuto)
|
|
|
{
|
|
|
::GetPreferences().WorkaroundEdit.m_dContourStart = atof(dlg.m_strName);
|
|
|
::GetPreferences().WorkaroundEdit.m_dContourStart += ::GetPreferences().WorkaroundEdit.m_dContourStep;
|
|
|
}
|
|
|
return 1;
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
//void CItemCurve::OnMouseMoveStatus(CDC* pDC, UINT nFlags, CPoint point)// , BYTE*& destBuffer, int& destLen)
|
|
|
//{
|
|
|
// SetScreenDC(pDC);
|
|
|
// dfPoint dp=GetRealPoint(PointList,nFlags, point);
|
|
|
//
|
|
|
// //设置状态条信息
|
|
|
// //if(PointList.GetCount()>0)
|
|
|
// // SetStatusBarLengthInfo(CurPoint.x0, CurPoint.y0, dp.x0, dp.y0);// , destBuffer, destLen);
|
|
|
//
|
|
|
// if(m_bContinuePen && nFlags & MK_LBUTTON)
|
|
|
// {
|
|
|
// AddPoint(dp);
|
|
|
// }
|
|
|
// else if(!PointList.IsEmpty())
|
|
|
// {
|
|
|
// dfPoint p1 = PointList.GetTail();
|
|
|
// CPoint ptT = GetDC()->GetScreen(p1);
|
|
|
// //不能使用point 因为当按shift键时 软件按正交或45度线计算点坐标 这个坐标不等于鼠标点
|
|
|
// CPoint ptCur = GetDC()->GetScreen(dp);
|
|
|
// if (!m_bStretchStart)
|
|
|
// {
|
|
|
// CPoint ptPrev = GetDC()->GetScreen(PrevPoint);
|
|
|
// DrawLineScreen(ptPrev.x, ptPrev.y, ptT.x, ptT.y);
|
|
|
// }
|
|
|
// DrawLineScreen(ptCur.x, ptCur.y, ptT.x, ptT.y);
|
|
|
// m_bStretchStart = false;
|
|
|
// }
|
|
|
// PrevPoint=dp;
|
|
|
// //TRACE("PrevPoint:%f, %f\n", PrevPoint.x0, PrevPoint.y0);
|
|
|
//}
|
|
|
|
|
|
|
|
|
//void CItemCurve::OnMouseMove(UINT nFlags, CPoint point)
|
|
|
//{
|
|
|
// CPointList PointList;
|
|
|
// dfPoint CurPoint;
|
|
|
//
|
|
|
// //CItemBase* itemBase = new CItemBase();
|
|
|
// dfPoint dp = GetRealPoint(PointList, nFlags, point);
|
|
|
//
|
|
|
// //设置状态条信息
|
|
|
// if (PointList.GetCount() > 0)
|
|
|
// SetStatusBarLengthInfo(CurPoint.x0, CurPoint.y0, dp.x0, dp.y0);
|
|
|
//
|
|
|
// if (m_bContinuePen && nFlags & MK_LBUTTON)
|
|
|
// {
|
|
|
// AddPoint(dp);
|
|
|
// }
|
|
|
// else if (!PointList.IsEmpty())
|
|
|
// {
|
|
|
// dfPoint p1 = PointList.GetTail();
|
|
|
// DrawLineReal(PrevPoint.x0, PrevPoint.y0, p1.x0, p1.y0);
|
|
|
// DrawLineReal(dp.x0, dp.y0, p1.x0, p1.y0);
|
|
|
// }
|
|
|
// PrevPoint = dp;
|
|
|
//}
|
|
|
|
|
|
|
|
|
//=====================
|