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.
124 lines
2.9 KiB
C++
124 lines
2.9 KiB
C++
#include "StdAfx.h"
|
|
#include "SplineDragPipeline.h"
|
|
#include "SigmaDoc.h"
|
|
#include <vector>
|
|
|
|
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<dfPoint> 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<dfPoint>& 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<dfPoint>& 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;
|
|
}
|
|
}
|