Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "selectiontool.h"
Toshihiro Shimizu 890ddd
#include "rasterselectiontool.h"
Toshihiro Shimizu 890ddd
#include "vectorselectiontool.h"
Toshihiro Shimizu 890ddd
#include "tcurveutil.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "tw/keycodes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace ToolUtils;
Toshihiro Shimizu 890ddd
using namespace DragSelectionTool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TEnv::StringVar SelectionType("SelectionType", "Rectangular");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DragSelectionTool::DragTool *createNewMoveSelectionTool(SelectionTool *st) {
Shinya Kitaoka 120a6e
  VectorSelectionTool *vst = dynamic_cast<vectorselectiontool *="">(st);</vectorselectiontool>
Shinya Kitaoka 120a6e
  RasterSelectionTool *rst = dynamic_cast<rasterselectiontool *="">(st);</rasterselectiontool>
Shinya Kitaoka 120a6e
  if (vst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::VectorMoveSelectionTool(vst);
Shinya Kitaoka 120a6e
  else if (rst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::RasterMoveSelectionTool(rst);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DragSelectionTool::DragTool *createNewRotationTool(SelectionTool *st) {
Shinya Kitaoka 120a6e
  VectorSelectionTool *vst = dynamic_cast<vectorselectiontool *="">(st);</vectorselectiontool>
Shinya Kitaoka 120a6e
  RasterSelectionTool *rst = dynamic_cast<rasterselectiontool *="">(st);</rasterselectiontool>
Shinya Kitaoka 120a6e
  if (vst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::VectorRotationTool(vst);
Shinya Kitaoka 120a6e
  else if (rst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::RasterRotationTool(rst);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DragSelectionTool::DragTool *createNewFreeDeformTool(SelectionTool *st) {
Shinya Kitaoka 120a6e
  VectorSelectionTool *vst = dynamic_cast<vectorselectiontool *="">(st);</vectorselectiontool>
Shinya Kitaoka 120a6e
  RasterSelectionTool *rst = dynamic_cast<rasterselectiontool *="">(st);</rasterselectiontool>
Shinya Kitaoka 120a6e
  if (vst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::VectorFreeDeformTool(vst);
Shinya Kitaoka 120a6e
  else if (rst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::RasterFreeDeformTool(rst);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DragSelectionTool::DragTool *createNewScaleTool(SelectionTool *st, int type) {
Shinya Kitaoka 120a6e
  VectorSelectionTool *vst = dynamic_cast<vectorselectiontool *="">(st);</vectorselectiontool>
Shinya Kitaoka 120a6e
  RasterSelectionTool *rst = dynamic_cast<rasterselectiontool *="">(st);</rasterselectiontool>
Shinya Kitaoka 120a6e
  if (vst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::VectorScaleTool(vst, type);
Shinya Kitaoka 120a6e
  else if (rst)
Shinya Kitaoka 120a6e
    return new DragSelectionTool::RasterScaleTool(rst, type);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Return index of point with min x or y
Shinya Kitaoka 120a6e
int tminPoint(std::vector<tpointd> points, bool isX) {</tpointd>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  int index = 0;
Shinya Kitaoka 120a6e
  TPointD p = points[0];
Shinya Kitaoka 120a6e
  for (i = 1; i < (int)points.size(); i++) {
Shinya Kitaoka 120a6e
    TPointD nextP = points[i];
Shinya Kitaoka 120a6e
    if (isX && p.x < nextP.x || !isX && p.y < nextP.y) continue;
Shinya Kitaoka 120a6e
    index = i;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return index;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int tminPoint(TPointD p0, TPointD p1, bool isX) {
Shinya Kitaoka 120a6e
  std::vector<tpointd> v;</tpointd>
Shinya Kitaoka 120a6e
  v.push_back(p0);
Shinya Kitaoka 120a6e
  v.push_back(p1);
Shinya Kitaoka 120a6e
  return tminPoint(v, isX);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// FourPoints
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FourPoints DragSelectionTool::FourPoints::orderedPoints() const {
Shinya Kitaoka 120a6e
  FourPoints newPoints;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  std::vector<tpointd> allPoints;</tpointd>
Shinya Kitaoka 120a6e
  allPoints.push_back(m_p00);
Shinya Kitaoka 120a6e
  allPoints.push_back(m_p01);
Shinya Kitaoka 120a6e
  allPoints.push_back(m_p10);
Shinya Kitaoka 120a6e
  allPoints.push_back(m_p11);
Shinya Kitaoka 120a6e
  int minXindex1 = tminPoint(allPoints, true);
Shinya Kitaoka 120a6e
  std::vector<tpointd> points;</tpointd>
Shinya Kitaoka 120a6e
  for (i = 0; i < 4; i++)
Shinya Kitaoka 120a6e
    if (i != minXindex1) points.push_back(allPoints[i]);
Shinya Kitaoka 120a6e
  int minXindex2 = tminPoint(points, true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int index = tminPoint(allPoints[minXindex1], points[minXindex2], false);
Shinya Kitaoka 120a6e
  TPointD newPoint1 = allPoints[minXindex1];
Shinya Kitaoka 120a6e
  TPointD newPoint2 = points[minXindex2];
Shinya Kitaoka 120a6e
  if (index == 1) tswap(newPoint1, newPoint2);
Shinya Kitaoka 120a6e
  newPoints.setP00(newPoint1);
Shinya Kitaoka 120a6e
  newPoints.setP01(newPoint2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tpointd> points2;</tpointd>
Shinya Kitaoka 120a6e
  for (i = 0; i < 3; i++)
Shinya Kitaoka 120a6e
    if (i != minXindex2) points2.push_back(points[i]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  index = tminPoint(points2, false);
Shinya Kitaoka 120a6e
  newPoints.setP10(points2[index]);
Shinya Kitaoka 120a6e
  newPoints.setP11(points2[(index == 0) ? 1 : 0]);
Shinya Kitaoka 120a6e
  return newPoints;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD DragSelectionTool::FourPoints::getPoint(int index) const {
Shinya Kitaoka 120a6e
  if (index == 0)
Shinya Kitaoka 120a6e
    return m_p00;
Shinya Kitaoka 120a6e
  else if (index == 1)
Shinya Kitaoka 120a6e
    return m_p10;
Shinya Kitaoka 120a6e
  else if (index == 2)
Shinya Kitaoka 120a6e
    return m_p11;
Shinya Kitaoka 120a6e
  else if (index == 3)
Shinya Kitaoka 120a6e
    return m_p01;
Shinya Kitaoka 120a6e
  else if (index == 4)
Shinya Kitaoka 120a6e
    return (m_p00 + m_p10) * 0.5;
Shinya Kitaoka 120a6e
  else if (index == 5)
Shinya Kitaoka 120a6e
    return (m_p10 + m_p11) * 0.5;
Shinya Kitaoka 120a6e
  else if (index == 6)
Shinya Kitaoka 120a6e
    return (m_p11 + m_p01) * 0.5;
Shinya Kitaoka 120a6e
  else if (index == 7)
Shinya Kitaoka 120a6e
    return (m_p01 + m_p00) * 0.5;
Shinya Kitaoka 120a6e
  return TPointD();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::FourPoints::setPoint(int index, const TPointD &p) {
Shinya Kitaoka 120a6e
  if (index == 0)
Shinya Kitaoka 120a6e
    m_p00 = p;
Shinya Kitaoka 120a6e
  else if (index == 1)
Shinya Kitaoka 120a6e
    m_p10 = p;
Shinya Kitaoka 120a6e
  else if (index == 2)
Shinya Kitaoka 120a6e
    m_p11 = p;
Shinya Kitaoka 120a6e
  else if (index == 3)
Shinya Kitaoka 120a6e
    m_p01 = p;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FourPoints DragSelectionTool::FourPoints::enlarge(double d) {
Shinya Kitaoka 120a6e
  TPointD v   = normalize(getP10() - getP00());
Shinya Kitaoka 120a6e
  TPointD p00 = getP00() - d * v;
Shinya Kitaoka 120a6e
  TPointD p10 = getP10() + d * v;
Shinya Kitaoka 120a6e
  v           = normalize(getP11() - getP10());
Shinya Kitaoka 120a6e
  p10         = p10 - d * v;
Shinya Kitaoka 120a6e
  TPointD p11 = getP11() + d * v;
Shinya Kitaoka 120a6e
  v           = normalize(getP01() - getP11());
Shinya Kitaoka 120a6e
  p11         = p11 - d * v;
Shinya Kitaoka 120a6e
  TPointD p01 = getP01() + d * v;
Shinya Kitaoka 120a6e
  v           = normalize(getP00() - getP01());
Shinya Kitaoka 120a6e
  p01         = p01 - d * v;
Shinya Kitaoka 120a6e
  p00         = p00 + d * v;
Shinya Kitaoka 120a6e
  return FourPoints(p00, p01, p10, p11);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool DragSelectionTool::FourPoints::isEmpty() {
Shinya Kitaoka 120a6e
  return ((getP00().x == getP01().x && getP01().x == getP10().x &&
Shinya Kitaoka 120a6e
           getP10().x == getP11().x) ||
Shinya Kitaoka 120a6e
          (getP00().y == getP01().y && getP01().y == getP10().y &&
Shinya Kitaoka 120a6e
           getP10().y == getP11().y));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::FourPoints::empty() {
Shinya Kitaoka 120a6e
  m_p00 = TPointD();
Shinya Kitaoka 120a6e
  m_p01 = TPointD();
Shinya Kitaoka 120a6e
  m_p10 = TPointD();
Shinya Kitaoka 120a6e
  m_p11 = TPointD();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool DragSelectionTool::FourPoints::contains(TPointD p) {
Shinya Kitaoka 120a6e
  double maxDistance =
Shinya Kitaoka 120a6e
      std::max(tdistance2(getP00(), getP11()), tdistance2(getP10(), getP01()));
Shinya Kitaoka 120a6e
  TPointD outP = p + maxDistance * TPointD(1, 1);
Shinya Kitaoka 120a6e
  TSegment segment(outP, p);
Shinya Kitaoka 120a6e
  std::vector<doublepair> d;</doublepair>
Shinya Kitaoka 120a6e
  int inters = intersect(TSegment(getP00(), getP10()), segment, d);
Shinya Kitaoka 120a6e
  inters += intersect(TSegment(getP10(), getP11()), segment, d);
Shinya Kitaoka 120a6e
  inters += intersect(TSegment(getP11(), getP01()), segment, d);
Shinya Kitaoka 120a6e
  inters += intersect(TSegment(getP01(), getP00()), segment, d);
Shinya Kitaoka 120a6e
  return inters % 2 == 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD DragSelectionTool::FourPoints::getBox() const {
Shinya Kitaoka 120a6e
  double x0 = std::min({getP00().x, getP10().x, getP01().x, getP11().x});
Shinya Kitaoka 120a6e
  double y0 = std::min({getP00().y, getP10().y, getP01().y, getP11().y});
Shinya Kitaoka 120a6e
  double x1 = std::max({getP00().x, getP10().x, getP01().x, getP11().x});
Shinya Kitaoka 120a6e
  double y1 = std::max({getP00().y, getP10().y, getP01().y, getP11().y});
Shinya Kitaoka 120a6e
  return TRectD(TPointD(x0, y0), TPointD(x1, y1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FourPoints &DragSelectionTool::FourPoints::operator=(const TRectD &r) {
Shinya Kitaoka 120a6e
  setP00(r.getP00());
Shinya Kitaoka 120a6e
  setP01(r.getP01());
Shinya Kitaoka 120a6e
  setP10(r.getP10());
Shinya Kitaoka 120a6e
  setP11(r.getP11());
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool DragSelectionTool::FourPoints::operator==(const FourPoints &p) const {
Shinya Kitaoka 120a6e
  return getP00() == p.getP00() && getP01() == p.getP01() &&
Shinya Kitaoka 120a6e
         getP10() == p.getP10() && getP11() == p.getP11();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FourPoints DragSelectionTool::FourPoints::operator*(const TAffine &aff) const {
Shinya Kitaoka 120a6e
  FourPoints p;
Shinya Kitaoka 120a6e
  p.setP00(aff * getP00());
Shinya Kitaoka 120a6e
  p.setP10(aff * getP10());
Shinya Kitaoka 120a6e
  p.setP11(aff * getP11());
Shinya Kitaoka 120a6e
  p.setP01(aff * getP01());
Shinya Kitaoka 120a6e
  return p;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::drawFourPoints(const FourPoints &rect,
Shinya Kitaoka 120a6e
                                       const TPixel32 &color,
Shinya Kitaoka 120a6e
                                       unsigned short stipple,
Shinya Kitaoka 120a6e
                                       bool doContrast) {
Shinya Kitaoka 120a6e
  GLint src, dst;
Shinya Kitaoka 120a6e
  bool isEnabled;
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  if (doContrast) {
Shinya Kitaoka 120a6e
    if (color == TPixel32::Black) tglColor(TPixel32(90, 90, 90));
Shinya Kitaoka 120a6e
    isEnabled = glIsEnabled(GL_BLEND);
Shinya Kitaoka 120a6e
    glGetIntegerv(GL_BLEND_SRC, &src);
Shinya Kitaoka 120a6e
    glGetIntegerv(GL_BLEND_DST, &dst);
Shinya Kitaoka 120a6e
    glEnable(GL_BLEND);
Shinya Kitaoka 120a6e
    glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (stipple != 0xffff) {
Shinya Kitaoka 120a6e
    glLineStipple(1, stipple);
Shinya Kitaoka 120a6e
    glEnable(GL_LINE_STIPPLE);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP01());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP11());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP10());
Shinya Kitaoka 120a6e
  tglVertex(rect.getP00());
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
  glDisable(GL_LINE_STIPPLE);
Shinya Kitaoka 120a6e
  if (doContrast) {
Shinya Kitaoka 120a6e
    if (!isEnabled) glDisable(GL_BLEND);
Shinya Kitaoka 120a6e
    glBlendFunc(src, dst);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// UndoMoveCenter
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UndoMoveCenter final : public TUndo {
Shinya Kitaoka 120a6e
  SelectionTool *m_tool;
Shinya Kitaoka 120a6e
  TAffine m_aff;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UndoMoveCenter(SelectionTool *tool, const TAffine &aff)
Shinya Kitaoka 120a6e
      : m_tool(tool), m_aff(aff) {}
Shinya Kitaoka 120a6e
  ~UndoMoveCenter() {}
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    m_tool->setCenter(m_aff.inv() * m_tool->getCenter());
Shinya Kitaoka 120a6e
    m_tool->invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    m_tool->setCenter(m_aff * m_tool->getCenter());
Shinya Kitaoka 120a6e
    m_tool->invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this) + sizeof(*m_tool); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getHistoryString() override { return QObject::tr("Move Center"); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MoveCenterTool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MoveCenterTool final : public DragTool {
Shinya Kitaoka 120a6e
  TPointD m_startPos;
Shinya Kitaoka 120a6e
  TAffine m_transform;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MoveCenterTool(SelectionTool *tool)
Shinya Kitaoka 120a6e
      : DragTool(tool), m_startPos(), m_transform() {}
Shinya Kitaoka 120a6e
  void translateCenter(TAffine aff) {
Shinya Kitaoka 120a6e
    getTool()->setCenter(aff * getTool()->getCenter());
Shinya Kitaoka 120a6e
    m_transform *= aff;
Shinya Kitaoka 120a6e
    getTool()->invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override {
Shinya Kitaoka 120a6e
    m_startPos = pos;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override {
Shinya Kitaoka 120a6e
    TPointD delta      = pos - m_startPos;
Shinya Kitaoka 120a6e
    FourPoints bbox    = getTool()->getBBox();
Shinya Kitaoka 120a6e
    TPointD bboxCenter = 0.5 * (bbox.getP11() + bbox.getP00());
Shinya Kitaoka 120a6e
    double maxDistance2 =
Shinya Kitaoka 120a6e
        32 * getTool()->getPixelSize() * getTool()->getPixelSize();
Shinya Kitaoka 120a6e
    TAffine aff       = m_transform.inv() * TTranslation(delta);
Shinya Kitaoka 120a6e
    TPointD newCenter = aff * getTool()->getCenter();
Shinya Kitaoka 120a6e
    if (tdistance2(newCenter, bboxCenter) < maxDistance2)
Shinya Kitaoka 120a6e
      translateCenter(TTranslation(bboxCenter - getTool()->getCenter()));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      translateCenter(aff);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override {
Shinya Kitaoka 120a6e
    UndoMoveCenter *undo = new UndoMoveCenter(getTool(), m_transform);
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void draw() override {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// DeformTool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DragSelectionTool::DeformTool::DeformTool(SelectionTool *tool)
Shinya Kitaoka 120a6e
    : DragTool(tool)
Shinya Kitaoka 120a6e
    , m_curPos()
Shinya Kitaoka 120a6e
    , m_isDragging(false)
Shinya Kitaoka 120a6e
    , m_startScaleValue(tool->m_deformValues.m_scaleValue) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int DragSelectionTool::DeformTool::getSimmetricPointIndex(int index) const {
Shinya Kitaoka 120a6e
  if (index == 0 || index == 4 || index == 1 || index == 5) return index + 2;
Shinya Kitaoka 120a6e
  return index - 2;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int DragSelectionTool::DeformTool::getBeforePointIndex(int index) const {
Shinya Kitaoka 120a6e
  if (index < 4) return (index == 0) ? 7 : index + 3;
Shinya Kitaoka 120a6e
  return index - 4;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int DragSelectionTool::DeformTool::getNextPointIndex(int index) const {
Shinya Kitaoka 120a6e
  if (index < 4) return index + 4;
Shinya Kitaoka 120a6e
  return (index == 7) ? 0 : index - 3;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int DragSelectionTool::DeformTool::getBeforeVertexIndex(int index) const {
Shinya Kitaoka 120a6e
  if (index < 4) return (index == 0) ? 3 : index - 1;
Shinya Kitaoka 120a6e
  return index - 4;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int DragSelectionTool::DeformTool::getNextVertexIndex(int index) const {
Shinya Kitaoka 120a6e
  if (index < 4) return (index == 3) ? 0 : index + 1;
Shinya Kitaoka 120a6e
  return (index == 7) ? 0 : index - 3;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::DeformTool::leftButtonDown(const TPointD &pos,
Shinya Kitaoka 120a6e
                                                   const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  m_isDragging = true;
Shinya Kitaoka 120a6e
  m_curPos     = pos;
Shinya Kitaoka 120a6e
  setStartPos(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::DeformTool::leftButtonUp(const TPointD &pos,
Shinya Kitaoka 120a6e
                                                 const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  addTransformUndo();
Shinya Kitaoka 120a6e
  m_isDragging = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Rotation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DragSelectionTool::Rotation::Rotation(DeformTool *deformTool)
Shinya Kitaoka 120a6e
    : m_curAng(), m_dstAng(), m_deformTool(deformTool) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD DragSelectionTool::Rotation::getStartCenter() const {
Shinya Kitaoka 120a6e
  return m_deformTool->getTool()->getCenter();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::Rotation::leftButtonDrag(const TPointD &pos,
Shinya Kitaoka 120a6e
                                                 const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  SelectionTool *tool  = m_deformTool->getTool();
Shinya Kitaoka 120a6e
  TPointD center       = tool->getCenter();
Shinya Kitaoka 120a6e
  TPointD curPos       = m_deformTool->getCurPos();
Shinya Kitaoka 120a6e
  TPointD delta        = pos - curPos;
Shinya Kitaoka 120a6e
  TPointD a            = pos - center;
Shinya Kitaoka 120a6e
  TPointD b            = (pos - delta) - center;
Shinya Kitaoka 120a6e
  double a2            = norm2(a);
Shinya Kitaoka 120a6e
  double b2            = norm2(b);
Shinya Kitaoka 120a6e
  const double epsilon = 1e-8;
Shinya Kitaoka 120a6e
  double dang          = 0;
Shinya Kitaoka 120a6e
  double scale         = 1;
Shinya Kitaoka 120a6e
  if (a2 <= epsilon || b2 <= epsilon) return;
Shinya Kitaoka 120a6e
  dang = asin(cross(a, b) / sqrt(a2 * b2)) * -M_180_PI;
Shinya Kitaoka 120a6e
  if (e.isShiftPressed()) {
Shinya Kitaoka 120a6e
    m_dstAng += dang;
Shinya Kitaoka 120a6e
    double ang = tfloor((int)(m_dstAng + 22.5), 45);
Shinya Kitaoka 120a6e
    dang       = ang - m_curAng;
Shinya Kitaoka 120a6e
    m_curAng   = ang;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_dstAng += dang;
Shinya Kitaoka 120a6e
    dang     = m_dstAng - m_curAng;
Shinya Kitaoka 120a6e
    m_curAng = m_dstAng;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  tool->m_deformValues.m_rotationAngle =
Shinya Kitaoka 120a6e
      tool->m_deformValues.m_rotationAngle + dang;
Shinya Kitaoka 120a6e
  m_deformTool->transform(TRotation(center, dang), dang);
Shinya Kitaoka 120a6e
  m_deformTool->setCurPos(pos);
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->notifyToolChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::Rotation::draw() {
Shinya Kitaoka 120a6e
  tglDrawSegment(m_deformTool->getCurPos(),
Shinya Kitaoka 120a6e
                 m_deformTool->getTool()->getCenter());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// FreeDeform
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DragSelectionTool::FreeDeform::FreeDeform(DeformTool *deformTool)
Shinya Kitaoka 120a6e
    : m_deformTool(deformTool) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void DragSelectionTool::FreeDeform::leftButtonDrag(const TPointD &pos,
Shinya Kitaoka 120a6e
                                                   const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  SelectionTool *tool = m_deformTool->getTool();
Shinya Kitaoka 120a6e
  TPointD delta       = pos - m_deformTool->getCurPos();
Shinya Kitaoka 120a6e
  TPointD center      = tool->getCenter();
Shinya Kitaoka 120a6e
  int index           = tool->getSelectedPoint();
Shinya Kitaoka 120a6e
  FourPoints bbox     = tool->getBBox();
Shinya Kitaoka 120a6e
  FourPoints newBbox  = bbox;
Shinya Kitaoka 120a6e
  if (index < 4)
Shinya Kitaoka 120a6e
    bbox.setPoint(index, bbox.getPoint(index) + delta);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    int beforeIndex = m_deformTool->getBeforeVertexIndex(index);
Shinya Kitaoka 120a6e
    bbox.setPoint(beforeIndex, bbox.getPoint(beforeIndex) + delta);
Shinya Kitaoka 120a6e
    bbox.setPoint(index, bbox.getPoint(index) + delta);
Shinya Kitaoka 120a6e
    int nextIndex = m_deformTool->getNextVertexIndex(index);
Shinya Kitaoka 120a6e
    bbox.setPoint(nextIndex, bbox.getPoint(nextIndex) + delta);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  tool->setBBox(bbox);
Shinya Kitaoka 120a6e
  m_deformTool->setCurPos(pos);
Shinya Kitaoka 120a6e
  m_deformTool->applyTransform(bbox);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MoveSelection
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DragSelectionTool::MoveSelection::MoveSelection(DeformTool *deformTool)
Shinya Kitaoka 120a6e
    : m_deformTool(deformTool), m_lastDelta(), m_firstPos() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::MoveSelection::leftButtonDown(const TPointD &pos,
Shinya Kitaoka 120a6e
                                                      const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  m_deformTool->setCurPos(pos);
Shinya Kitaoka 120a6e
  m_firstPos = pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void DragSelectionTool::MoveSelection::leftButtonDrag(const TPointD &pos,
Shinya Kitaoka 120a6e
                                                      const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  TAffine aff;
Shinya Kitaoka 120a6e
  TPointD curPos = m_deformTool->getCurPos();
Shinya Kitaoka 120a6e
  TPointD delta  = pos - curPos;
Shinya Kitaoka 120a6e
  if (e.isShiftPressed()) {
Shinya Kitaoka 120a6e
    if (m_lastDelta == TPointD()) {
Shinya Kitaoka 120a6e
      TPointD totalDelta = curPos - m_firstPos;
Shinya Kitaoka 120a6e
      aff                = TTranslation(totalDelta).inv();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      aff = TTranslation(m_lastDelta).inv();
Shinya Kitaoka 120a6e
    if (fabs((curPos - m_firstPos).x) > fabs((curPos - m_firstPos).y))
Shinya Kitaoka 120a6e
      m_lastDelta = TPointD((curPos - m_firstPos).x, 0);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_lastDelta = TPointD(0, (curPos - m_firstPos).y);
Shinya Kitaoka 120a6e
    aff *= TTranslation(m_lastDelta);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    aff         = TTranslation(delta);
Shinya Kitaoka 120a6e
  double factor = 1.0 / Stage::inch;
Shinya Kitaoka 120a6e
  m_deformTool->getTool()->m_deformValues.m_moveValue =
Shinya Kitaoka 120a6e
      m_deformTool->getTool()->m_deformValues.m_moveValue + factor * delta;
Shinya Kitaoka 120a6e
  m_deformTool->transform(aff);
Shinya Kitaoka 120a6e
  m_deformTool->setCurPos(pos);
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->notifyToolChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Scale
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DragSelectionTool::Scale::Scale(DeformTool *deformTool, int type)
Shinya Kitaoka 120a6e
    : m_deformTool(deformTool)
Shinya Kitaoka 120a6e
    , m_startCenter(deformTool->getTool()->getCenter())
Shinya Kitaoka 120a6e
    , m_type(type)
Shinya Kitaoka 120a6e
    , m_isShiftPressed(false)
Shinya Kitaoka 120a6e
    , m_isAltPressed(false)
Shinya Kitaoka 120a6e
    , m_scaleInCenter(true) {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)m_deformTool->getTool()->getBBoxsCount(); i++)
Shinya Kitaoka 120a6e
    m_startBboxs.push_back(m_deformTool->getTool()->getBBox(i));
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TPointD DragSelectionTool::Scale::getIntersectionPoint(const TPointD &point0,
Shinya Kitaoka 120a6e
                                                       const TPointD &point1,
Shinya Kitaoka 120a6e
                                                       const TPointD &point2,
Shinya Kitaoka 120a6e
                                                       const TPointD &point3,
Shinya Kitaoka 120a6e
                                                       const TPointD &p) const {
Shinya Kitaoka 120a6e
  // Parametri della retta passante per point0, point1
Shinya Kitaoka 120a6e
  double d1x = point0.x - point1.x;
Shinya Kitaoka 120a6e
  double m1  = d1x == 0 ? 0 : (point0.y - point1.y) / d1x;
Shinya Kitaoka 120a6e
  double q1  = point1.y - m1 * point1.x;
Shinya Kitaoka 120a6e
  // Parametri della retta passante per p parallela alla retta passante per
Shinya Kitaoka 120a6e
  // point1, point2
Shinya Kitaoka 120a6e
  double d2x = point2.x - point3.x;
Shinya Kitaoka 120a6e
  double m2  = d2x == 0 ? 0 : (point2.y - point3.y) / d2x;
Shinya Kitaoka 120a6e
  double q2  = p.y - m2 * p.x;
Shinya Kitaoka 120a6e
  // Calcolo l'intersezione tra le due rette
Shinya Kitaoka 120a6e
  double x, y, m, q;
Shinya Kitaoka 120a6e
  if (d1x == 0) {
Shinya Kitaoka 120a6e
    x = point0.x;
Shinya Kitaoka 120a6e
    m = m2;
Shinya Kitaoka 120a6e
    q = q2;
Shinya Kitaoka 120a6e
  } else if (d2x == 0) {
Shinya Kitaoka 120a6e
    x = p.x;
Shinya Kitaoka 120a6e
    m = m1;
Shinya Kitaoka 120a6e
    q = q1;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(m1 != m2);
Shinya Kitaoka 120a6e
    x = (q1 - q2) / (m2 - m1);
Shinya Kitaoka 120a6e
    m = m1;
Shinya Kitaoka 120a6e
    q = q1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  y = m * x + q;
Shinya Kitaoka 120a6e
  return TPointD(x, y);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
DragSelectionTool::FourPoints DragSelectionTool::Scale::bboxScale(
Shinya Kitaoka 120a6e
    int index, const FourPoints &oldBbox, const TPointD &pos) {
Shinya Kitaoka 120a6e
  FourPoints bbox = oldBbox;
Shinya Kitaoka 120a6e
  TPointD p       = oldBbox.getPoint(index);
Shinya Kitaoka 120a6e
  int nextIndex   = m_deformTool->getNextVertexIndex(index);
Shinya Kitaoka 120a6e
  TPointD nextP   = oldBbox.getPoint(nextIndex);
Shinya Kitaoka 120a6e
  int nextIndex2  = m_deformTool->getNextVertexIndex(nextIndex);
Shinya Kitaoka 120a6e
  TPointD next2P  = oldBbox.getPoint(nextIndex2);
Shinya Kitaoka 120a6e
  TPointD newP    = getIntersectionPoint(next2P, nextP, nextP, p, pos);
Shinya Kitaoka 120a6e
  bbox.setPoint(nextIndex, newP);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int beforeIndex  = m_deformTool->getBeforeVertexIndex(index);
Shinya Kitaoka 120a6e
  TPointD beforeP  = oldBbox.getPoint(beforeIndex);
Shinya Kitaoka 120a6e
  int before2Index = m_deformTool->getBeforeVertexIndex(beforeIndex);
Shinya Kitaoka 120a6e
  TPointD before2P = oldBbox.getPoint(before2Index);
Shinya Kitaoka 120a6e
  newP             = getIntersectionPoint(before2P, beforeP, beforeP, p, pos);
Shinya Kitaoka 120a6e
  bbox.setPoint(beforeIndex, newP);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (index < 4) bbox.setPoint(index, pos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return bbox;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TPointD DragSelectionTool::Scale::computeScaleValue(int movedIndex,
Shinya Kitaoka 120a6e
                                                    const FourPoints newBbox) {
Shinya Kitaoka 120a6e
  TPointD p = m_startBboxs[0].getPoint(movedIndex);
Shinya Kitaoka 120a6e
  if (movedIndex < 4) {
Shinya Kitaoka 120a6e
    int beforeIndex = m_deformTool->getBeforePointIndex(movedIndex);
Shinya Kitaoka 120a6e
    int nextIndex   = m_deformTool->getNextPointIndex(movedIndex);
Shinya Kitaoka 120a6e
    FourPoints bbox = bboxScale(nextIndex, newBbox, p);
Shinya Kitaoka 120a6e
    TPointD scale1  = computeScaleValue(beforeIndex, bbox);
Shinya Kitaoka 120a6e
    bbox            = bboxScale(beforeIndex, newBbox, p);
Shinya Kitaoka 120a6e
    TPointD scale2  = computeScaleValue(nextIndex, bbox);
Shinya Kitaoka 120a6e
    if (movedIndex % 2 == 0)
Shinya Kitaoka 120a6e
      return TPointD(scale1.x, scale2.y);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return TPointD(scale2.x, scale1.y);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int simmetricIndex = m_deformTool->getSimmetricPointIndex(movedIndex);
Shinya Kitaoka 120a6e
  TPointD s          = m_startBboxs[0].getPoint(simmetricIndex);
Shinya Kitaoka 120a6e
  TPointD center     = m_scaleInCenter ? m_startCenter : s;
Shinya Kitaoka 120a6e
  TPointD nearP =
Shinya Kitaoka 120a6e
      m_startBboxs[0].getPoint(m_deformTool->getBeforePointIndex(movedIndex));
Shinya Kitaoka 120a6e
  TPointD pc   = getIntersectionPoint(nearP, p, p, s, center);
Shinya Kitaoka 120a6e
  TPointD newp = newBbox.getPoint(movedIndex);
Shinya Kitaoka 120a6e
  TPointD news = newBbox.getPoint(simmetricIndex);
Shinya Kitaoka 120a6e
  TPointD newNearP =
Shinya Kitaoka 120a6e
      newBbox.getPoint(m_deformTool->getBeforePointIndex(movedIndex));
Shinya Kitaoka 120a6e
  TPointD newpc = getIntersectionPoint(newNearP, newp, newp, news, center);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double newD             = tdistance2(newpc, center);
Shinya Kitaoka 120a6e
  double oldD             = tdistance2(pc, center);
Shinya Kitaoka 120a6e
  double f                = sqrt(newD / oldD) - 1;
Shinya Kitaoka 120a6e
  TPointD startScaleValue = m_deformTool->getStartScaleValue();
Shinya Kitaoka 120a6e
  if (movedIndex % 2 == 1) {
Shinya Kitaoka 120a6e
    double sign = (pc.x < center.x && newpc.x < center.x) ||
Shinya Kitaoka 120a6e
                          (pc.x > center.x && newpc.x > center.x)
Shinya Kitaoka 120a6e
                      ? 1
Shinya Kitaoka 120a6e
                      : -1;
Shinya Kitaoka 120a6e
    double x =
Shinya Kitaoka 120a6e
        startScaleValue.x == 0 ? f : startScaleValue.x + startScaleValue.x * f;
Shinya Kitaoka 120a6e
    return TPointD(sign * x, startScaleValue.y);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    double sign = (pc.y < center.y && newpc.y < center.y) ||
Shinya Kitaoka 120a6e
                          (pc.y > center.y && newpc.y > center.y)
Shinya Kitaoka 120a6e
                      ? 1
Shinya Kitaoka 120a6e
                      : -1;
Shinya Kitaoka 120a6e
    double y =
Shinya Kitaoka 120a6e
        startScaleValue.y == 0 ? f : startScaleValue.y + startScaleValue.y * f;
Shinya Kitaoka 120a6e
    return TPointD(startScaleValue.x, sign * y);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TPointD DragSelectionTool::Scale::getScaledPoint(int index,
Shinya Kitaoka 120a6e
                                                 const FourPoints &oldBbox,
Shinya Kitaoka 120a6e
                                                 const TPointD scaleValue,
Shinya Kitaoka 120a6e
                                                 const TPointD center) {
Shinya Kitaoka 120a6e
  TPointD p          = oldBbox.getPoint(index);
Shinya Kitaoka 120a6e
  int simmetricIndex = m_deformTool->getSimmetricPointIndex(index);
Shinya Kitaoka 120a6e
  TPointD s          = oldBbox.getPoint(simmetricIndex);
Shinya Kitaoka 120a6e
  if (index < 4) {
Shinya Kitaoka 120a6e
    int beforeIndex = m_deformTool->getBeforePointIndex(index);
Shinya Kitaoka 120a6e
    int nextIndex   = m_deformTool->getNextPointIndex(index);
Shinya Kitaoka 120a6e
    TPointD newbp   = getScaledPoint(beforeIndex, oldBbox, scaleValue, center);
Shinya Kitaoka 120a6e
    TPointD newnp   = getScaledPoint(nextIndex, oldBbox, scaleValue, center);
Shinya Kitaoka 120a6e
    TPointD bp = oldBbox.getPoint(m_deformTool->getBeforePointIndex(index));
Shinya Kitaoka 120a6e
    TPointD np = oldBbox.getPoint(m_deformTool->getNextPointIndex(index));
Shinya Kitaoka 120a6e
    TPointD in = getIntersectionPoint(np, p, bp, p, newbp);
Shinya Kitaoka 120a6e
    return getIntersectionPoint(newbp, in, np, p, newnp);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TPointD nearP = oldBbox.getPoint(m_deformTool->getBeforePointIndex(index));
Shinya Kitaoka 120a6e
  TPointD nearS =
Shinya Kitaoka 120a6e
      oldBbox.getPoint(m_deformTool->getBeforePointIndex(simmetricIndex));
Shinya Kitaoka 120a6e
  TPointD pc = getIntersectionPoint(nearP, p, p, s, center);
Shinya Kitaoka 120a6e
  TPointD sc = getIntersectionPoint(nearS, s, p, s, center);
Shinya Kitaoka 120a6e
  if (center == pc) return pc;
Shinya Kitaoka 120a6e
  TPointD v       = normalize(center - pc);
Shinya Kitaoka 120a6e
  double currentD = tdistance(sc, pc);
Shinya Kitaoka 120a6e
  double startD   = (index % 2 == 1)
Shinya Kitaoka 120a6e
                      ? currentD / m_deformTool->getStartScaleValue().x
Shinya Kitaoka 120a6e
                      : currentD / m_deformTool->getStartScaleValue().y;
Shinya Kitaoka 120a6e
  double factor = (index % 2 == 1) ? scaleValue.x : scaleValue.y;
Shinya Kitaoka 120a6e
  double d = (currentD - startD * factor) * tdistance(center, pc) / currentD;
Shinya Kitaoka 120a6e
  return TPointD(pc.x + d * v.x, pc.y + d * v.y);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
TPointD DragSelectionTool::Scale::getNewCenter(int index, const FourPoints bbox,
Shinya Kitaoka 120a6e
                                               const TPointD scaleValue) {
Shinya Kitaoka 120a6e
  int xIndex, yIndex;
Shinya Kitaoka 120a6e
  if (index < 4) {
Shinya Kitaoka 120a6e
    xIndex = m_deformTool->getBeforePointIndex(index);
Shinya Kitaoka 120a6e
    yIndex = m_deformTool->getNextPointIndex(index);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    xIndex =
Shinya Kitaoka 120a6e
        m_deformTool->getNextPointIndex(m_deformTool->getNextPointIndex(index));
Shinya Kitaoka 120a6e
    yIndex = index;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (index % 2 == 1) tswap(xIndex, yIndex);
Shinya Kitaoka 120a6e
  FourPoints xBbox = bboxScale(xIndex, bbox, m_startCenter);
Shinya Kitaoka 120a6e
  TPointD xCenter  = getScaledPoint(
Shinya Kitaoka 120a6e
      xIndex, xBbox, scaleValue,
Shinya Kitaoka 120a6e
      xBbox.getPoint(m_deformTool->getSimmetricPointIndex(xIndex)));
Shinya Kitaoka 120a6e
  FourPoints yBbox = bboxScale(yIndex, bbox, m_startCenter);
Shinya Kitaoka 120a6e
  TPointD yCenter  = getScaledPoint(
Shinya Kitaoka 120a6e
      yIndex, yBbox, scaleValue,
Shinya Kitaoka 120a6e
      yBbox.getPoint(m_deformTool->getSimmetricPointIndex(yIndex)));
Shinya Kitaoka 120a6e
  TPointD in = getIntersectionPoint(bbox.getP00(), bbox.getP10(), bbox.getP10(),
Shinya Kitaoka 120a6e
                                    bbox.getP11(), xCenter);
Shinya Kitaoka 120a6e
  return getIntersectionPoint(in, xCenter, bbox.getP00(), bbox.getP10(),
Shinya Kitaoka 120a6e
                              yCenter);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
FourPoints DragSelectionTool::Scale::bboxScaleInCenter(
Shinya Kitaoka 120a6e
    int index, const FourPoints &oldBbox, const TPointD newPos,
Shinya Kitaoka 120a6e
    TPointD &scaleValue, const TPointD center, bool recomputeScaleValue) {
Shinya Kitaoka 120a6e
  TPointD oldp = oldBbox.getPoint(index);
Shinya Kitaoka 120a6e
  if (areAlmostEqual(oldp.x, newPos.x, 1e-2) &&
Shinya Kitaoka 120a6e
      areAlmostEqual(oldp.y, newPos.y, 1e-2))
Shinya Kitaoka 120a6e
    return oldBbox;
Shinya Kitaoka 120a6e
  FourPoints bbox                     = bboxScale(index, oldBbox, newPos);
Shinya Kitaoka 120a6e
  if (recomputeScaleValue) scaleValue = computeScaleValue(index, bbox);
Shinya Kitaoka 120a6e
  if (!m_scaleInCenter) return bbox;
Shinya Kitaoka 120a6e
  int simmetricIndex = m_deformTool->getSimmetricPointIndex(index);
Shinya Kitaoka 120a6e
  // Gestisco il caso particolare in cui uno dei fattori di scalatura e' -100% e
Shinya Kitaoka 120a6e
  // center e' al centro della bbox
Shinya Kitaoka 120a6e
  if (bbox.getPoint(index) == oldBbox.getPoint(simmetricIndex)) {
Shinya Kitaoka 120a6e
    bbox.setPoint(simmetricIndex, oldBbox.getPoint(index));
Shinya Kitaoka 120a6e
    bbox.setPoint(m_deformTool->getNextPointIndex(simmetricIndex),
Shinya Kitaoka 120a6e
                  oldBbox.getPoint(m_deformTool->getBeforePointIndex(index)));
Shinya Kitaoka 120a6e
    bbox.setPoint(m_deformTool->getBeforePointIndex(simmetricIndex),
Shinya Kitaoka 120a6e
                  oldBbox.getPoint(m_deformTool->getNextPointIndex(index)));
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    bbox =
Shinya Kitaoka 120a6e
        bboxScale(simmetricIndex, bbox,
Shinya Kitaoka 120a6e
                  getScaledPoint(simmetricIndex, oldBbox, scaleValue, center));
Shinya Kitaoka 120a6e
  return bbox;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void DragSelectionTool::Scale::leftButtonDown(const TPointD &pos,
Shinya Kitaoka 120a6e
                                              const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  m_isShiftPressed = e.isShiftPressed();
Shinya Kitaoka 120a6e
  m_isAltPressed   = e.isAltPressed();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void DragSelectionTool::Scale::leftButtonDrag(const TPointD &pos,
Shinya Kitaoka 120a6e
                                              const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  SelectionTool *tool = m_deformTool->getTool();
Shinya Kitaoka 120a6e
  bool isBboxReset    = false;
Shinya Kitaoka 120a6e
  if (m_isShiftPressed != e.isShiftPressed() ||
Shinya Kitaoka 120a6e
      m_isAltPressed != e.isAltPressed()) {
Shinya Kitaoka 120a6e
    m_deformTool->applyTransform(m_startBboxs[0]);
Shinya Kitaoka 120a6e
    tool->setBBox(m_startBboxs[0]);
Shinya Kitaoka 120a6e
    tool->setCenter(m_startCenter);
Shinya Kitaoka 120a6e
    isBboxReset      = true;
Shinya Kitaoka 120a6e
    m_isShiftPressed = e.isShiftPressed();
Shinya Kitaoka 120a6e
    m_isAltPressed   = e.isAltPressed();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TPointD newPos    = pos;
Shinya Kitaoka 120a6e
  int selectedIndex = tool->getSelectedPoint();
Shinya Kitaoka 120a6e
  if (m_isShiftPressed && m_type == GLOBAL) {
Shinya Kitaoka 120a6e
    TPointD point = tool->getBBox().getPoint(selectedIndex);
Shinya Kitaoka 120a6e
    TPointD delta;
Shinya Kitaoka 120a6e
    if (!isBboxReset)
Shinya Kitaoka 120a6e
      delta = pos - m_deformTool->getCurPos();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      delta            = pos - m_deformTool->getStartPos();
Shinya Kitaoka 120a6e
    int simmetricIndex = m_deformTool->getSimmetricPointIndex(selectedIndex);
Shinya Kitaoka 120a6e
    TPointD simmetricPoint = tool->getBBox().getPoint(simmetricIndex);
Shinya Kitaoka 120a6e
    TPointD v              = normalize(point - simmetricPoint);
Shinya Kitaoka 120a6e
    delta                  = v * (v * delta);
Shinya Kitaoka 120a6e
    newPos                 = point + delta;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_scaleInCenter = m_isAltPressed;
Shinya Kitaoka 120a6e
  m_deformTool->setCurPos(pos);
Shinya Kitaoka 120a6e
  TPointD scaleValue = m_deformTool->transform(selectedIndex, newPos);
Shinya Kitaoka 120a6e
  tool->m_deformValues.m_scaleValue = scaleValue;
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->notifyToolChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// SelectionTool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
SelectionTool::SelectionTool(int targetType)
Shinya Kitaoka 120a6e
    : TTool("T_Selection")
Shinya Kitaoka 120a6e
    , m_firstTime(true)
Shinya Kitaoka 120a6e
    , m_dragTool(0)
Shinya Kitaoka 120a6e
    , m_what(Outside)
Shinya Kitaoka 120a6e
    , m_leftButtonMousePressed(false)
Shinya Kitaoka 120a6e
    , m_shiftPressed(false)
Shinya Kitaoka 120a6e
    , m_selecting(false)
Shinya Kitaoka 120a6e
    , m_mousePosition(TPointD())
Shinya Kitaoka 120a6e
    , m_stroke(0)
Shinya Kitaoka 120a6e
    , m_justSelected(false)
Shinya Kitaoka 120a6e
    , m_strokeSelectionType("Type:")
Shinya Kitaoka 120a6e
    , m_deformValues()
Shinya Kitaoka 120a6e
    , m_cursorId(ToolCursor::CURSOR_ARROW) {
Shinya Kitaoka 120a6e
  bind(targetType);
Shinya Kitaoka 120a6e
  m_prop.bind(m_strokeSelectionType);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_strokeSelectionType.addValue(RECT_SELECTION);
Shinya Kitaoka 120a6e
  m_strokeSelectionType.addValue(FREEHAND_SELECTION);
Shinya Kitaoka 120a6e
  m_strokeSelectionType.addValue(POLYLINE_SELECTION);
Shinya Kitaoka 120a6e
  m_strokeSelectionType.setId("Type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
SelectionTool::~SelectionTool() {
Shinya Kitaoka 120a6e
  delete m_dragTool;
Shinya Kitaoka 120a6e
  if (m_stroke) {
Shinya Kitaoka 120a6e
    delete m_stroke;
Shinya Kitaoka 120a6e
    m_stroke = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!m_freeDeformers.empty()) clearPointerContainer(m_freeDeformers);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::clearDeformers() { clearPointerContainer(m_freeDeformers); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD SelectionTool::getCenter(int index) const {
Shinya Kitaoka 120a6e
  if (m_centers.empty()) return TPointD();
Shinya Kitaoka 120a6e
  assert((int)m_centers.size() > index);
Shinya Kitaoka 120a6e
  return m_centers[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::setCenter(const TPointD ¢er, int index) {
Shinya Kitaoka 120a6e
  if (m_centers.empty()) return;
Shinya Kitaoka 120a6e
  assert((int)m_centers.size() > index);
Shinya Kitaoka 120a6e
  m_centers[index] = center;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int SelectionTool::getBBoxsCount() const { return m_bboxs.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
DragSelectionTool::FourPoints SelectionTool::getBBox(int index) const {
Shinya Kitaoka 120a6e
  if (m_bboxs.empty()) return DragSelectionTool::FourPoints();
Shinya Kitaoka 120a6e
  assert((int)m_bboxs.size() > index);
Shinya Kitaoka 120a6e
  return m_bboxs[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::setBBox(const DragSelectionTool::FourPoints &points,
Shinya Kitaoka 120a6e
                            int index) {
Shinya Kitaoka 120a6e
  if (m_bboxs.empty()) return;
Shinya Kitaoka 120a6e
  assert((int)m_bboxs.size() > index);
Shinya Kitaoka 120a6e
  m_bboxs[index] = points;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FreeDeformer *SelectionTool::getFreeDeformer(int index) const {
Shinya Kitaoka 120a6e
  if (m_freeDeformers.empty()) return 0;
Shinya Kitaoka 120a6e
  return m_freeDeformers[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::updateTranslation() {
Shinya Kitaoka 120a6e
  m_strokeSelectionType.setQStringName(tr("Type:"));
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void SelectionTool::updateAction(TPointD pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  TImageP image    = getImage(false);
Shinya Kitaoka 120a6e
  TToonzImageP ti  = image;
Shinya Kitaoka 120a6e
  TRasterImageP ri = image;
Shinya Kitaoka 120a6e
  TVectorImageP vi = image;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_what     = Outside;
Shinya Kitaoka 120a6e
  m_cursorId = ToolCursor::StrokeSelectCursor;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ti && !vi && !ri) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool shift = e.isShiftPressed();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (shift && !m_leftButtonMousePressed && isModifiableSelectionType()) {
Shinya Kitaoka 120a6e
    m_what     = ADD_SELECTION;
Shinya Kitaoka 120a6e
    m_cursorId = ToolCursor::SplineEditorCursorAdd;
Shinya Kitaoka 120a6e
  } else if (m_leftButtonMousePressed)
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  FourPoints bbox = getBBox();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double pixelSize = getPixelSize();
Shinya Kitaoka 120a6e
  if (!bbox.isEmpty()) {
Shinya Kitaoka 120a6e
    double maxDist  = 8 * pixelSize;
Shinya Kitaoka 120a6e
    double maxDist2 = maxDist * maxDist;
Shinya Kitaoka 120a6e
    double p        = (12 * pixelSize) - 3 * pixelSize;
Shinya Kitaoka 120a6e
    m_selectedPoint = NONE;
Shinya Kitaoka 120a6e
    if (tdistance2(bbox.getP00(), pos) < maxDist2 + p)
Shinya Kitaoka 120a6e
      m_selectedPoint = P00;
Shinya Kitaoka 120a6e
    else if (tdistance2(bbox.getP11(), pos) < maxDist2 + p)
Shinya Kitaoka 120a6e
      m_selectedPoint = P11;
Shinya Kitaoka 120a6e
    else if (tdistance2(bbox.getP01(), pos) < maxDist2 + p)
Shinya Kitaoka 120a6e
      m_selectedPoint = P01;
Shinya Kitaoka 120a6e
    else if (tdistance2(bbox.getP10(), pos) < maxDist2 + p)
Shinya Kitaoka 120a6e
      m_selectedPoint = P10;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (tdistance2(bbox.getBottomLeft() + TPointD(-p, -p), pos) < maxDist2) {
Shinya Kitaoka 120a6e
      m_what     = ROTATION;
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::RotBottomLeft;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (tdistance2(bbox.getBottomRight() + TPointD(p, -p), pos) <
Shinya Kitaoka 120a6e
               maxDist2) {
Shinya Kitaoka 120a6e
      m_what     = ROTATION;
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::RotBottomRight;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (tdistance2(bbox.getTopRight() + TPointD(p, p), pos) < maxDist2) {
Shinya Kitaoka 120a6e
      m_what     = ROTATION;
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::RotCursor;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (tdistance2(bbox.getTopLeft() + TPointD(-p, p), pos) < maxDist2) {
Shinya Kitaoka 120a6e
      m_what     = ROTATION;
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::RotTopLeft;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    maxDist  = 5 * pixelSize;
Shinya Kitaoka 120a6e
    maxDist2 = maxDist * maxDist;
Shinya Kitaoka 120a6e
    if (tdistance2(bbox.getP00(), pos) < maxDist2 ||
Shinya Kitaoka 120a6e
        tdistance2(bbox.getP11(), pos) < maxDist2 ||
Shinya Kitaoka 120a6e
        tdistance2(bbox.getP01(), pos) < maxDist2 ||
Shinya Kitaoka 120a6e
        tdistance2(bbox.getP10(), pos) < maxDist2) {
Shinya Kitaoka 120a6e
      if (!e.isCtrlPressed() || isLevelType() || isSelectedFramesType()) {
Shinya Kitaoka 120a6e
        m_what = SCALE;
Shinya Kitaoka 120a6e
        if (tdistance2(bbox.getTopRight(), pos) < maxDist2 ||
Shinya Kitaoka 120a6e
            tdistance2(bbox.getBottomLeft(), pos) < maxDist2)
Shinya Kitaoka 120a6e
          m_cursorId = ToolCursor::ScaleCursor;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          m_cursorId = ToolCursor::ScaleInvCursor;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        m_cursorId = ToolCursor::DistortCursor;
Shinya Kitaoka 120a6e
        m_what     = DEFORM;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (isCloseToSegment(pos, TSegment(bbox.getPoint(0), bbox.getPoint(3)),
Shinya Kitaoka 120a6e
                         maxDist))
Shinya Kitaoka 120a6e
      m_selectedPoint = P0M;
Shinya Kitaoka 120a6e
    else if (isCloseToSegment(pos, TSegment(bbox.getPoint(1), bbox.getPoint(2)),
Shinya Kitaoka 120a6e
                              maxDist))
Shinya Kitaoka 120a6e
      m_selectedPoint = P1M;
Shinya Kitaoka 120a6e
    else if (isCloseToSegment(pos, TSegment(bbox.getPoint(3), bbox.getPoint(2)),
Shinya Kitaoka 120a6e
                              maxDist))
Shinya Kitaoka 120a6e
      m_selectedPoint = PM1;
Shinya Kitaoka 120a6e
    else if (isCloseToSegment(pos, TSegment(bbox.getPoint(0), bbox.getPoint(1)),
Shinya Kitaoka 120a6e
                              maxDist))
Shinya Kitaoka 120a6e
      m_selectedPoint = PM0;
Shinya Kitaoka 120a6e
    if (m_selectedPoint == P0M || m_selectedPoint == P1M) {
Shinya Kitaoka 120a6e
      if (!e.isCtrlPressed() || isLevelType() || isSelectedFramesType()) {
Shinya Kitaoka 120a6e
        m_cursorId = ToolCursor::ScaleHCursor;
Shinya Kitaoka 120a6e
        m_what     = SCALE_X;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        m_cursorId = ToolCursor::DistortCursor;
Shinya Kitaoka 120a6e
        m_what     = DEFORM;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_selectedPoint == PM1 || m_selectedPoint == PM0) {
Shinya Kitaoka 120a6e
      if (!e.isCtrlPressed() || isLevelType() || isSelectedFramesType()) {
Shinya Kitaoka 120a6e
        m_cursorId = ToolCursor::ScaleVCursor;
Shinya Kitaoka 120a6e
        m_what     = SCALE_Y;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        m_cursorId = ToolCursor::DistortCursor;
Shinya Kitaoka 120a6e
        m_what     = DEFORM;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!isLevelType() && !isSelectedFramesType() &&
Shinya Kitaoka 120a6e
        tdistance2(getCenter(), pos) < maxDist2) {
Shinya Kitaoka 120a6e
      m_what = MOVE_CENTER;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TPointD hpos = bbox.getP10() - TPointD(14 * pixelSize, 15 * pixelSize);
Shinya Kitaoka 120a6e
    TRectD rect(hpos - TPointD(14 * pixelSize, 5 * pixelSize),
Shinya Kitaoka 120a6e
                hpos + TPointD(14 * pixelSize, 5 * pixelSize));
Shinya Kitaoka 120a6e
    if (!m_deformValues.m_isSelectionModified && rect.contains(pos) && vi &&
Shinya Kitaoka 120a6e
        !TTool::getApplication()->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
      m_what     = GLOBAL_THICKNESS;
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::PumpCursor;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_selectedPoint = NONE;
Shinya Kitaoka 120a6e
  if ((isLevelType() || isSelectedFramesType()) && !isSameStyleType()) {
Shinya Kitaoka 120a6e
    m_what = Inside;
Shinya Kitaoka 120a6e
    ToolCursor::LevelSelectCursor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (shift) return;
Shinya Kitaoka 120a6e
  if (!vi && bbox.contains(pos)) {
Shinya Kitaoka 120a6e
    m_what = Inside;
Shinya Kitaoka 120a6e
    if (isLevelType() || isSelectedFramesType())
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::LevelSelectCursor;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::MoveCursor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void SelectionTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  TImageP image = getImage(false);
Shinya Kitaoka 120a6e
  if (!image) return;
Shinya Kitaoka 120a6e
  if (m_polyline.size() == 0) {
Shinya Kitaoka 120a6e
    modifySelectionOnClick(image, pos, e);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_what == ROTATION) m_dragTool = createNewRotationTool(this);
Shinya Kitaoka 120a6e
    if (!e.isShiftPressed() && m_what == Inside)
Shinya Kitaoka 120a6e
      m_dragTool = createNewMoveSelectionTool(this);
Shinya Kitaoka 120a6e
    else if (m_what == MOVE_CENTER)
Shinya Kitaoka 120a6e
      m_dragTool = new MoveCenterTool(this);
Shinya Kitaoka 120a6e
    else if (m_what == SCALE)
Shinya Kitaoka 120a6e
      m_dragTool = createNewScaleTool(this, 0);
Shinya Kitaoka 120a6e
    else if (m_what == SCALE_X)
Shinya Kitaoka 120a6e
      m_dragTool = createNewScaleTool(this, 1);
Shinya Kitaoka 120a6e
    else if (m_what == SCALE_Y)
Shinya Kitaoka 120a6e
      m_dragTool = createNewScaleTool(this, 2);
Shinya Kitaoka 120a6e
    else if (m_what == DEFORM)
Shinya Kitaoka 120a6e
      m_dragTool = createNewFreeDeformTool(this);
Shinya Kitaoka 120a6e
    else if (m_what == GLOBAL_THICKNESS)
Shinya Kitaoka 120a6e
      m_dragTool = new VectorChangeThicknessTool((VectorSelectionTool *)this);
Shinya Kitaoka 120a6e
    if (m_dragTool) m_dragTool->leftButtonDown(pos, e);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_selecting = true;
Shinya Kitaoka 120a6e
  if (m_selecting) {
Shinya Kitaoka 120a6e
    if (m_stroke) {
Shinya Kitaoka 120a6e
      delete m_stroke;
Shinya Kitaoka 120a6e
      m_stroke = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_strokeSelectionType.getValue() == FREEHAND_SELECTION)
Shinya Kitaoka 120a6e
      startFreehand(pos);
Shinya Kitaoka 120a6e
    if (m_strokeSelectionType.getValue() == POLYLINE_SELECTION)
Shinya Kitaoka 120a6e
      addPointPolyline(pos);
Shinya Kitaoka 120a6e
    else if (m_polyline.size() != 0)
Shinya Kitaoka 120a6e
      m_polyline.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_firstPos = m_curPos    = pos;
Shinya Kitaoka 120a6e
  m_leftButtonMousePressed = true;
Shinya Kitaoka 120a6e
  m_shiftPressed           = e.isShiftPressed();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void SelectionTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  updateAction(pos, e);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_strokeSelectionType.getValue() == POLYLINE_SELECTION) {
Shinya Kitaoka 120a6e
    m_mousePosition = pos;
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool SelectionTool::keyDown(int key, TUINT32 flags, const TPoint &pos) {
Shinya Kitaoka 120a6e
  if (isSelectionEmpty()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD delta;
Shinya Kitaoka 120a6e
  if (key == TwConsts::TK_UpArrow)
Shinya Kitaoka 120a6e
    delta.y = 1;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_DownArrow)
Shinya Kitaoka 120a6e
    delta.y = -1;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_LeftArrow)
Shinya Kitaoka 120a6e
    delta.x = -1;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_RightArrow)
Shinya Kitaoka 120a6e
    delta.x = 1;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_ShiftUpArrow)
Shinya Kitaoka 120a6e
    delta.y = 10;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_ShiftDownArrow)
Shinya Kitaoka 120a6e
    delta.y = -10;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_ShiftLeftArrow)
Shinya Kitaoka 120a6e
    delta.x = -10;
Shinya Kitaoka 120a6e
  else if (key == TwConsts::TK_ShiftRightArrow)
Shinya Kitaoka 120a6e
    delta.x = 10;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP image = getImage(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TToonzImageP ti  = (TToonzImageP)image;
Shinya Kitaoka 120a6e
  TRasterImageP ri = (TRasterImageP)image;
Shinya Kitaoka 120a6e
  TVectorImageP vi = (TVectorImageP)image;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ti && !vi && !ri) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  DragTool *dragTool = createNewMoveSelectionTool(this);
Shinya Kitaoka 120a6e
  TPointD p          = convert(pos);
Shinya Kitaoka 120a6e
  TAffine aff        = TTranslation(delta);
Shinya Kitaoka 120a6e
  dragTool->transform(aff);
Shinya Kitaoka 120a6e
  double factor = 1.0 / Stage::inch;
Shinya Kitaoka 120a6e
  m_deformValues.m_moveValue += factor * delta;
Shinya Kitaoka 120a6e
  dragTool->addTransformUndo();
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->notifyToolChanged();
Shinya Kitaoka 120a6e
  delete dragTool;
Shinya Kitaoka 120a6e
  dragTool = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int SelectionTool::getCursorId() const {
Shinya Kitaoka 120a6e
  TImageP image    = getImage(false);
Shinya Kitaoka 120a6e
  TToonzImageP ti  = (TToonzImageP)image;
Shinya Kitaoka 120a6e
  TRasterImageP ri = (TRasterImageP)image;
Shinya Kitaoka 120a6e
  TVectorImageP vi = (TVectorImageP)image;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!ti && !vi && !ri) return ToolCursor::StrokeSelectCursor;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_cursorId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::drawPolylineSelection() {
Shinya Kitaoka 120a6e
  if (m_polyline.empty()) return;
Shinya Kitaoka 120a6e
  TPixel color = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg
Shinya Kitaoka 120a6e
                     ? TPixel32::White
Shinya Kitaoka 120a6e
                     : TPixel32::Black;
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  tglDrawCircle(m_polyline[0], 2);
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_polyline.size(); i++) tglVertex(m_polyline[i]);
Shinya Kitaoka 120a6e
  tglVertex(m_mousePosition);
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::drawRectSelection(const TImage *image) {
Shinya Kitaoka 120a6e
  const TVectorImage *vi   = dynamic_cast<const *="" tvectorimage="">(image);</const>
Shinya Kitaoka 120a6e
  unsigned short stipple   = 0x3F33;
Shinya Kitaoka 120a6e
  FourPoints selectingRect = m_selectingRect;
Shinya Kitaoka 120a6e
  if (vi && m_curPos.x >= m_firstPos.x) stipple = 0xFF00;
Shinya Kitaoka 120a6e
  drawFourPoints(selectingRect, TPixel32::Black, stipple, true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::drawCommandHandle(const TImage *image) {
Shinya Kitaoka 120a6e
  const TVectorImage *vi = dynamic_cast<const *="" tvectorimage="">(image);</const>
Shinya Kitaoka 120a6e
  TPixel32 frameColor(127, 127, 127);
Shinya Kitaoka 120a6e
  FourPoints rect = getBBox();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  drawFourPoints(rect, frameColor, 0xffff, true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  tglColor(frameColor);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_dragTool) m_dragTool->draw();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double pixelSize = getPixelSize();
Shinya Kitaoka 120a6e
  if (!isLevelType() && !isSelectedFramesType())
Shinya Kitaoka 120a6e
    tglDrawCircle(getCenter(), pixelSize * 4);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  drawSquare(rect.getP00(), pixelSize * 4, frameColor);
Shinya Kitaoka 120a6e
  drawSquare(rect.getP01(), pixelSize * 4, frameColor);
Shinya Kitaoka 120a6e
  drawSquare(rect.getP10(), pixelSize * 4, frameColor);
Shinya Kitaoka 120a6e
  drawSquare(rect.getP11(), pixelSize * 4, frameColor);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (vi && !m_deformValues.m_isSelectionModified) {
Shinya Kitaoka 120a6e
    TPointD thickCommandPos =
Shinya Kitaoka 120a6e
        rect.getP10() - TPointD(14 * pixelSize, 15 * pixelSize);
Shinya Kitaoka 120a6e
    drawRectWhitArrow(thickCommandPos, pixelSize);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  drawSquare(0.5 * (rect.getP10() + rect.getP11()), pixelSize * 4, frameColor);
Shinya Kitaoka 120a6e
  drawSquare(0.5 * (rect.getP01() + rect.getP11()), pixelSize * 4, frameColor);
Shinya Kitaoka 120a6e
  drawSquare(0.5 * (rect.getP10() + rect.getP00()), pixelSize * 4, frameColor);
Shinya Kitaoka 120a6e
  drawSquare(0.5 * (rect.getP01() + rect.getP00()), pixelSize * 4, frameColor);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::onActivate() {
Shinya Kitaoka 120a6e
  if (m_firstTime) {
Shinya Kitaoka 120a6e
    m_strokeSelectionType.setValue(::to_wstring(SelectionType.getValue()));
Shinya Kitaoka 120a6e
    m_firstTime = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (isLevelType() || isSelectedFramesType()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  doOnActivate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::onDeactivate() {
Shinya Kitaoka 120a6e
  if (isLevelType() || isSelectedFramesType()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  doOnDeactivate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SelectionTool::onSelectionChanged() {
Shinya Kitaoka 120a6e
  computeBBox();
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
  m_polyline.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool SelectionTool::onPropertyChanged(std::string propertyName) {
Shinya Kitaoka 120a6e
  if (propertyName == m_strokeSelectionType.getName()) {
Shinya Kitaoka 120a6e
    SelectionType = ::to_string(m_strokeSelectionType.getValue());
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Viene aggiunto \b pos a \b m_track e disegnato il primo pezzetto del lazzo.
Shinya Kitaoka 120a6e
//! Viene inizializzato \b m_firstPos
Shinya Kitaoka 120a6e
void SelectionTool::startFreehand(const TPointD &pos) {
Shinya Kitaoka 120a6e
  m_track.clear();
Shinya Kitaoka 120a6e
  m_firstPos       = pos;
Shinya Kitaoka 120a6e
  double pixelSize = getPixelSize();
Shinya Kitaoka 120a6e
  m_track.add(TThickPoint(pos, 0), pixelSize * pixelSize);
Shinya Kitaoka 120a6e
  TPointD dpiScale = m_viewer->getDpiScale();
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Toshihiro Shimizu 890ddd
//			m_viewer->prepareForegroundDrawing();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  TPixel color = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg
Shinya Kitaoka 120a6e
                     ? TPixel32::White
Shinya Kitaoka 120a6e
                     : TPixel32::Black;
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  m_viewer->startForegroundDrawing();
Shinya Kitaoka 120a6e
  glPushMatrix();
Shinya Kitaoka 120a6e
  tglMultMatrix(getMatrix());
Shinya Kitaoka 120a6e
  glScaled(dpiScale.x, dpiScale.y, 1);
Shinya Kitaoka 120a6e
  m_track.drawLastFragments();
Shinya Kitaoka 120a6e
  glPopMatrix();
Shinya Kitaoka 120a6e
  m_viewer->endForegroundDrawing();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Viene aggiunto \b pos a \b m_track e disegnato un altro pezzetto del lazzo.
Shinya Kitaoka 120a6e
void SelectionTool::freehandDrag(const TPointD &pos) {
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Toshihiro Shimizu 890ddd
//		m_viewer->enableRedraw(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double pixelSize = getPixelSize();
Shinya Kitaoka 120a6e
  m_viewer->startForegroundDrawing();
Shinya Kitaoka 120a6e
  TPixel color = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg
Shinya Kitaoka 120a6e
                     ? TPixel32::White
Shinya Kitaoka 120a6e
                     : TPixel32::Black;
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  glPushMatrix();
Shinya Kitaoka 120a6e
  tglMultMatrix(getMatrix());
Shinya Kitaoka 120a6e
  TPointD dpiScale = m_viewer->getDpiScale();
Shinya Kitaoka 120a6e
  glScaled(dpiScale.x, dpiScale.y, 1);
Shinya Kitaoka 120a6e
  m_track.add(TThickPoint(pos, 0), pixelSize * pixelSize);
Shinya Kitaoka 120a6e
  m_track.drawLastFragments();
Shinya Kitaoka 120a6e
  glPopMatrix();
Shinya Kitaoka 120a6e
  m_viewer->endForegroundDrawing();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Viene chiuso il lazzo (si aggiunge l'ultimo punto ad m_track) e viene creato
Shinya Kitaoka 120a6e
//! lo stroke rappresentante il lazzo.
Shinya Kitaoka 120a6e
void SelectionTool::closeFreehand(const TPointD &pos) {
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Toshihiro Shimizu 890ddd
//		m_viewer->enableRedraw(true);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  if (m_track.isEmpty()) return;
Shinya Kitaoka 120a6e
  double pixelSize = getPixelSize();
Shinya Kitaoka 120a6e
  m_track.add(TThickPoint(m_firstPos, 0), pixelSize * pixelSize);
Shinya Kitaoka 120a6e
  m_track.filterPoints();
Shinya Kitaoka 120a6e
  double error = (30.0 / 11) * pixelSize;
Shinya Kitaoka 120a6e
  m_stroke     = m_track.makeStroke(error);
Shinya Kitaoka 120a6e
  m_stroke->setStyle(1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Viene aggiunto un punto al vettore m_polyline.
Shinya Kitaoka 120a6e
void SelectionTool::addPointPolyline(const TPointD &pos) {
Shinya Kitaoka 120a6e
  m_firstPos      = pos;
Shinya Kitaoka 120a6e
  m_mousePosition = pos;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPointD dpiScale = m_viewer->getDpiScale();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Toshihiro Shimizu 890ddd
//		 m_viewer->prepareForegroundDrawing();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  TPixel color = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg
Shinya Kitaoka 120a6e
                     ? TPixel32::White
Shinya Kitaoka 120a6e
                     : TPixel32::Black;
Shinya Kitaoka 120a6e
  tglColor(color);
Shinya Kitaoka 120a6e
  m_viewer->startForegroundDrawing();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Shinya Kitaoka 120a6e
//  		m_viewer->enableRedraw(m_strokeSelectionType.getValue() ==
Shinya Kitaoka 120a6e
//  POLYLINE_SELECTION);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glPushMatrix();
Shinya Kitaoka 120a6e
  glScaled(dpiScale.x, dpiScale.y, 1);
Shinya Kitaoka 120a6e
  m_polyline.push_back(pos);
Shinya Kitaoka 120a6e
  glPopMatrix();
Shinya Kitaoka 120a6e
  m_viewer->endForegroundDrawing();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//! Agginge l'ultimo pos a \b m_polyline e chiude la spezzata (aggiunge \b
Shinya Kitaoka 120a6e
//! m_polyline.front() alla fine del vettore).
Shinya Kitaoka 120a6e
void SelectionTool::closePolyline(const TPointD &pos) {
Shinya Kitaoka 120a6e
  if (m_polyline.size() <= 1) return;
Shinya Kitaoka 120a6e
  if (m_polyline.back() != pos) m_polyline.push_back(pos);
Shinya Kitaoka 120a6e
  if (m_polyline.back() != m_polyline.front())
Shinya Kitaoka 120a6e
    m_polyline.push_back(m_polyline.front());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> strokePoints;</tthickpoint>
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_polyline.size() - 1; i++) {
Shinya Kitaoka 120a6e
    strokePoints.push_back(TThickPoint(m_polyline[i], 0));
Shinya Kitaoka 120a6e
    strokePoints.push_back(
Shinya Kitaoka 120a6e
        TThickPoint(0.5 * (m_polyline[i] + m_polyline[i + 1]), 0));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  strokePoints.push_back(TThickPoint(m_polyline.back(), 0));
Shinya Kitaoka 120a6e
  m_polyline.clear();
Shinya Kitaoka 120a6e
  m_stroke = new TStroke(strokePoints);
Shinya Kitaoka 120a6e
  assert(m_stroke->getPoint(0) == m_stroke->getPoint(1));
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}