|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include "SplineCurveModel.h"
|
|
|
|
|
|
#include "ItemCurve.h"
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
class CSigmaDoc; // forward declaration for GetDoc()
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 样条拖拽状态
|
|
|
|
|
|
*
|
|
|
|
|
|
* 集中管理鼠标按下/拖拽位置及预览点,与 CurveEditorSpline 共享。
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct SplineDragState
|
|
|
|
|
|
{
|
|
|
|
|
|
CPoint screenDownPoint;
|
|
|
|
|
|
CPoint2D worldDownPoint;
|
|
|
|
|
|
CPoint2D worldLastPoint;
|
|
|
|
|
|
bool isLeftButtonDownDuringMove;
|
|
|
|
|
|
CPointList previewPoints;
|
|
|
|
|
|
|
|
|
|
|
|
void Reset()
|
|
|
|
|
|
{
|
|
|
|
|
|
worldDownPoint = CPoint2D(0, 0);
|
|
|
|
|
|
worldLastPoint = CPoint2D(0, 0);
|
|
|
|
|
|
isLeftButtonDownDuringMove = false;
|
|
|
|
|
|
previewPoints.RemoveAll();
|
|
|
|
|
|
}
|
|
|
|
|
|
void StartDrag(CPoint screen, CPoint2D world)
|
|
|
|
|
|
{
|
|
|
|
|
|
screenDownPoint = screen;
|
|
|
|
|
|
worldDownPoint = world;
|
|
|
|
|
|
worldLastPoint = world;
|
|
|
|
|
|
previewPoints.RemoveAll();
|
|
|
|
|
|
}
|
|
|
|
|
|
void UpdateLast(CPoint2D world) { worldLastPoint = world; }
|
|
|
|
|
|
bool HasMoved() const { return !(worldLastPoint == worldDownPoint); }
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 拖拽流水线上下文接口
|
|
|
|
|
|
*
|
|
|
|
|
|
* CurveEditorSpline 实现,供 SplineDragPipeline 访问文档与模型。
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct ISplineDragPipelineContext
|
|
|
|
|
|
{
|
|
|
|
|
|
virtual ~ISplineDragPipelineContext() = default;
|
|
|
|
|
|
virtual CSigmaDoc* GetDoc() = 0;
|
|
|
|
|
|
virtual POSITION GetPos() = 0;
|
|
|
|
|
|
virtual int GetHandleIndex() = 0;
|
|
|
|
|
|
virtual void WriteModelToDocCurve() = 0;
|
|
|
|
|
|
virtual void Invalidate() = 0;
|
|
|
|
|
|
virtual void AttachProcess(CPointList& oldPoints, CPointList& newPoints) = 0;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 样条拖拽流水线
|
|
|
|
|
|
*
|
|
|
|
|
|
* 根据拖拽状态计算并应用/预览效果,流程:取曲线 → 重建样条 → 写回 → 同步模型。
|
|
|
|
|
|
*/
|
|
|
|
|
|
class SplineDragPipeline
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
SplineDragPipeline(SplineCurveModel& model, SplineDragState& dragState, ISplineDragPipelineContext* pContext);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 执行拖拽步骤,isPreview 为 true 时仅输出预览点到 pListForPreview
|
|
|
|
|
|
*/
|
|
|
|
|
|
bool ProcessDragStep(bool isPreview, CPointList* pListForPreview);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
bool GetCurveForDragEdit(bool isPreview, CCurveEx*& pValue, int& handleIndex, CPointList* pListForPreview);
|
|
|
|
|
|
bool GetDraggedSegmentAndAttachContext(std::vector<dfPoint>& segmentVec);
|
|
|
|
|
|
bool WriteDraggedSegmentToCurve(CCurveEx* pValue, const std::vector<dfPoint>& segmentVec);
|
|
|
|
|
|
void SyncControlPointsAndNotify(int handleIndex);
|
|
|
|
|
|
void EndDragEdit(CCurveEx* pValue, bool isPreview, CPointList* pList);
|
|
|
|
|
|
|
|
|
|
|
|
SplineCurveModel* m_pModel;
|
|
|
|
|
|
SplineDragState* m_pDragState;
|
|
|
|
|
|
ISplineDragPipelineContext* m_pContext;
|
|
|
|
|
|
};
|