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.

328 lines
6.8 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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