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