|
|
#include "StdAfx.h"
|
|
|
#include ".\itemcurveedit.h"
|
|
|
#include "SigmaDoc.h"
|
|
|
#include "SigmaView.h"
|
|
|
#include ".\actionmodifieditem.h"
|
|
|
#include "ActionBackupItem.h"
|
|
|
#include "DrawOperator/TypeDefine.h"
|
|
|
#include "ActionCurveEdit.h"
|
|
|
#include "ActionCurveEditAddPoint.h"
|
|
|
#include "ActionCurveEditDeletePoint.h"
|
|
|
#include "HandleDrawer.h"
|
|
|
|
|
|
// 引入具体的编辑器实现
|
|
|
#include "CurveEditorDefault.h"
|
|
|
#include "CurveEditorLinear.h"
|
|
|
#include "CurveEditorCosine.h"
|
|
|
#include "CurveEditorSpline.h"
|
|
|
|
|
|
namespace NItem
|
|
|
{
|
|
|
#define TRACKER_SOLID 1
|
|
|
#define TRACKER_RECT 2
|
|
|
#define TRACKER_CIRCLE 4
|
|
|
#define TRACKER_NO_EDIT TRACKER_SOLID | TRACKER_CIRCLE
|
|
|
|
|
|
// ========== 适配器/代理实现 ==========
|
|
|
|
|
|
CItemCurveEdit::CItemCurveEdit(CSigmaDoc* pDoc)
|
|
|
: CItemCurve(pDoc)
|
|
|
, m_pDoc(pDoc)
|
|
|
{
|
|
|
this->SetType(ITEM_CURVE_EDIT);
|
|
|
// 默认使用 Default 模式编辑器
|
|
|
m_currentEditor = CreateEditor(DRAG_NODE_DEFAULT);
|
|
|
}
|
|
|
|
|
|
CItemCurveEdit::~CItemCurveEdit(void)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
int CItemCurveEdit::GetCurrentEditMode() const
|
|
|
{
|
|
|
if (std::dynamic_pointer_cast<CurveEditorDefault>(m_currentEditor))
|
|
|
{
|
|
|
return DRAG_NODE_DEFAULT;
|
|
|
}
|
|
|
|
|
|
if (std::dynamic_pointer_cast<CurveEditorLinear>(m_currentEditor))
|
|
|
{
|
|
|
return DRAG_NODE_LINE;
|
|
|
}
|
|
|
|
|
|
if (std::dynamic_pointer_cast<CurveEditorCosine>(m_currentEditor))
|
|
|
{
|
|
|
return DRAG_NODE_COS;
|
|
|
}
|
|
|
|
|
|
if (std::dynamic_pointer_cast<CurveEditorSpline>(m_currentEditor))
|
|
|
{
|
|
|
return DRAG_NODE_SPLINE;
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
// 创建编辑器的辅助方法
|
|
|
std::shared_ptr<CurveEditorBase> CItemCurveEdit::CreateEditor(int mode)
|
|
|
{
|
|
|
switch (mode)
|
|
|
{
|
|
|
case DRAG_NODE_DEFAULT:
|
|
|
return std::make_shared<CurveEditorDefault>(m_pDoc);
|
|
|
case DRAG_NODE_LINE:
|
|
|
return std::make_shared<CurveEditorLinear>(m_pDoc);
|
|
|
case DRAG_NODE_COS:
|
|
|
return std::make_shared<CurveEditorCosine>(m_pDoc);
|
|
|
case DRAG_NODE_SPLINE:
|
|
|
return std::make_shared<CurveEditorSpline>(m_pDoc);
|
|
|
default:
|
|
|
return std::make_shared<CurveEditorDefault>(m_pDoc);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 根据曲线状态切换编辑器
|
|
|
void CItemCurveEdit::SetCurveState(int state, CDC* pDC)
|
|
|
{
|
|
|
|
|
|
// 根据状态映射到编辑模式
|
|
|
int mode = DRAG_NODE_DEFAULT;
|
|
|
switch (state)
|
|
|
{
|
|
|
case CURVE_STATE_LINE:
|
|
|
mode = DRAG_NODE_DEFAULT;
|
|
|
break;
|
|
|
case CURVE_STATE_ARC:
|
|
|
mode = DRAG_NODE_COS;
|
|
|
break;
|
|
|
case CURVE_STATE_SPLINE:
|
|
|
mode = DRAG_NODE_SPLINE;
|
|
|
break;
|
|
|
default:
|
|
|
// WARNING:
|
|
|
// 当前不能切换为 DRAG_NODE_DEFAULT
|
|
|
// 原因: state 中模式切换与其他指令混合处理,
|
|
|
// 若在此处切换,会意外修改编辑状态
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
SwitchEditMode(mode);
|
|
|
CItemCurve::SetCurveState(state, pDC);
|
|
|
}
|
|
|
|
|
|
// 显式切换编辑模式
|
|
|
void CItemCurveEdit::SwitchEditMode(int mode)
|
|
|
{
|
|
|
// 模式变更拦截:
|
|
|
// 1. 防御冗余触发:解决上层状态同步 Bug 导致的点击时重复进入此函数的问题,保护当前交互状态不丢失。
|
|
|
// 2. 生命周期管理:仅在模式真正变化时销毁并重建 Editor。
|
|
|
// 3. 状态隔离:真正切换模式时,不跨对象透传控制点下标(HandleIndex),确保各模式逻辑独立且安全。
|
|
|
if (GetCurrentEditMode() == mode)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 保存当前状态
|
|
|
POSITION oldPos = GetPos();
|
|
|
|
|
|
// 创建新编辑器
|
|
|
m_currentEditor = CreateEditor(mode);
|
|
|
|
|
|
// 同步状态
|
|
|
if (oldPos && m_currentEditor)
|
|
|
{
|
|
|
m_currentEditor->SetPos(oldPos);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ========== 所有方法转发到 m_currentEditor ==========
|
|
|
|
|
|
void CItemCurveEdit::OnDraw(CXyDC* pDC)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->OnDraw(pDC);
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->OnLButtonDblClk(nFlags, point);
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::OnLButtonDown(CDC* pDC, UINT nFlags, CPoint point, int vk)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->OnLButtonDown(pDC, nFlags, point, vk);
|
|
|
}
|
|
|
|
|
|
int CItemCurveEdit::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->OnMouseMove(pDC, nFlags, point);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::OnLButtonUp(CDC* pDC, UINT nFlags, CPoint point, int vk)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->OnLButtonUp(pDC, nFlags, point, vk);
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurveEdit::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->OnSetCursor(pWnd, nHitTest, message);
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurveEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->OnKeyDown(nChar, nRepCnt, nFlags);
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurveEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->OnKeyUp(nChar, nRepCnt, nFlags);
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
int CItemCurveEdit::GetSubMenu()
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->GetSubMenu();
|
|
|
return 6;
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::SetPos(POSITION pos)
|
|
|
{
|
|
|
CItem::SetPos(pos);
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->SetPos(pos);
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::Clear(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->Clear();
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::Draw(CDC* pDC)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->Draw(pDC);
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::DrawAssistant(CDC* pDC, int mouseX, int mouseY)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->DrawAssistant(pDC, mouseX, mouseY);
|
|
|
}
|
|
|
|
|
|
int CItemCurveEdit::GetNumberOfNode()
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->GetNumberOfNode();
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::EreaseHandles(CDC* pDC)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->EreaseHandles(pDC);
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::EndEdit(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->EndEdit();
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::CancelAll(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->CancelAll();
|
|
|
}
|
|
|
|
|
|
BOOL CItemCurveEdit::IsCanCancelAll(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->IsCanCancelAll();
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
int CItemCurveEdit::HitTestHandle(CPoint point)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->HitTestHandle(point);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::DeleteHandle(int nIndex)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->DeleteHandle(nIndex);
|
|
|
}
|
|
|
|
|
|
int CItemCurveEdit::AddHandle(CPoint point)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->AddHandle(point);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
CCurveEx* CItemCurveEdit::GetCurCurve(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->GetControlCurve();
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::AttachProcess(CPointList & oldPoints, CPointList & newPoints)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->AttachProcess(oldPoints, newPoints);
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::DrawMoveLine(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->DrawMoveLine();
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::GetMarkCurve(void)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
m_currentEditor->GetMarkCurve();
|
|
|
}
|
|
|
BOOL CItemCurveEdit::IsCanAddHandle(CPoint point, double* pl0)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->IsCanAddHandle(point, pl0);
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
void CItemCurveEdit::GetXY(CCurveEx* pValue, int nIndex, dfPoint& point)
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->GetXY(pValue, nIndex, point);
|
|
|
}
|
|
|
|
|
|
CPoint2D CItemCurveEdit::GetCDown() const
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->GetCDown();
|
|
|
return CPoint2D{ 0.0, 0.0 };
|
|
|
}
|
|
|
|
|
|
CPoint2D CItemCurveEdit::GetCLast() const
|
|
|
{
|
|
|
if (m_currentEditor)
|
|
|
return m_currentEditor->GetCDown();
|
|
|
return CPoint2D{ 0.0, 0.0 };
|
|
|
}
|
|
|
|
|
|
}//namespace
|