#include "StdAfx.h" #include "SplineDragPipeline.h" #include "SigmaDoc.h" #include SplineDragPipeline::SplineDragPipeline(SplineCurveModel& model, SplineDragState& dragState, ISplineDragPipelineContext* pContext) : m_pModel(&model) , m_pDragState(&dragState) , m_pContext(pContext) { } bool SplineDragPipeline::ProcessDragStep(bool isPreview, CPointList* pListForPreview) { CCurveEx* pValue = nullptr; int handleIndex = -1; if (!GetCurveForDragEdit(isPreview, pValue, handleIndex, pListForPreview)) return false; std::vector segmentVec; if (!GetDraggedSegmentAndAttachContext(segmentVec)) { if (isPreview && pValue) delete pValue; return false; } if (!WriteDraggedSegmentToCurve(pValue, segmentVec)) { if (isPreview && pValue) delete pValue; return false; } if (!isPreview) SyncControlPointsAndNotify(handleIndex); EndDragEdit(pValue, isPreview, pListForPreview); return true; } bool SplineDragPipeline::GetCurveForDragEdit(bool isPreview, CCurveEx*& pValue, int& handleIndex, CPointList* pListForPreview) { CCurveEx* pDocCurve = (CCurveEx*)m_pContext->GetDoc()->GetDraw()->GetAtValue(m_pContext->GetPos()); if (isPreview) { CCurveEx* pc = new CCurveEx; *pc = *pDocCurve; pValue = pc; } else pValue = pDocCurve; handleIndex = m_pContext->GetHandleIndex(); if (handleIndex < 0 || !m_pModel->IsValid()) { if (isPreview && pListForPreview) { if (pValue) { pValue->GetPoint(*pListForPreview); delete pValue; } pValue = nullptr; } return false; } return true; } bool SplineDragPipeline::GetDraggedSegmentAndAttachContext(std::vector& segmentVec) { int handleIndex = m_pContext->GetHandleIndex(); if (handleIndex < 0 || !m_pModel->IsValid()) return false; m_pModel->UpdateControlPoint(handleIndex, m_pDragState->worldLastPoint.x0, m_pDragState->worldLastPoint.y0); const auto& renderPts = m_pModel->GetRenderPoints(); if (renderPts.empty()) return false; m_pDragState->previewPoints.RemoveAll(); segmentVec.clear(); for (const auto& rp : renderPts) { m_pDragState->previewPoints.AddTail(rp.point); segmentVec.push_back(rp.point); } return true; } bool SplineDragPipeline::WriteDraggedSegmentToCurve(CCurveEx* pValue, const std::vector& segmentVec) { if (segmentVec.empty()) return false; CPointList fullPointList; for (const auto& p : segmentVec) fullPointList.AddTail(p); if (pValue->nPoint == 4) pValue->nPoint = 3; if (!pValue->bAutoLocation) pValue->bAutoLocation = TRUE; pValue->SetPoints(fullPointList, pValue->nPoint, pValue->bAutoLocation); return true; } void SplineDragPipeline::SyncControlPointsAndNotify(int handleIndex) { (void)handleIndex; m_pContext->WriteModelToDocCurve(); m_pContext->Invalidate(); } void SplineDragPipeline::EndDragEdit(CCurveEx* pValue, bool isPreview, CPointList* pList) { if (isPreview && pValue && pList) { pValue->GetPoint(*pList); delete pValue; } }