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