#pragma once #include #include "HandleDrawer.h" #include "itemcurve.h" namespace NItem { #define DRAG_NODE_DEFAULT 0 // 直接移动当前节点 #define DRAG_NODE_LINE 1 // 线性移动节点 #define DRAG_NODE_COS 2 // 余弦移动节点 #define DRAG_NODE_SPLINE 3 // 三次样条移动节点 #define DRAG_LINE_COLOR RGB(0, 153, 255) // #define TRACKER_SOLID 1 // #define TRACKER_RECT 2 // #define TRACKER_CIRCLE 4 // #define TRACKER_NO_EDIT TRACKER_SOLID | TRACKER_CIRCLE class CurveEditorBase : public CItemCurve { public: CurveEditorBase(CSigmaDoc *pDoc); virtual ~CurveEditorBase(void); void OnDraw(CXyDC *pDC) override final; void OnLButtonDblClk(UINT nFlags, CPoint point) override final; void OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) override final; int OnMouseMove(CDC *pDC, UINT nFlags, CPoint point) override final; void OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) override final; BOOL OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message) override final; BOOL OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) override final; BOOL OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) override final; int GetSubMenu() override final; void SetPos(POSITION pos) override final; void Clear(void); void Draw(CDC *pDC); void DrawAssistant(CDC *pDC, int mouseX, int mouseY) override; int GetNumberOfNode(); void EreaseHandles(CDC *pDC); void EndEdit(void); void CancelAll(void); BOOL IsCanCancelAll(void); // 控制点操作 int HitTestHandle(CPoint point); void DeleteHandle(int nIndex); int AddHandle(CPoint point); BOOL IsCanAddHandle(CPoint point, double *pl0 = nullptr); // 虚函数:样条模式需重写为返回冗余曲线 virtual CCurveEx *GetControlCurve(void); void GetXY(CCurveEx *pValue, int nIndex, dfPoint &point); void AttachProcess(CPointList &oldPoints, CPointList &newPoints); void DrawMoveLine(void); void GetMarkCurve(void); CPoint2D GetCDown() const; CPoint2D GetCLast() const; protected: // 默认:绘制两条线段 // 线性/余弦/样条:绘制整条受影响的曲线 virtual void OnDrawDragPreview() = 0; virtual void OnCalculateDragEffect(CPointList *pList) = 0; // 在SetPos后调用,样条模式用于计算m_pMarkCurve virtual void OnModeInitialize() {} // 在OnMouseMove中调用 virtual void OnDragMove(int nIndex, CPoint2D pt) {} // 获取当前偏移模式(Linear/Cosine模式使用) int GetOffsetMode(void); // 虚函数:样条模式需重写 virtual int AddHandle(double l0); // 辅助方法:向指定曲线添加点 int AddHandle(CCurveEx *pValue, dfPoint add); // 鼠标位置(世界坐标) CPoint2D c_down, c_last; // 拖动标志 bool m_bLButtonDownWhenMouseMove; // 备份原始曲线(用于撤销) std::unique_ptr m_pBakOne; // 控制点绘制器 std::unique_ptr m_handleDrawer; // 鼠标按下点(屏幕坐标) CPoint m_nLButtonDownPoint; // 新点列表(用于预览) CPointList NewPointList; // 临时点列表 CPointList PointList; // 控制点绘制模式 DWORD m_nHandleDrawMode; int m_nModeX; int m_nModeY; // 绘制模式 private: void DrawHandle(CXyDC *pDC, CCurveEx *pCurve); void DrawHandlesByCDC(CDC *pDC, CCurveEx *pCurve); void DrawSelectHandle(int nHandle); CRect GetRangeWidthIndex(int nIndex); CRect GetFirstNodeHandleRectFocus(CPoint point); void SetDrawMode(int nModeX, int nModeY); int HitTestHandle(CCurveEx *pValue, CPoint point); bool IsDragging(int nFlags) const; int HandleMouseDrag(CXyDC *pDC, CPoint point); int HandleMouseHover(CDC *dc, CPoint point); }; }; // namespace NItem