#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 "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(m_currentEditor)) { return DRAG_NODE_DEFAULT; } if (std::dynamic_pointer_cast(m_currentEditor)) { return DRAG_NODE_SPLINE; } return -1; } // 创建编辑器的辅助方法 std::shared_ptr CItemCurveEdit::CreateEditor(int mode) { switch (mode) { case DRAG_NODE_DEFAULT: return std::make_shared(m_pDoc); case DRAG_NODE_SPLINE: return std::make_shared(m_pDoc); default: return std::make_shared(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