tahoma2d/toonz/sources/tnztools/controlpointselection.h

171 lines
5.2 KiB
C
Raw Normal View History

2016-05-17 03:04:11 +12:00
#pragma once
2016-03-19 06:57:51 +13:00
#ifndef CONTROLPOINT_SELECTION_INCLUDED
#define CONTROLPOINT_SELECTION_INCLUDED
#include "toonzqt/selection.h"
#include "tools/tool.h"
#include "tstroke.h"
#include "tvectorimage.h"
#include "tcurves.h"
//=============================================================================
// ControlPointEditorStroke
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
class ControlPointEditorStroke {
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
class ControlPoint {
public:
int m_pointIndex;
TThickPoint m_speedIn;
TThickPoint m_speedOut;
bool m_isCusp;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
ControlPoint(int i, TThickPoint speedIn, TThickPoint speedOut,
bool isCusp = true)
: m_pointIndex(i)
, m_speedIn(speedIn)
, m_speedOut(speedOut)
, m_isCusp(isCusp) {}
ControlPoint() {}
};
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QList<ControlPoint> m_controlPoints;
TVectorImageP m_vi;
int m_strokeIndex;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void adjustChunkParity();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
/*! Reset m_controlPoints. */
void resetControlPoints();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TThickPoint getPureDependentPoint(int index) const;
void getDependentPoints(
int index, std::vector<std::pair<int, TThickPoint>> &points) const;
void updatePoints();
void updateDependentPoint(int index);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
inline int nextIndex(int index) const;
inline int prevIndex(int index) const;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void moveSpeedIn(int index, const TPointD &delta, double minDistance);
void moveSpeedOut(int index, const TPointD &delta, double minDistance);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void moveSingleControlPoint(int index, const TPointD &delta);
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
enum PointType { CONTROL_POINT, SPEED_IN, SPEED_OUT, SEGMENT, NONE };
ControlPointEditorStroke() : m_vi() {}
~ControlPointEditorStroke() { m_controlPoints.clear(); }
ControlPointEditorStroke *clone() const;
/*! Modify stroke: between two linear or cusp point must be a pair chunk
number.
PAY ATTENTION: Can add control point in the stroke. */
void setStroke(const TVectorImageP &vi, int strokeIndex);
TStroke *getStroke() const {
return m_vi ? m_vi->getStroke(m_strokeIndex) : 0;
}
void setStrokeIndex(int strokeIndex) { m_strokeIndex = strokeIndex; }
int getStrokeIndex() const { return m_strokeIndex; }
int getControlPointCount() const { return m_controlPoints.size(); }
TThickPoint getControlPoint(int index) const;
/*! From index point in \b ControlPointEditorStroke to index point in \b
* TStroke. */
int getIndexPointInStroke(int index) const;
TThickPoint getSpeedInPoint(int index) const;
TThickPoint getSpeedOutPoint(int index) const;
//! Return true if index point is a cusp.
bool isCusp(int index) const;
//! Set \b m_isCusp of \b index point to \b isCusp.
/*! If isCusp == false check \b setSpeedIn and modify speed. */
void setCusp(int index, bool isCusp, bool setSpeedIn);
bool isSpeedInLinear(int index) const;
bool isSpeedOutLinear(int index) const;
void setLinearSpeedIn(int index, bool linear = true,
bool updatePoints = true);
void setLinearSpeedOut(int index, bool linear = true,
bool updatePoints = true);
/*! If isLinear==true set to "0" the speedIn and speedOut value of index
point; otherwise set to default value.
Return true if speedIn or speedOut is modified.
If updatePoints is true update dependent point after.*/
bool setLinear(int index, bool isLinear, bool updatePoints = true);
bool setControlPointsLinear(std::set<int> points, bool isLinear);
/*! Move \b index ControlPoint of \b delta. */
void moveControlPoint(int index, const TPointD &delta);
/*! Add a ControlPoint in \b point. Return added ControlPoint index. */
int addControlPoint(const TPointD &pos);
void deleteControlPoint(int index);
/*! Move speed in \b index of \b delta. */
void moveSpeed(int index, const TPointD &delta, bool isIn,
double minDistance);
/*! Move segment between \b beforeIndex and \b nextIndex of \b delta. */
void moveSegment(int beforeIndex, int nextIndex, const TPointD &delta,
const TPointD &pos);
/*!Return NONE if \b pos is far from stroke.*/
PointType getPointTypeAt(const TPointD &pos, double &distance2,
int &index) const;
bool isSelfLoop() const {
TStroke *stroke = getStroke();
return stroke && stroke->isSelfLoop();
}
2016-03-19 06:57:51 +13:00
};
//=============================================================================
// ControlPointSelection
//-----------------------------------------------------------------------------
class ControlPointSelection final : public QObject, public TSelection {
2016-06-15 18:43:10 +12:00
Q_OBJECT
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
std::set<int> m_selectedPoints;
int m_strokeIndex;
ControlPointEditorStroke *m_controlPointEditorStroke;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
ControlPointSelection() : m_controlPointEditorStroke(0), m_strokeIndex(-1) {}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void setControlPointEditorStroke(
ControlPointEditorStroke *controlPointEditorStroke) {
m_controlPointEditorStroke = controlPointEditorStroke;
}
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
bool isEmpty() const override { return m_selectedPoints.empty(); }
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
void selectNone() override { m_selectedPoints.clear(); }
2016-06-15 18:43:10 +12:00
bool isSelected(int index) const;
void select(int index);
void unselect(int index);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void deleteControlPoints();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
void addMenuItems(QMenu *menu);
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
void enableCommands() override;
2016-03-19 06:57:51 +13:00
protected slots:
2016-06-15 18:43:10 +12:00
void setLinear();
void setUnlinear();
2016-03-19 06:57:51 +13:00
};
2016-06-15 18:43:10 +12:00
#endif // CONTROLPOINT_SELECTION_INCLUDED