Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
// For Qt translation support
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace ToolUtils;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define POINT2POINT L"Endpoint to Endpoint"
Toshihiro Shimizu 890ddd
#define POINT2LINE L"Endpoint to Line"
Toshihiro Shimizu 890ddd
#define LINE2LINE L"Line to Line"
Toshihiro Shimizu 890ddd
#define NORMAL L"Normal"
Toshihiro Shimizu 890ddd
#define RECT L"Rectangular"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TEnv::StringVar TapeMode("InknpaintTapeMode1", "Endpoint to Endpoint");
Toshihiro Shimizu 890ddd
TEnv::IntVar TapeSmooth("InknpaintTapeSmooth", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar TapeJoinStrokes("InknpaintTapeJoinStrokes", 0);
Toshihiro Shimizu 890ddd
TEnv::StringVar TapeType("InknpaintTapeType1", "Normal");
Toshihiro Shimizu 890ddd
TEnv::DoubleVar AutocloseFactor("InknpaintAutocloseFactor", 4.0);
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UndoAutoclose final : public ToolUtils::TToolUndo {
Shinya Kitaoka 120a6e
  int m_oldStrokeId1;
Shinya Kitaoka 120a6e
  int m_oldStrokeId2;
Shinya Kitaoka 120a6e
  int m_pos1, m_pos2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  VIStroke *m_oldStroke1;
Shinya Kitaoka 120a6e
  VIStroke *m_oldStroke2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> *m_fillInformation;</tfilledregioninf>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_row;
Shinya Kitaoka 120a6e
  int m_column;
Shinya Kitaoka 120a6e
  std::vector<int> m_changedStrokes;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  VIStroke *m_newStroke;
Shinya Kitaoka 120a6e
  int m_newStrokeId;
Shinya Kitaoka 120a6e
  int m_newStrokePos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UndoAutoclose(TXshSimpleLevel *level, const TFrameId &frameId, int pos1,
Shinya Kitaoka 120a6e
                int pos2, std::vector<tfilledregioninf> *fillInformation,</tfilledregioninf>
Shinya Kitaoka 120a6e
                const std::vector<int> &changedStrokes)</int>
Shinya Kitaoka 120a6e
      : ToolUtils::TToolUndo(level, frameId)
Shinya Kitaoka 120a6e
      , m_oldStroke1(0)
Shinya Kitaoka 120a6e
      , m_oldStroke2(0)
Shinya Kitaoka 120a6e
      , m_pos1(pos1)
Shinya Kitaoka 120a6e
      , m_pos2(pos2)
Shinya Kitaoka 120a6e
      , m_newStrokePos(-1)
Shinya Kitaoka 120a6e
      , m_fillInformation(fillInformation)
Shinya Kitaoka 120a6e
      , m_changedStrokes(changedStrokes) {
Shinya Kitaoka 120a6e
    TVectorImageP image = level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    if (pos1 != -1) {
Shinya Kitaoka 120a6e
      m_oldStrokeId1 = image->getStroke(pos1)->getId();
Shinya Kitaoka 120a6e
      m_oldStroke1   = cloneVIStroke(image->getVIStroke(pos1));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (pos2 != -1 && pos1 != pos2 && image) {
Shinya Kitaoka 120a6e
      m_oldStrokeId2 = image->getStroke(pos2)->getId();
Shinya Kitaoka 120a6e
      m_oldStroke2   = cloneVIStroke(image->getVIStroke(pos2));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      m_row    = app->getCurrentFrame()->getFrame();
Shinya Kitaoka 120a6e
      m_column = app->getCurrentColumn()->getColumnIndex();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~UndoAutoclose() {
Shinya Kitaoka 120a6e
    deleteVIStroke(m_newStroke);
Shinya Kitaoka 120a6e
    if (m_oldStroke1) deleteVIStroke(m_oldStroke1);
Shinya Kitaoka 120a6e
    if (m_oldStroke2) deleteVIStroke(m_oldStroke2);
Shinya Kitaoka 120a6e
    if (m_isLastInBlock) delete m_fillInformation;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
    if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
      app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(!!image);
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
    int strokeIndex = image->getStrokeIndexById(m_newStrokeId);
Shinya Kitaoka 120a6e
    if (strokeIndex != -1) image->removeStroke(strokeIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_oldStroke1)
Shinya Kitaoka 120a6e
      image->insertStrokeAt(cloneVIStroke(m_oldStroke1), m_pos1);
Shinya Kitaoka 120a6e
    if (m_oldStroke2)
Shinya Kitaoka 120a6e
      image->insertStrokeAt(cloneVIStroke(m_oldStroke2), m_pos2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    image->notifyChangedStrokes(m_changedStrokes, std::vector<tstroke *="">());</tstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!m_isLastInBlock) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < m_fillInformation->size(); i++) {
Shinya Kitaoka 120a6e
      TRegion *reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Shinya Kitaoka 120a6e
      assert(reg);
Shinya Kitaoka 120a6e
      if (reg) reg->setStyle((*m_fillInformation)[i].m_styleId);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
      app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(!!image);
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
    if (m_oldStroke1) {
Shinya Kitaoka 120a6e
      int strokeIndex = image->getStrokeIndexById(m_oldStrokeId1);
Shinya Kitaoka 120a6e
      if (strokeIndex != -1) image->removeStroke(strokeIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_oldStroke2) {
Shinya Kitaoka 120a6e
      int strokeIndex = image->getStrokeIndexById(m_oldStrokeId2);
Shinya Kitaoka 120a6e
      if (strokeIndex != -1) image->removeStroke(strokeIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    VIStroke *stroke = cloneVIStroke(m_newStroke);
Shinya Kitaoka 120a6e
    image->insertStrokeAt(stroke, m_pos1 == -1 ? m_newStrokePos : m_pos1,
Shinya Kitaoka 120a6e
                          false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    image->notifyChangedStrokes(m_changedStrokes, std::vector<tstroke *="">());</tstroke>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    return sizeof(*this) +
Shinya Kitaoka 120a6e
           m_fillInformation->capacity() * sizeof(TFilledRegionInf) + 500;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QString("Autoclose Tool"); }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::AutocloseTool; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Autoclose Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class VectorTapeTool final : public TTool {
Shinya Kitaoka 120a6e
  Q_DECLARE_TR_FUNCTIONS(VectorTapeTool)
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_draw;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_secondPoint;
Shinya Kitaoka 120a6e
  int m_strokeIndex1, m_strokeIndex2;
Shinya Kitaoka 120a6e
  double m_w1, m_w2, m_pixelSize;
Shinya Kitaoka 120a6e
  TPointD m_pos;
Shinya Kitaoka 120a6e
  bool m_firstTime;
Shinya Kitaoka 120a6e
  TRectD m_selectionRect;
Shinya Kitaoka 120a6e
  TPointD m_startRect;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TBoolProperty m_smooth;
Shinya Kitaoka 120a6e
  TBoolProperty m_joinStrokes;
Shinya Kitaoka 120a6e
  TEnumProperty m_mode;
Shinya Kitaoka 120a6e
  TPropertyGroup m_prop;
Shinya Kitaoka 120a6e
  TDoubleProperty m_autocloseFactor;
Shinya Kitaoka 120a6e
  TEnumProperty m_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  VectorTapeTool()
Shinya Kitaoka 120a6e
      : TTool("T_Tape")
Shinya Kitaoka 120a6e
      , m_secondPoint(false)
Shinya Kitaoka 120a6e
      , m_strokeIndex1(-1)
Shinya Kitaoka 120a6e
      , m_strokeIndex2(-1)
Shinya Kitaoka 120a6e
      , m_w1(-1.0)
Shinya Kitaoka 120a6e
      , m_w2(-1.0)
Shinya Kitaoka 120a6e
      , m_pixelSize(1)
Shinya Kitaoka 120a6e
      , m_draw(false)
Shinya Kitaoka 120a6e
      , m_smooth("Smooth", false)  // W_ToolOptions_Smooth
Shinya Kitaoka 120a6e
      , m_joinStrokes("JoinStrokes", false)
Shinya Kitaoka 120a6e
      , m_mode("Mode")
Shinya Kitaoka 120a6e
      , m_type("Type")
Shinya Kitaoka 120a6e
      , m_autocloseFactor("Distance", 0.1, 100, 0.5)
Shinya Kitaoka 120a6e
      , m_firstTime(true)
Shinya Kitaoka 120a6e
      , m_selectionRect()
Shinya Kitaoka 120a6e
      , m_startRect() {
Shinya Kitaoka 120a6e
    bind(TTool::Vectors);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_prop.bind(m_type);
Shinya Kitaoka 120a6e
    m_prop.bind(m_mode);
Shinya Kitaoka 120a6e
    m_prop.bind(m_autocloseFactor);
Shinya Kitaoka 120a6e
    m_prop.bind(m_joinStrokes);
Shinya Kitaoka 120a6e
    m_prop.bind(m_smooth);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_mode.addValue(POINT2POINT);
Shinya Kitaoka 120a6e
    m_mode.addValue(POINT2LINE);
Shinya Kitaoka 120a6e
    m_mode.addValue(LINE2LINE);
Shinya Kitaoka 120a6e
    m_smooth.setId("Smooth");
Shinya Kitaoka 120a6e
    m_type.addValue(NORMAL);
Shinya Kitaoka 120a6e
    m_type.addValue(RECT);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_mode.setId("Mode");
Shinya Kitaoka 120a6e
    m_type.setId("Type");
Shinya Kitaoka 120a6e
    m_joinStrokes.setId("JoinVectors");
Shinya Kitaoka 120a6e
    m_autocloseFactor.setId("Distance");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  ToolType getToolType() const override { return TTool::LevelWriteTool; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  bool onPropertyChanged(std::string propertyName) override {
Shinya Kitaoka 120a6e
    TapeMode                 = ::to_string(m_mode.getValue());
Shinya Kitaoka 120a6e
    TapeSmooth               = (int)(m_smooth.getValue());
Shinya Kitaoka 120a6e
    std::wstring s           = m_type.getValue();
Shinya Kitaoka 120a6e
    if (!s.empty()) TapeType = ::to_string(s);
Shinya Kitaoka 120a6e
    TapeJoinStrokes          = (int)(m_joinStrokes.getValue());
Shinya Kitaoka 120a6e
    AutocloseFactor          = (double)(m_autocloseFactor.getValue());
Shinya Kitaoka 120a6e
    m_selectionRect          = TRectD();
Shinya Kitaoka 120a6e
    m_startRect              = TPointD();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (propertyName == "Distance" &&
Shinya Kitaoka 120a6e
        (ToonzCheck::instance()->getChecks() & ToonzCheck::eAutoclose))
Shinya Kitaoka 120a6e
      notifyImageChanged();
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 473e70
  void updateTranslation() override {
Shinya Kitaoka 120a6e
    m_smooth.setQStringName(tr("Smooth"));
Shinya Kitaoka 120a6e
    m_joinStrokes.setQStringName(tr("Join Vectors"));
Xelloss 6a7ff2
    m_autocloseFactor.setQStringName(tr("Distance"));
Shinya Kitaoka 120a6e
    m_mode.setQStringName(tr("Mode:"));
Shinya Kitaoka 120a6e
    m_type.setQStringName(tr("Type:"));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void draw() override {
Shinya Kitaoka 120a6e
    TVectorImageP vi(getImage(false));
Shinya Kitaoka 120a6e
    if (!m_draw) return;
Shinya Kitaoka 120a6e
    if (!vi) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // TAffine viewMatrix = getViewer()->getViewMatrix();
Shinya Kitaoka 120a6e
    // glPushMatrix();
Shinya Kitaoka 120a6e
    // tglMultMatrix(viewMatrix);
Shinya Kitaoka 120a6e
    if (m_type.getValue() == RECT) {
Shinya Kitaoka 120a6e
      if (!m_selectionRect.isEmpty())
Shinya Kitaoka 120a6e
        ToolUtils::drawRect(m_selectionRect, TPixel::Black, 0x3F33, true);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_strokeIndex1 == -1 || m_strokeIndex1 >= (int)(vi->getStrokeCount()))
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    tglColor(TPixelD(0.1, 0.9, 0.1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *stroke1   = vi->getStroke(m_strokeIndex1);
Shinya Kitaoka 120a6e
    TThickPoint point1 = stroke1->getPoint(m_w1);
Shinya Kitaoka 120a6e
    // TThickPoint point1 = stroke1->getControlPoint(m_cpIndex1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_pixelSize  = getPixelSize();
Shinya Kitaoka 120a6e
    double thick = std::max(6.0 * m_pixelSize, point1.thick);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    tglDrawCircle(point1, thick);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TThickPoint point2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_secondPoint) {
Shinya Kitaoka 120a6e
      if (m_strokeIndex2 != -1) {
Shinya Kitaoka 120a6e
        TStroke *stroke2 = vi->getStroke(m_strokeIndex2);
Shinya Kitaoka 120a6e
        point2           = stroke2->getPoint(m_w2);
Shinya Kitaoka 120a6e
        thick            = std::max(6.0 * m_pixelSize, point2.thick);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        tglColor(TPixelD(0.6, 0.7, 0.4));
Shinya Kitaoka 120a6e
        thick  = 4 * m_pixelSize;
Shinya Kitaoka 120a6e
        point2 = m_pos;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      tglDrawCircle(point2, thick);
Shinya Kitaoka 120a6e
      tglDrawSegment(point1, point2);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // glPopMatrix();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &) override {
Shinya Kitaoka 120a6e
    TVectorImageP vi(getImage(false));
Shinya Kitaoka 120a6e
    if (!vi) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // BUTTA e rimetti (Dava problemi con la penna)
Shinya Kitaoka 120a6e
    if (!m_draw) return;  // Questa riga potrebbe non essere messa
Shinya Kitaoka 120a6e
    // m_draw=true;   //Perche'??? Non basta dargli true in onEnter??
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_type.getValue() == RECT) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double minDistance2 = 10000000000.;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_strokeIndex1 = -1;
Shinya Kitaoka 120a6e
    m_secondPoint  = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int i, strokeNumber = vi->getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *stroke;
Shinya Kitaoka 120a6e
    double distance2, outW;
Shinya Kitaoka 120a6e
    TPointD point;
Shinya Kitaoka 120a6e
    int cpMax;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < strokeNumber; i++) {
Shinya Kitaoka 120a6e
      stroke = vi->getStroke(i);
Shinya Kitaoka 120a6e
      if (m_mode.getValue() == LINE2LINE) {
Shinya Kitaoka 120a6e
        if (stroke->getNearestW(pos, outW, distance2) &&
Shinya Kitaoka 120a6e
            distance2 < minDistance2) {
Shinya Kitaoka 120a6e
          minDistance2   = distance2;
Shinya Kitaoka 120a6e
          m_strokeIndex1 = i;
Shinya Kitaoka 120a6e
          if (areAlmostEqual(outW, 0.0, 1e-3))
Shinya Kitaoka 120a6e
            m_w1 = 0.0;
Shinya Kitaoka 120a6e
          else if (areAlmostEqual(outW, 1.0, 1e-3))
Shinya Kitaoka 120a6e
            m_w1 = 1.0;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            m_w1 = outW;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else if (!stroke->isSelfLoop()) {
Shinya Kitaoka 120a6e
        point = stroke->getControlPoint(0);
Shinya Kitaoka 120a6e
        if ((distance2 = tdistance2(pos, point)) < minDistance2) {
Shinya Kitaoka 120a6e
          minDistance2   = distance2;
Shinya Kitaoka 120a6e
          m_strokeIndex1 = i;
Shinya Kitaoka 120a6e
          m_w1           = 0.0;
Shinya Kitaoka 120a6e
          // m_cpIndex1=0;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        cpMax = stroke->getControlPointCount() - 1;
Shinya Kitaoka 120a6e
        point = stroke->getControlPoint(cpMax);
Shinya Kitaoka 120a6e
        if ((distance2 = tdistance2(pos, point)) < minDistance2) {
Shinya Kitaoka 120a6e
          minDistance2   = distance2;
Shinya Kitaoka 120a6e
          m_strokeIndex1 = i;
Shinya Kitaoka 120a6e
          m_w1           = 1.0;
Shinya Kitaoka 120a6e
          // m_cpIndex1=cpMax;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override {
Shinya Kitaoka 120a6e
    if (!(TVectorImageP)getImage(false)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_type.getValue() == RECT) {
Shinya Kitaoka 120a6e
      m_startRect = pos;
Shinya Kitaoka 120a6e
    } else if (m_strokeIndex1 != -1)
Shinya Kitaoka 120a6e
      m_secondPoint = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &) override {
Shinya Kitaoka 120a6e
    TVectorImageP vi(getImage(false));
Shinya Kitaoka 120a6e
    if (!vi) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_type.getValue() == RECT) {
Shinya Kitaoka 120a6e
      m_selectionRect = TRectD(
Shinya Kitaoka 120a6e
          std::min(m_startRect.x, pos.x), std::min(m_startRect.y, pos.y),
Shinya Kitaoka 120a6e
          std::max(m_startRect.x, pos.x), std::max(m_startRect.y, pos.y));
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_strokeIndex1 == -1 || !m_secondPoint) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double minDistance2 = 900 * m_pixelSize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int i, strokeNumber = vi->getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *stroke;
Shinya Kitaoka 120a6e
    double distance2, outW;
Shinya Kitaoka 120a6e
    TPointD point;
Shinya Kitaoka 120a6e
    int cpMax;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_strokeIndex2 = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (i = 0; i < strokeNumber; i++) {
Shinya Kitaoka 120a6e
      if (!vi->sameGroup(m_strokeIndex1, i)) continue;
Shinya Kitaoka 120a6e
      stroke = vi->getStroke(i);
Shinya Kitaoka 120a6e
      if (m_mode.getValue() != POINT2POINT) {
Shinya Kitaoka 120a6e
        if (stroke->getNearestW(pos, outW, distance2) &&
Shinya Kitaoka 120a6e
            distance2 < minDistance2) {
Shinya Kitaoka 120a6e
          minDistance2   = distance2;
Shinya Kitaoka 120a6e
          m_strokeIndex2 = i;
Shinya Kitaoka 120a6e
          if (areAlmostEqual(outW, 0.0, 1e-3))
Shinya Kitaoka 120a6e
            m_w2 = 0.0;
Shinya Kitaoka 120a6e
          else if (areAlmostEqual(outW, 1.0, 1e-3))
Shinya Kitaoka 120a6e
            m_w2 = 1.0;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            m_w2 = outW;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (!stroke->isSelfLoop()) {
Shinya Kitaoka 120a6e
        cpMax = stroke->getControlPointCount() - 1;
Shinya Kitaoka 120a6e
        if (!(m_strokeIndex1 == i && (m_w1 == 0.0 || cpMax < 3))) {
Shinya Kitaoka 120a6e
          point = stroke->getControlPoint(0);
Shinya Kitaoka 120a6e
          if ((distance2 = tdistance2(pos, point)) < minDistance2) {
Shinya Kitaoka 120a6e
            minDistance2   = distance2;
Shinya Kitaoka 120a6e
            m_strokeIndex2 = i;
Shinya Kitaoka 120a6e
            m_w2           = 0.0;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (!(m_strokeIndex1 == i && (m_w1 == 1.0 || cpMax < 3))) {
Shinya Kitaoka 120a6e
          point = stroke->getControlPoint(cpMax);
Shinya Kitaoka 120a6e
          if ((distance2 = tdistance2(pos, point)) < minDistance2) {
Shinya Kitaoka 120a6e
            minDistance2   = distance2;
Shinya Kitaoka 120a6e
            m_strokeIndex2 = i;
Shinya Kitaoka 120a6e
            m_w2           = 1.0;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_pos = pos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void joinPointToPoint(const TVectorImageP &vi,
Shinya Kitaoka 120a6e
                        std::vector<tfilledregioninf> *fillInfo) {</tfilledregioninf>
Shinya Kitaoka 120a6e
    int minindex = std::min(m_strokeIndex1, m_strokeIndex2);
Shinya Kitaoka 120a6e
    int maxindex = std::max(m_strokeIndex1, m_strokeIndex2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    UndoAutoclose *autoCloseUndo = 0;
Shinya Kitaoka 120a6e
    TUndo *undo                  = 0;
Shinya Kitaoka 120a6e
    if (TTool::getApplication()->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
      undo =
Shinya Kitaoka 120a6e
          new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
          TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
      std::vector<int> v(1);</int>
Shinya Kitaoka 120a6e
      v[0]          = minindex;
Shinya Kitaoka 120a6e
      autoCloseUndo = new UndoAutoclose(level, getCurrentFid(), minindex,
Shinya Kitaoka 120a6e
                                        maxindex, fillInfo, v);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    VIStroke *newStroke = vi->joinStroke(
Shinya Kitaoka 120a6e
        m_strokeIndex1, m_strokeIndex2,
Shinya Kitaoka 120a6e
        (m_w1 == 0.0)
Shinya Kitaoka 120a6e
            ? 0
Shinya Kitaoka 120a6e
            : vi->getStroke(m_strokeIndex1)->getControlPointCount() - 1,
Shinya Kitaoka 120a6e
        (m_w2 == 0.0)
Shinya Kitaoka 120a6e
            ? 0
Shinya Kitaoka 120a6e
            : vi->getStroke(m_strokeIndex2)->getControlPointCount() - 1,
Shinya Kitaoka 120a6e
        m_smooth.getValue());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (autoCloseUndo) {
Shinya Kitaoka 120a6e
      autoCloseUndo->m_newStroke   = cloneVIStroke(newStroke);
Shinya Kitaoka 120a6e
      autoCloseUndo->m_newStrokeId = vi->getStroke(minindex)->getId();
Shinya Kitaoka 120a6e
      undo                         = autoCloseUndo;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    vi->notifyChangedStrokes(minindex);
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void joinPointToLine(const TVectorImageP &vi,
Shinya Kitaoka 120a6e
                       std::vector<tfilledregioninf> *fillInfo) {</tfilledregioninf>
Shinya Kitaoka 120a6e
    TUndo *undo                  = 0;
Shinya Kitaoka 120a6e
    UndoAutoclose *autoCloseUndo = 0;
Shinya Kitaoka 120a6e
    if (TTool::getApplication()->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
      undo =
Shinya Kitaoka 120a6e
          new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      std::vector<int> v(2);</int>
Shinya Kitaoka 120a6e
      v[0] = m_strokeIndex1;
Shinya Kitaoka 120a6e
      v[1] = m_strokeIndex2;
Shinya Kitaoka 120a6e
      TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
          TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
      autoCloseUndo = new UndoAutoclose(level, getCurrentFid(), m_strokeIndex1,
Shinya Kitaoka 120a6e
                                        -1, fillInfo, v);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    VIStroke *newStroke;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    newStroke = vi->extendStroke(
Shinya Kitaoka 120a6e
        m_strokeIndex1, vi->getStroke(m_strokeIndex2)->getThickPoint(m_w2),
Shinya Kitaoka 120a6e
        (m_w1 == 0.0)
Shinya Kitaoka 120a6e
            ? 0
Shinya Kitaoka 120a6e
            : vi->getStroke(m_strokeIndex1)->getControlPointCount() - 1,
Shinya Kitaoka 120a6e
        m_smooth.getValue());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (autoCloseUndo) {
Shinya Kitaoka 120a6e
      autoCloseUndo->m_newStroke   = cloneVIStroke(newStroke);
Shinya Kitaoka 120a6e
      autoCloseUndo->m_newStrokeId = vi->getStroke(m_strokeIndex1)->getId();
Shinya Kitaoka 120a6e
      undo                         = autoCloseUndo;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    vi->notifyChangedStrokes(m_strokeIndex1);
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void joinLineToLine(const TVectorImageP &vi,
Shinya Kitaoka 120a6e
                      std::vector<tfilledregioninf> *fillInfo) {</tfilledregioninf>
Shinya Kitaoka 120a6e
    if (TTool::getApplication()->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
      return;  // Caanot add vectros to spline... Spline can be only one
Shinya Kitaoka 120a6e
               // std::vector
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TThickPoint p1 = vi->getStroke(m_strokeIndex1)->getThickPoint(m_w1);
Shinya Kitaoka 120a6e
    TThickPoint p2 = vi->getStroke(m_strokeIndex2)->getThickPoint(m_w2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    UndoAutoclose *autoCloseUndo = 0;
Shinya Kitaoka 120a6e
    std::vector<int> v(2);</int>
Shinya Kitaoka 120a6e
    v[0] = m_strokeIndex1;
Shinya Kitaoka 120a6e
    v[1] = m_strokeIndex2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    autoCloseUndo =
Shinya Kitaoka 120a6e
        new UndoAutoclose(level, getCurrentFid(), -1, -1, fillInfo, v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points(3);</tthickpoint>
Shinya Kitaoka 120a6e
    points[0]          = p1;
Shinya Kitaoka 120a6e
    points[1]          = 0.5 * (p1 + p2);
Shinya Kitaoka 120a6e
    points[2]          = p2;
Shinya Kitaoka 120a6e
    TStroke *auxStroke = new TStroke(points);
Shinya Kitaoka 120a6e
    auxStroke->setStyle(TTool::getApplication()->getCurrentLevelStyleIndex());
Shinya Kitaoka 120a6e
    auxStroke->outlineOptions() =
Shinya Kitaoka 120a6e
        vi->getStroke(m_strokeIndex1)->outlineOptions();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int pos = vi->addStrokeToGroup(auxStroke, m_strokeIndex1);
Shinya Kitaoka 120a6e
    if (pos < 0) return;
Shinya Kitaoka 120a6e
    VIStroke *newStroke = vi->getVIStroke(pos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    autoCloseUndo->m_newStrokePos = pos;
Shinya Kitaoka 120a6e
    autoCloseUndo->m_newStroke    = cloneVIStroke(newStroke);
Shinya Kitaoka 120a6e
    autoCloseUndo->m_newStrokeId  = vi->getStroke(pos)->getId();
Shinya Kitaoka 120a6e
    vi->notifyChangedStrokes(v, std::vector<tstroke *="">());</tstroke>
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(autoCloseUndo);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void inline rearrangeClosingPoints(const TVectorImageP &vi,
Shinya Kitaoka 120a6e
                                     std::pair<int, double=""> &closingPoint,</int,>
Shinya Kitaoka 120a6e
                                     const TPointD &p) {
Shinya Kitaoka 120a6e
    int erasedIndex = std::max(m_strokeIndex1, m_strokeIndex2);
Shinya Kitaoka 120a6e
    int joinedIndex = std::min(m_strokeIndex1, m_strokeIndex2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (closingPoint.first == joinedIndex)
Shinya Kitaoka 120a6e
      closingPoint.second = vi->getStroke(joinedIndex)->getW(p);
Shinya Kitaoka 120a6e
    else if (closingPoint.first == erasedIndex) {
Shinya Kitaoka 120a6e
      closingPoint.first  = joinedIndex;
Shinya Kitaoka 120a6e
      closingPoint.second = vi->getStroke(joinedIndex)->getW(p);
Shinya Kitaoka 120a6e
    } else if (closingPoint.first > erasedIndex)
Shinya Kitaoka 120a6e
      closingPoint.first--;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define p2p 1
Toshihiro Shimizu 890ddd
#define p2l 2
Toshihiro Shimizu 890ddd
#define l2p 3
Toshihiro Shimizu 890ddd
#define l2l 4
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void tapeRect(const TVectorImageP &vi, const TRectD &rect) {
Shinya Kitaoka 120a6e
    std::vector<tfilledregioninf> *fillInformation =</tfilledregioninf>
Shinya Kitaoka 120a6e
        new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
    ImageUtils::getFillingInformationOverlappingArea(vi, *fillInformation,
Shinya Kitaoka 120a6e
                                                     rect);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool initUndoBlock = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<std::pair<int, double="">> startPoints, endPoints;</std::pair<int,>
Shinya Kitaoka 120a6e
    getClosingPoints(rect, m_autocloseFactor.getValue(), vi, startPoints,
Shinya Kitaoka 120a6e
                     endPoints);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    assert(startPoints.size() == endPoints.size());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::vector<tpointd> startP(startPoints.size()), endP(startPoints.size());</tpointd>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!startPoints.empty()) {
Shinya Kitaoka 120a6e
      TUndoManager::manager()->beginBlock();
Shinya Kitaoka 120a6e
      for (UINT i = 0; i < startPoints.size(); i++) {
Shinya Kitaoka 120a6e
        startP[i] = vi->getStroke(startPoints[i].first)
Shinya Kitaoka 120a6e
                        ->getPoint(startPoints[i].second);
Shinya Kitaoka 120a6e
        endP[i] =
Shinya Kitaoka 120a6e
            vi->getStroke(endPoints[i].first)->getPoint(endPoints[i].second);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < startPoints.size(); i++) {
Shinya Kitaoka 120a6e
      m_strokeIndex1 = startPoints[i].first;
Shinya Kitaoka 120a6e
      m_strokeIndex2 = endPoints[i].first;
Shinya Kitaoka 120a6e
      m_w1           = startPoints[i].second;
Shinya Kitaoka 120a6e
      m_w2           = endPoints[i].second;
Shinya Kitaoka 120a6e
      int type       = doTape(vi, fillInformation, m_joinStrokes.getValue());
Shinya Kitaoka 120a6e
      if (type == p2p && m_strokeIndex1 != m_strokeIndex2) {
Shinya Kitaoka 120a6e
        for (UINT j = i + 1; j < startPoints.size(); j++) {
Shinya Kitaoka 120a6e
          rearrangeClosingPoints(vi, startPoints[j], startP[j]);
Shinya Kitaoka 120a6e
          rearrangeClosingPoints(vi, endPoints[j], endP[j]);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else if (type == p2l ||
Shinya Kitaoka 120a6e
                 (type == p2p && m_strokeIndex1 == m_strokeIndex2)) {
Shinya Kitaoka 120a6e
        for (UINT j = i + 1; j < startPoints.size(); j++) {
Shinya Kitaoka 120a6e
          if (startPoints[j].first == m_strokeIndex1)
Shinya Kitaoka 120a6e
            startPoints[j].second =
Shinya Kitaoka 120a6e
                vi->getStroke(m_strokeIndex1)->getW(startP[j]);
Shinya Kitaoka 120a6e
          if (endPoints[j].first == m_strokeIndex1)
Shinya Kitaoka 120a6e
            endPoints[j].second = vi->getStroke(m_strokeIndex1)->getW(endP[j]);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!startPoints.empty()) TUndoManager::manager()->endBlock();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int doTape(const TVectorImageP &vi,
Shinya Kitaoka 120a6e
             std::vector<tfilledregioninf> *fillInformation, bool joinStrokes) {</tfilledregioninf>
Shinya Kitaoka 120a6e
    int type;
Shinya Kitaoka 120a6e
    if (!joinStrokes)
Shinya Kitaoka 120a6e
      type = l2l;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      type = (m_w1 == 0.0 || m_w1 == 1.0)
Shinya Kitaoka 120a6e
                 ? ((m_w2 == 0.0 || m_w2 == 1.0) ? p2p : p2l)
Shinya Kitaoka 120a6e
                 : ((m_w2 == 0.0 || m_w2 == 1.0) ? l2p : l2l);
Shinya Kitaoka 120a6e
      if (type == l2p) {
Shinya Kitaoka 120a6e
        tswap(m_strokeIndex1, m_strokeIndex2);
Shinya Kitaoka 120a6e
        tswap(m_w1, m_w2);
Shinya Kitaoka 120a6e
        type = p2l;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (type) {
Shinya Kitaoka 120a6e
    case p2p:
Shinya Kitaoka 120a6e
      joinPointToPoint(vi, fillInformation);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case p2l:
Shinya Kitaoka 120a6e
      joinPointToLine(vi, fillInformation);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case l2l:
Shinya Kitaoka 120a6e
      joinLineToLine(vi, fillInformation);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return type;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //-------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &, const TMouseEvent &) override {
Shinya Kitaoka 120a6e
    TVectorImageP vi(getImage(true));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (vi && m_type.getValue() == RECT) {
Shinya Kitaoka 120a6e
      tapeRect(vi, m_selectionRect);
Shinya Kitaoka 120a6e
      m_selectionRect = TRectD();
Shinya Kitaoka 120a6e
      m_startRect     = TPointD();
Shinya Kitaoka 120a6e
      notifyImageChanged();
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!vi || m_strokeIndex1 == -1 || !m_secondPoint || m_strokeIndex2 == -1) {
Shinya Kitaoka 120a6e
      m_strokeIndex1 = -1;
Shinya Kitaoka 120a6e
      m_strokeIndex2 = -1;
Shinya Kitaoka 120a6e
      m_w1           = -1.0;
Shinya Kitaoka 120a6e
      m_w2           = -1.0;
Shinya Kitaoka 120a6e
      m_secondPoint  = false;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    QMutexLocker lock(vi->getMutex());
Shinya Kitaoka 120a6e
    m_secondPoint = false;
Shinya Kitaoka 120a6e
    std::vector<tfilledregioninf> *fillInformation =</tfilledregioninf>
Shinya Kitaoka 120a6e
        new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
    ImageUtils::getFillingInformationOverlappingArea(
Shinya Kitaoka 120a6e
        vi, *fillInformation, vi->getStroke(m_strokeIndex1)->getBBox() +
Shinya Kitaoka 120a6e
                                  vi->getStroke(m_strokeIndex2)->getBBox());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    doTape(vi, fillInformation, m_joinStrokes.getValue());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_strokeIndex2 = -1;
Shinya Kitaoka 120a6e
    m_w1           = -1.0;
Shinya Kitaoka 120a6e
    m_w2           = -1.0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onEnter() override {
Shinya Kitaoka 120a6e
    //      getApplication()->editImage();
Shinya Kitaoka 120a6e
    m_draw          = true;
Shinya Kitaoka 120a6e
    m_selectionRect = TRectD();
Shinya Kitaoka 120a6e
    m_startRect     = TPointD();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onLeave() override {
Shinya Kitaoka 120a6e
    m_draw = false;
Shinya Kitaoka 120a6e
    // m_strokeIndex1=-1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onActivate() override {
Shinya Kitaoka 120a6e
    if (!m_firstTime) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::wstring s = ::to_wstring(TapeMode.getValue());
Shinya Kitaoka 120a6e
    if (s != L"") m_mode.setValue(s);
Shinya Kitaoka 120a6e
    s = ::to_wstring(TapeType.getValue());
Shinya Kitaoka 120a6e
    if (s != L"") m_type.setValue(s);
Shinya Kitaoka 120a6e
    m_autocloseFactor.setValue(AutocloseFactor);
Shinya Kitaoka 120a6e
    m_smooth.setValue(TapeSmooth ? 1 : 0);
Shinya Kitaoka 120a6e
    m_joinStrokes.setValue(TapeJoinStrokes ? 1 : 0);
Shinya Kitaoka 120a6e
    m_firstTime     = false;
Shinya Kitaoka 120a6e
    m_selectionRect = TRectD();
Shinya Kitaoka 120a6e
    m_startRect     = TPointD();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getCursorId() const override {
Shinya Kitaoka 120a6e
    if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg)
Shinya Kitaoka 120a6e
      return ToolCursor::TapeCursorWhite;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return ToolCursor::TapeCursor;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} vectorTapeTool;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// TTool *getAutocloseTool() {return &autocloseTool;}