Toshihiro Shimizu 890ddd
shun-iwasawa a5c4f3
#include "geometrictool.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
manongjohn 40a40e
#include "tools/toolcommandids.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "bluredbrush.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectspline.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
#include "toonz/trasterimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "historytypes.h"
manongjohn 40a40e
#include "toonzvectorbrushtool.h"
shun-iwasawa a5c4f3
#include "tcurveutil.h"
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
#include "tpixelutils.h"
shun-iwasawa a5c4f3
#include "toonz/mypaintbrushstyle.h"
shun-iwasawa a5c4f3
#include "toonz/ttilesaver.h"
Toshihiro Shimizu 890ddd
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
class GeometricTool;
Toshihiro Shimizu 890ddd
class MultiLinePrimitive;
pojienie e8ee24
class MultiArcPrimitive;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TEnv::DoubleVar GeometricSize("InknpaintGeometricSize", 1);
Toshihiro Shimizu 890ddd
TEnv::DoubleVar GeometricRasterSize("InknpaintGeometricRasterSize", 1);
Toshihiro Shimizu 890ddd
TEnv::StringVar GeometricType("InknpaintGeometricType", "Rectangle");
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricEdgeCount("InknpaintGeometricEdgeCount", 3);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricSelective("InknpaintGeometricSelective", 0);
pojienie 7f72a6
TEnv::IntVar GeometricRotate("InknpaintGeometricRotate", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricGroupIt("InknpaintGeometricGroupIt", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricAutofill("InknpaintGeometricAutofill", 0);
pojienie 66058f
TEnv::IntVar GeometricSmooth("InknpaintGeometricSmooth", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricPencil("InknpaintGeometricPencil", 0);
Toshihiro Shimizu 890ddd
TEnv::DoubleVar GeometricBrushHardness("InknpaintGeometricHardness", 100);
Toshihiro Shimizu 890ddd
TEnv::DoubleVar GeometricOpacity("InknpaintGeometricOpacity", 100);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricCapStyle("InknpaintGeometricCapStyle", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricJoinStyle("InknpaintGeometricJoinStyle", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricMiterValue("InknpaintGeometricMiterValue", 4);
Jeremy Bullock 977232
TEnv::IntVar GeometricSnap("InknpaintGeometricSnap", 0);
Jeremy Bullock 977232
TEnv::IntVar GeometricSnapSensitivity("InknpaintGeometricSnapSensitivity", 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define ROUNDC_WSTR L"round_cap"
Toshihiro Shimizu 890ddd
#define BUTT_WSTR L"butt_cap"
Toshihiro Shimizu 890ddd
#define PROJECTING_WSTR L"projecting_cap"
Toshihiro Shimizu 890ddd
#define ROUNDJ_WSTR L"round_join"
Toshihiro Shimizu 890ddd
#define BEVEL_WSTR L"bevel_join"
Toshihiro Shimizu 890ddd
#define MITER_WSTR L"miter_join"
Jeremy Bullock 977232
#define LOW_WSTR L"Low"
Jeremy Bullock 977232
#define MEDIUM_WSTR L"Medium"
Jeremy Bullock 977232
#define HIGH_WSTR L"High"
Jeremy Bullock 977232
Jeremy Bullock 977232
const double SNAPPING_LOW    = 5.0;
Jeremy Bullock 977232
const double SNAPPING_MEDIUM = 25.0;
Jeremy Bullock 977232
const double SNAPPING_HIGH   = 100.0;
Toshihiro Shimizu 890ddd
shun-iwasawa a5c4f3
//----------------------------------------------------------------------------------
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
namespace {
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//-----------------------------------------------------------------------------
shun-iwasawa a5c4f3
class FullColorMyPaintGeometryUndo final
shun-iwasawa a5c4f3
    : public ToolUtils::TFullColorRasterUndo {
shun-iwasawa a5c4f3
  TPoint m_offset;
shun-iwasawa a5c4f3
  QString m_id;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
public:
shun-iwasawa a5c4f3
  FullColorMyPaintGeometryUndo(TTileSetFullColor *tileSet,
shun-iwasawa a5c4f3
                               TXshSimpleLevel *level, const TFrameId &frameId,
shun-iwasawa a5c4f3
                               bool isFrameCreated, const TRasterP &ras,
shun-iwasawa a5c4f3
                               const TPoint &offset)
shun-iwasawa a5c4f3
      : ToolUtils::TFullColorRasterUndo(tileSet, level, frameId, isFrameCreated,
shun-iwasawa a5c4f3
                                        false, 0)
shun-iwasawa a5c4f3
      , m_offset(offset) {
shun-iwasawa a5c4f3
    static int counter = 0;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    m_id = QString("FullColorMyPaintGeometryUndo") + QString::number(counter++);
shun-iwasawa a5c4f3
    TImageCache::instance()->add(m_id.toStdString(), TRasterImageP(ras));
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  ~FullColorMyPaintGeometryUndo() { TImageCache::instance()->remove(m_id); }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  void redo() const override {
shun-iwasawa a5c4f3
    insertLevelAndFrameIfNeeded();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TRasterImageP image = getImage();
shun-iwasawa a5c4f3
    TRasterP ras        = image->getRaster();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TRasterImageP srcImg =
shun-iwasawa a5c4f3
        TImageCache::instance()->get(m_id.toStdString(), false);
shun-iwasawa a5c4f3
    ras->copy(srcImg->getRaster(), m_offset);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
shun-iwasawa a5c4f3
    notifyImageChanged();
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  int getSize() const override {
shun-iwasawa a5c4f3
    return sizeof(*this) + ToolUtils::TFullColorRasterUndo::getSize();
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  QString getToolName() override { return QString("Geometric Tool"); }
shun-iwasawa a5c4f3
  int getHistoryType() override { return HistoryType::GeometricTool; }
shun-iwasawa a5c4f3
};
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//-----------------------------------------------------------------------------
shun-iwasawa a5c4f3
class CMappedMyPaintGeometryUndo final : public TRasterUndo {
shun-iwasawa a5c4f3
  TPoint m_offset;
shun-iwasawa a5c4f3
  QString m_id;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
public:
shun-iwasawa a5c4f3
  CMappedMyPaintGeometryUndo(TTileSetCM32 *tileSet, TXshSimpleLevel *level,
shun-iwasawa a5c4f3
                             const TFrameId &frameId, bool isFrameCreated,
shun-iwasawa a5c4f3
                             bool isLevelCreated, const TRasterCM32P &ras,
shun-iwasawa a5c4f3
                             const TPoint &offset)
shun-iwasawa a5c4f3
      : TRasterUndo(tileSet, level, frameId, isFrameCreated, isLevelCreated, 0)
shun-iwasawa a5c4f3
      , m_offset(offset) {
shun-iwasawa a5c4f3
    static int counter = 0;
shun-iwasawa a5c4f3
    m_id = QString("CMappedMyPaintGeometryUndo") + QString::number(counter++);
shun-iwasawa a5c4f3
    TImageCache::instance()->add(m_id.toStdString(),
shun-iwasawa a5c4f3
                                 TToonzImageP(ras, TRect(ras->getSize())));
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  ~CMappedMyPaintGeometryUndo() { TImageCache::instance()->remove(m_id); }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  void redo() const override {
shun-iwasawa a5c4f3
    insertLevelAndFrameIfNeeded();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TToonzImageP image = getImage();
shun-iwasawa a5c4f3
    TRasterCM32P ras   = image->getRaster();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TImageP srcImg =
shun-iwasawa a5c4f3
        TImageCache::instance()->get(m_id.toStdString(), false)->cloneImage();
shun-iwasawa a5c4f3
    TToonzImageP tSrcImg = srcImg;
shun-iwasawa a5c4f3
    assert(tSrcImg);
shun-iwasawa a5c4f3
    ras->copy(tSrcImg->getRaster(), m_offset);
shun-iwasawa a5c4f3
    ToolUtils::updateSaveBox();
shun-iwasawa a5c4f3
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
shun-iwasawa a5c4f3
    notifyImageChanged();
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  int getSize() const override {
shun-iwasawa a5c4f3
    return sizeof(*this) + TRasterUndo::getSize();
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  QString getToolName() override { return QString("Geometric Tool"); }
shun-iwasawa a5c4f3
  int getHistoryType() override { return HistoryType::GeometricTool; }
shun-iwasawa a5c4f3
};
shun-iwasawa a5c4f3
//-----------------------------------------------------------------------------
shun-iwasawa a5c4f3
}  // namespace
shun-iwasawa a5c4f3
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Utility Functions
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static TPointD rectify(const TPointD &oldPos, const TPointD &pos) {
Shinya Kitaoka 120a6e
  const double h             = sqrt(2.0) / 2.0;
Shinya Kitaoka 120a6e
  const TPointD directions[] = {TPointD(1, 0),  TPointD(h, h),  TPointD(0, 1),
Shinya Kitaoka 120a6e
                                TPointD(-h, h), TPointD(-1, 0), TPointD(-h, -h),
Shinya Kitaoka 120a6e
                                TPointD(0, -1), TPointD(h, -h)};
shun-iwasawa 036853
  TPointD v                  = pos - oldPos;
shun-iwasawa 036853
  int j                      = 0;
shun-iwasawa 036853
  double bestValue           = v * directions[j];
Shinya Kitaoka 120a6e
  for (int k = 1; k < 8; k++) {
Shinya Kitaoka 120a6e
    double value = v * directions[k];
Shinya Kitaoka 120a6e
    if (value > bestValue) {
Shinya Kitaoka 120a6e
      bestValue = value;
Shinya Kitaoka 120a6e
      j         = k;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return oldPos + bestValue * directions[j];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static TPointD computeSpeed(TPointD p0, TPointD p1, double factor) {
Shinya Kitaoka 120a6e
  TPointD d = p1 - p0;
Shinya Kitaoka 120a6e
  return (d == TPointD()) ? TPointD() : d * (factor / norm(d));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 27b0cf
static TRect drawBluredBrush(const TRasterImageP &ri, TStroke *stroke,
shun-iwasawa 27b0cf
                             int thick, double hardness, double opacity) {
Shinya Kitaoka 120a6e
  TStroke *s       = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  TPointD riCenter = ri->getRaster()->getCenterD();
Shinya Kitaoka 120a6e
  s->transform(TTranslation(riCenter));
Shinya Kitaoka 120a6e
  int styleId    = s->getStyle();
Shinya Kitaoka 120a6e
  TPalette *plt  = ri->getPalette();
Shinya Kitaoka 120a6e
  TPixel32 color = plt->getStyle(styleId)->getMainColor();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD bbox      = s->getBBox();
Shinya Kitaoka 120a6e
  TRect bboxI      = convert(bbox).enlarge(1);
Shinya Kitaoka 120a6e
  TRect rectRender = bboxI * ri->getRaster()->getBounds();
Shinya Kitaoka 120a6e
  if (rectRender.isEmpty()) return TRect();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P workRas(ri->getRaster()->getSize());
Shinya Kitaoka 120a6e
  TRaster32P backupRas = ri->getRaster()->clone();
Shinya Kitaoka 120a6e
  workRas->clear();
Shinya Kitaoka 120a6e
  QRadialGradient brushPad = ToolUtils::getBrushPad(thick, hardness);
Shinya Kitaoka 120a6e
  BluredBrush brush(workRas, thick, brushPad, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i, chunkCount = s->getChunkCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < chunkCount; i++) {
Shinya Kitaoka 120a6e
    const TThickQuadratic *q = s->getChunk(i);
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points;</tthickpoint>
Shinya Kitaoka 120a6e
    points.push_back(q->getThickP0());
Shinya Kitaoka 120a6e
    points.push_back(q->getThickP1());
Shinya Kitaoka 120a6e
    points.push_back(q->getThickP2());
Shinya Kitaoka 120a6e
    // i punti contenuti nello stroke sembra che haano la tickness pari al
Shinya Kitaoka 120a6e
    // raggio e non al diametro del punto!
Shinya Kitaoka 120a6e
    points[0].thick *= 2;
Shinya Kitaoka 120a6e
    points[1].thick *= 2;
Shinya Kitaoka 120a6e
    points[2].thick *= 2;
Shinya Kitaoka 120a6e
    TRect chunkBox = brush.getBoundFromPoints(points);
Shinya Kitaoka 120a6e
    brush.addArc(points[0], points[1], points[2], 1, 1);
Shinya Kitaoka 120a6e
    brush.updateDrawing(ri->getRaster(), backupRas, color, chunkBox, opacity);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delete s;
Shinya Kitaoka 120a6e
  return rectRender;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static TRect drawBluredBrush(const TToonzImageP &ti, TStroke *stroke, int thick,
Campbell Barton 8c6c57
                             double hardness, bool selective) {
Shinya Kitaoka 120a6e
  TStroke *s       = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  TPointD riCenter = ti->getRaster()->getCenterD();
Shinya Kitaoka 120a6e
  s->transform(TTranslation(riCenter));
Shinya Kitaoka 120a6e
  int styleId = s->getStyle();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD bbox      = s->getBBox();
Shinya Kitaoka 120a6e
  TRect bboxI      = convert(bbox).enlarge(1);
Shinya Kitaoka 120a6e
  TRect rectRender = bboxI * ti->getRaster()->getBounds();
Shinya Kitaoka 120a6e
  if (rectRender.isEmpty()) return TRect();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P workRas(ti->getRaster()->getSize());
Shinya Kitaoka 120a6e
  TRasterCM32P backupRas = ti->getRaster()->clone();
Shinya Kitaoka 120a6e
  workRas->clear();
Shinya Kitaoka 120a6e
  QRadialGradient brushPad = ToolUtils::getBrushPad(thick, hardness);
Shinya Kitaoka 120a6e
  BluredBrush brush(workRas, thick, brushPad, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i, chunkCount = s->getChunkCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < chunkCount; i++) {
Shinya Kitaoka 120a6e
    const TThickQuadratic *q = s->getChunk(i);
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points;</tthickpoint>
Shinya Kitaoka 120a6e
    points.push_back(q->getThickP0());
Shinya Kitaoka 120a6e
    points.push_back(q->getThickP1());
Shinya Kitaoka 120a6e
    points.push_back(q->getThickP2());
Shinya Kitaoka 120a6e
    // i punti contenuti nello stroke sembra che haano la tickness pari al
Shinya Kitaoka 120a6e
    // raggio e non al diametro del punto!
Shinya Kitaoka 120a6e
    points[0].thick *= 2;
Shinya Kitaoka 120a6e
    points[1].thick *= 2;
Shinya Kitaoka 120a6e
    points[2].thick *= 2;
Shinya Kitaoka 120a6e
    TRect chunkBox = brush.getBoundFromPoints(points);
Shinya Kitaoka 120a6e
    brush.addArc(points[0], points[1], points[2], 1, 1);
Shinya Kitaoka 120a6e
    brush.updateDrawing(ti->getRaster(), backupRas, chunkBox, styleId,
manongjohn 422d0a
                        selective, false);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delete s;
Shinya Kitaoka 120a6e
  return rectRender;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MultilinePrimitiveUndo final : public TUndo {
Shinya Kitaoka 120a6e
  std::vector<tpointd> m_oldVertex;</tpointd>
Shinya Kitaoka 120a6e
  std::vector<tpointd> m_newVertex;</tpointd>
Shinya Kitaoka 120a6e
  MultiLinePrimitive *m_tool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MultilinePrimitiveUndo(const std::vector<tpointd> &vertex,</tpointd>
Shinya Kitaoka 120a6e
                         MultiLinePrimitive *tool)
Shinya Kitaoka 120a6e
      : TUndo(), m_oldVertex(vertex), m_tool(tool), m_newVertex() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~MultilinePrimitiveUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override;
Shinya Kitaoka 473e70
  void redo() const override;
Shinya Kitaoka 120a6e
  void setNewVertex(const std::vector<tpointd> &vertex) {</tpointd>
Shinya Kitaoka 120a6e
    m_newVertex = vertex;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QString getToolName();
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::GeometricTool; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie e8ee24
class MultiArcPrimitiveUndoData {
pojienie e8ee24
private:
pojienie e8ee24
  TStroke *m_stroke;
pojienie e8ee24
  TStroke *m_strokeTemp;
pojienie e8ee24
  TPointD m_startPoint, m_endPoint, m_centralPoint;
pojienie e8ee24
  int m_clickNumber;
pojienie e8ee24
pojienie e8ee24
public:
pojienie e8ee24
  MultiArcPrimitiveUndoData(TStroke *stroke, TStroke *strokeTemp,
pojienie e8ee24
                            TPointD startPoint, TPointD endPoint,
pojienie 8f2ac7
                            TPointD centralPoint, int clickNumber)
pojienie e8ee24
      : m_stroke(0)
pojienie e8ee24
      , m_strokeTemp(0)
pojienie e8ee24
      , m_startPoint(startPoint)
pojienie e8ee24
      , m_endPoint(endPoint)
pojienie e8ee24
      , m_centralPoint(centralPoint)
pojienie 8f2ac7
      , m_clickNumber(clickNumber) {
pojienie e8ee24
    if (stroke) {
pojienie e8ee24
      m_stroke = new TStroke(*stroke);
pojienie e8ee24
    }
pojienie e8ee24
    if (strokeTemp) {
pojienie e8ee24
      m_strokeTemp = new TStroke(*strokeTemp);
pojienie e8ee24
    }
pojienie e8ee24
  }
pojienie e8ee24
pojienie e8ee24
  ~MultiArcPrimitiveUndoData() {
pojienie e8ee24
    delete m_stroke;
pojienie e8ee24
    delete m_strokeTemp;
pojienie e8ee24
  }
pojienie e8ee24
pojienie e8ee24
  void replace(MultiArcPrimitive *tool) const;
pojienie e8ee24
};
pojienie e8ee24
pojienie e8ee24
//-----------------------------------------------------------------------------
pojienie e8ee24
pojienie e8ee24
class MultiArcPrimitiveUndo final : public TUndo {
pojienie e8ee24
  MultiArcPrimitive *m_tool;
pojienie e8ee24
  MultiArcPrimitiveUndoData m_undo;
pojienie e8ee24
  MultiArcPrimitiveUndoData *m_redo;
pojienie e8ee24
pojienie e8ee24
public:
pojienie e8ee24
  MultiArcPrimitiveUndo(MultiArcPrimitive *tool, TStroke *stroke,
pojienie e8ee24
                        TStroke *strokeTemp, TPointD startPoint,
pojienie 8f2ac7
                        TPointD endPoint, TPointD centralPoint, int clickNumber)
pojienie e8ee24
      : TUndo()
pojienie e8ee24
      , m_tool(tool)
pojienie e8ee24
      , m_undo(stroke, strokeTemp, startPoint, endPoint, centralPoint,
pojienie 8f2ac7
               clickNumber)
pojienie e8ee24
      , m_redo(0) {}
pojienie e8ee24
pojienie e8ee24
  ~MultiArcPrimitiveUndo() { delete m_redo; }
pojienie e8ee24
pojienie e8ee24
  void setRedoData(TStroke *stroke, TStroke *strokeTemp, TPointD startPoint,
pojienie 8f2ac7
                   TPointD endPoint, TPointD centralPoint, int clickNumber) {
pojienie 8f2ac7
    m_redo = new MultiArcPrimitiveUndoData(stroke, strokeTemp, startPoint,
pojienie 8f2ac7
                                           endPoint, centralPoint, clickNumber);
pojienie e8ee24
  }
pojienie e8ee24
pojienie e8ee24
  void undo() const override;
pojienie e8ee24
  void redo() const override;
pojienie e8ee24
pojienie e8ee24
  int getSize() const override { return sizeof(this); }
pojienie e8ee24
pojienie e8ee24
  QString getToolName();
pojienie e8ee24
  int getHistoryType() override { return HistoryType::GeometricTool; }
pojienie e8ee24
};
pojienie e8ee24
pojienie e8ee24
//-----------------------------------------------------------------------------
pojienie e8ee24
Shinya Kitaoka d1f6c4
class FullColorBluredPrimitiveUndo final : public UndoFullColorPencil {
Shinya Kitaoka 120a6e
  int m_thickness;
Shinya Kitaoka 120a6e
  double m_hardness;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FullColorBluredPrimitiveUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                               TStroke *stroke, int thickness, double hardness,
Shinya Kitaoka 120a6e
                               double opacity, bool doAntialias,
Shinya Kitaoka 120a6e
                               bool createdFrame, bool createdLevel)
Shinya Kitaoka 120a6e
      : UndoFullColorPencil(level, frameId, stroke, opacity, doAntialias,
Shinya Kitaoka 120a6e
                            createdFrame, createdLevel)
Shinya Kitaoka 120a6e
      , m_thickness(thickness)
Shinya Kitaoka 120a6e
      , m_hardness(hardness) {
Shinya Kitaoka 120a6e
    TRasterP raster = getImage()->getRaster();
Shinya Kitaoka 120a6e
    TDimension d    = raster->getSize();
Shinya Kitaoka 120a6e
    m_tiles         = new TTileSetFullColor(d);
Shinya Kitaoka 120a6e
    TRect rect      = convert(stroke->getBBox()) +
Shinya Kitaoka 120a6e
                 TPoint((int)(d.lx * 0.5), (int)(d.ly * 0.5));
Shinya Kitaoka 120a6e
    m_tiles->add(raster, rect.enlarge(2));
Shinya Kitaoka 120a6e
    m_stroke = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~FullColorBluredPrimitiveUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
    TRasterImageP ri = getImage();
Shinya Kitaoka 120a6e
    if (!ri) return;
Shinya Kitaoka 120a6e
    drawBluredBrush(ri, m_stroke, m_thickness, m_hardness, m_opacity);
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  int getSize() const override {
Shinya Kitaoka 38fd86
    return UndoFullColorPencil::getSize() + sizeof(this);
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*-- Hardness<100 のときの GeometricToolのUndo --*/
Shinya Kitaoka d1f6c4
class CMBluredPrimitiveUndo final : public UndoRasterPencil {
Shinya Kitaoka 120a6e
  int m_thickness;
Shinya Kitaoka 120a6e
  double m_hardness;
Shinya Kitaoka 120a6e
  bool m_selective;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CMBluredPrimitiveUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
                        TStroke *stroke, int thickness, double hardness,
Shinya Kitaoka 120a6e
                        bool selective, bool doAntialias, bool createdFrame,
Shinya Kitaoka 120a6e
                        bool createdLevel, std::string primitiveName)
Shinya Kitaoka 120a6e
      : UndoRasterPencil(level, frameId, stroke, selective, false, doAntialias,
Shinya Kitaoka 120a6e
                         createdFrame, createdLevel, primitiveName)
Shinya Kitaoka 120a6e
      , m_thickness(thickness)
Shinya Kitaoka 120a6e
      , m_hardness(hardness)
Shinya Kitaoka 120a6e
      , m_selective(selective) {
Shinya Kitaoka 120a6e
    TRasterCM32P raster = getImage()->getRaster();
Shinya Kitaoka 120a6e
    TDimension d        = raster->getSize();
Shinya Kitaoka 120a6e
    m_tiles             = new TTileSetCM32(d);
Shinya Kitaoka 120a6e
    TRect rect          = convert(stroke->getBBox()) +
Shinya Kitaoka 120a6e
                 TPoint((int)(d.lx * 0.5), (int)(d.ly * 0.5));
Shinya Kitaoka 120a6e
    m_tiles->add(raster, rect.enlarge(2));
Shinya Kitaoka 120a6e
    m_stroke = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~CMBluredPrimitiveUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
    TToonzImageP ti = getImage();
Shinya Kitaoka 120a6e
    if (!ti) return;
Shinya Kitaoka 120a6e
    drawBluredBrush(ti, m_stroke, m_thickness, m_hardness, m_selective);
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  int getSize() const override {
Shinya Kitaoka 38fd86
    return UndoRasterPencil::getSize() + sizeof(this);
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa a5c4f3
PrimitiveParam::PrimitiveParam(int targetType)
shun-iwasawa a5c4f3
    : m_type("Shape:")  // "W_ToolOptions_ShapeType")
shun-iwasawa a5c4f3
    , m_toolSize("Size:", 0, 100,
shun-iwasawa a5c4f3
                 1)  // "W_ToolOptions_ShapeThickness", 0,30,1)
shun-iwasawa a5c4f3
    , m_rasterToolSize("Size:", 1, 100, 1)
shun-iwasawa a5c4f3
    , m_opacity("Opacity:", 0, 100, 100)
shun-iwasawa a5c4f3
    , m_hardness("Hardness:", 0, 100, 100)
shun-iwasawa a5c4f3
    , m_edgeCount("Polygon Sides:", 3, 15, 3)
shun-iwasawa a5c4f3
    , m_rotate("rotate", false)
shun-iwasawa a5c4f3
    , m_autogroup("Auto Group", false)
shun-iwasawa a5c4f3
    , m_autofill("Auto Fill", false)
shun-iwasawa a5c4f3
    , m_smooth("Smooth", false)
shun-iwasawa a5c4f3
    , m_selective("Selective", false)
shun-iwasawa a5c4f3
    , m_pencil("Pencil Mode", false)
shun-iwasawa a5c4f3
    , m_capStyle("Cap")
shun-iwasawa a5c4f3
    , m_joinStyle("Join")
shun-iwasawa a5c4f3
    , m_miterJoinLimit("Miter:", 0, 100, 4)
shun-iwasawa a5c4f3
    , m_snap("Snap", false)
shun-iwasawa a5c4f3
    , m_snapSensitivity("Sensitivity:")
shun-iwasawa a5c4f3
    , m_modifierSize("ModifierSize", -3, 3, 0, true)
shun-iwasawa a5c4f3
    , m_modifierOpacity("ModifierOpacity", 0, 100, 100, true)
shun-iwasawa a5c4f3
    , m_targetType(targetType) {
shun-iwasawa a5c4f3
  if (targetType & TTool::Vectors) m_prop[0].bind(m_toolSize);
shun-iwasawa a5c4f3
  if (targetType & TTool::ToonzImage || targetType & TTool::RasterImage) {
shun-iwasawa a5c4f3
    m_prop[0].bind(m_rasterToolSize);
shun-iwasawa a5c4f3
    m_prop[0].bind(m_hardness);
shun-iwasawa a5c4f3
    m_prop[0].bind(m_modifierSize);
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  if (targetType & TTool::RasterImage) {
shun-iwasawa a5c4f3
    m_prop[0].bind(m_opacity);
shun-iwasawa a5c4f3
    m_prop[0].bind(m_modifierOpacity);
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  m_prop[0].bind(m_type);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_prop[0].bind(m_edgeCount);
shun-iwasawa a5c4f3
  m_prop[0].bind(m_rotate);
shun-iwasawa a5c4f3
  if (targetType & TTool::Vectors) {
shun-iwasawa a5c4f3
    m_prop[0].bind(m_autogroup);
shun-iwasawa a5c4f3
    m_prop[0].bind(m_autofill);
shun-iwasawa a5c4f3
    m_prop[0].bind(m_snap);
shun-iwasawa a5c4f3
    m_snap.setId("Snap");
shun-iwasawa a5c4f3
    m_prop[0].bind(m_snapSensitivity);
shun-iwasawa a5c4f3
    m_snapSensitivity.addValue(LOW_WSTR);
shun-iwasawa a5c4f3
    m_snapSensitivity.addValue(MEDIUM_WSTR);
shun-iwasawa a5c4f3
    m_snapSensitivity.addValue(HIGH_WSTR);
shun-iwasawa a5c4f3
    m_snapSensitivity.setId("SnapSensitivity");
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  if (targetType & TTool::ToonzImage) {
shun-iwasawa a5c4f3
    m_prop[0].bind(m_selective);
shun-iwasawa a5c4f3
    m_prop[0].bind(m_pencil);
shun-iwasawa a5c4f3
    m_pencil.setId("PencilMode");
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  m_prop[0].bind(m_smooth);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_capStyle.addValue(BUTT_WSTR, QString::fromStdWString(BUTT_WSTR));
shun-iwasawa a5c4f3
  m_capStyle.addValue(ROUNDC_WSTR, QString::fromStdWString(ROUNDC_WSTR));
shun-iwasawa a5c4f3
  m_capStyle.addValue(PROJECTING_WSTR,
shun-iwasawa a5c4f3
                      QString::fromStdWString(PROJECTING_WSTR));
shun-iwasawa a5c4f3
  m_capStyle.setId("Cap");
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_joinStyle.addValue(MITER_WSTR, QString::fromStdWString(MITER_WSTR));
shun-iwasawa a5c4f3
  m_joinStyle.addValue(ROUNDJ_WSTR, QString::fromStdWString(ROUNDJ_WSTR));
shun-iwasawa a5c4f3
  m_joinStyle.addValue(BEVEL_WSTR, QString::fromStdWString(BEVEL_WSTR));
shun-iwasawa a5c4f3
  m_joinStyle.setId("Join");
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_miterJoinLimit.setId("Miter");
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_prop[1].bind(m_capStyle);
shun-iwasawa a5c4f3
  m_prop[1].bind(m_joinStyle);
shun-iwasawa a5c4f3
  m_prop[1].bind(m_miterJoinLimit);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_selective.setId("Selective");
shun-iwasawa a5c4f3
  m_rotate.setId("Rotate");
shun-iwasawa a5c4f3
  m_autogroup.setId("AutoGroup");
shun-iwasawa a5c4f3
  m_autofill.setId("Autofill");
shun-iwasawa a5c4f3
  m_smooth.setId("Smooth");
shun-iwasawa a5c4f3
  m_type.setId("GeometricShape");
shun-iwasawa a5c4f3
  m_edgeCount.setId("GeometricEdge");
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
void PrimitiveParam::updateTranslation() {
shun-iwasawa a5c4f3
  m_type.setQStringName(tr("Shape:"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Rectangle", tr("Rectangle"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Circle", tr("Circle"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Ellipse", tr("Ellipse"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Line", tr("Line"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Polyline", tr("Polyline"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Arc", tr("Arc"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"MultiArc", tr("MultiArc"));
shun-iwasawa a5c4f3
  m_type.setItemUIName(L"Polygon", tr("Polygon"));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_toolSize.setQStringName(tr("Size:"));
shun-iwasawa a5c4f3
  m_rasterToolSize.setQStringName(tr("Thickness:"));
shun-iwasawa a5c4f3
  m_opacity.setQStringName(tr("Opacity:"));
shun-iwasawa a5c4f3
  m_hardness.setQStringName(tr("Hardness:"));
shun-iwasawa a5c4f3
  m_edgeCount.setQStringName(tr("Polygon Sides:"));
shun-iwasawa a5c4f3
  m_rotate.setQStringName(tr("Rotate"));
shun-iwasawa a5c4f3
  m_autogroup.setQStringName(tr("Auto Group"));
shun-iwasawa a5c4f3
  m_autofill.setQStringName(tr("Auto Fill"));
shun-iwasawa a5c4f3
  m_smooth.setQStringName(tr("Smooth"));
shun-iwasawa a5c4f3
  m_selective.setQStringName(tr("Selective"));
shun-iwasawa a5c4f3
  m_pencil.setQStringName(tr("Pencil Mode"));
shun-iwasawa a5c4f3
  m_modifierSize.setQStringName(tr("Size"));
shun-iwasawa a5c4f3
  m_modifierOpacity.setQStringName(tr("Opacity"));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_capStyle.setQStringName(tr("Cap"));
shun-iwasawa a5c4f3
  m_capStyle.setItemUIName(BUTT_WSTR, tr("Butt cap"));
shun-iwasawa a5c4f3
  m_capStyle.setItemUIName(ROUNDC_WSTR, tr("Round cap"));
shun-iwasawa a5c4f3
  m_capStyle.setItemUIName(PROJECTING_WSTR, tr("Projecting cap"));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_joinStyle.setQStringName(tr("Join"));
shun-iwasawa a5c4f3
  m_joinStyle.setItemUIName(MITER_WSTR, tr("Miter join"));
shun-iwasawa a5c4f3
  m_joinStyle.setItemUIName(ROUNDJ_WSTR, tr("Round join"));
shun-iwasawa a5c4f3
  m_joinStyle.setItemUIName(BEVEL_WSTR, tr("Bevel join"));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_miterJoinLimit.setQStringName(tr("Miter:"));
shun-iwasawa a5c4f3
  m_snap.setQStringName(tr("Snap"));
shun-iwasawa a5c4f3
  m_snapSensitivity.setQStringName(tr(""));
shun-iwasawa a5c4f3
  if (m_targetType & TTool::Vectors) {
shun-iwasawa a5c4f3
    m_snapSensitivity.setItemUIName(LOW_WSTR, tr("Low"));
shun-iwasawa a5c4f3
    m_snapSensitivity.setItemUIName(MEDIUM_WSTR, tr("Med"));
shun-iwasawa a5c4f3
    m_snapSensitivity.setItemUIName(HIGH_WSTR, tr("High"));
Shinya Kitaoka 120a6e
  }
shun-iwasawa a5c4f3
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Abstract Class Primitive
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class Primitive {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  bool m_isEditing, m_rasterTool, m_isPrompting;
Shinya Kitaoka 120a6e
  GeometricTool *m_tool;
Shinya Kitaoka 120a6e
  PrimitiveParam *m_param;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Primitive(PrimitiveParam *param, GeometricTool *tool, bool rasterTool)
Shinya Kitaoka 120a6e
      : m_param(param)
Shinya Kitaoka 120a6e
      , m_tool(tool)
Shinya Kitaoka 120a6e
      , m_isEditing(false)
Shinya Kitaoka 120a6e
      , m_rasterTool(rasterTool)
Shinya Kitaoka 120a6e
      , m_isPrompting(false) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double getThickness() const {
Shinya Kitaoka 120a6e
    if (m_rasterTool)
Shinya Kitaoka 120a6e
      return m_param->m_rasterToolSize.getValue() * 0.5;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return m_param->m_toolSize.getValue() * 0.5;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setIsPrompting(bool value) { m_isPrompting = value; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual std::string getName() const = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual ~Primitive() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual void leftButtonDown(const TPointD &p, const TMouseEvent &e){};
Shinya Kitaoka 120a6e
  virtual void leftButtonDrag(const TPointD &p, const TMouseEvent &e){};
Shinya Kitaoka 120a6e
  virtual void leftButtonUp(const TPointD &p, const TMouseEvent &e){};
Shinya Kitaoka 120a6e
  virtual void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e){};
Shinya Kitaoka 120a6e
  virtual void rightButtonDown(const TPointD &p, const TMouseEvent &e){};
Shinya Kitaoka 120a6e
  virtual void mouseMove(const TPointD &p, const TMouseEvent &e){};
shun-iwasawa 7f1e30
  virtual bool keyDown(QKeyEvent *event) { return false; }
Shinya Kitaoka 120a6e
  virtual void onEnter(){};
Shinya Kitaoka 120a6e
  virtual void draw(){};
Shinya Kitaoka 120a6e
  virtual void onActivate(){};
Shinya Kitaoka 120a6e
  virtual void onDeactivate(){};
Shinya Kitaoka 120a6e
  virtual void onImageChanged(){};
Jeremy Bullock 977232
  TPointD calculateSnap(TPointD pos);
Jeremy Bullock 977232
  void drawSnap();
Jeremy Bullock 977232
  TPointD getSnap(TPointD pos);
Jeremy Bullock 977232
  void resetSnap();
Jeremy Bullock 977232
  TPointD checkGuideSnapping(TPointD pos);
pojienie a82098
  bool getSmooth() { return m_param->m_smooth.getValue(); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  virtual TStroke *makeStroke() const = 0;
shun-iwasawa 71d24f
  virtual bool canTouchImageOnPreLeftClick() { return true; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Jeremy Bullock 977232
//-----------------------------------------------------------------------------
Jeremy Bullock 977232
Jeremy Bullock 977232
void Primitive::resetSnap() {
Jeremy Bullock 977232
  m_param->m_strokeIndex1 = -1;
Jeremy Bullock 977232
  m_param->m_w1           = -1;
Jeremy Bullock 977232
  m_param->m_foundSnap    = false;
Jeremy Bullock 977232
}
Jeremy Bullock 977232
Jeremy Bullock 977232
//-----------------------------------------------------------------------------
Jeremy Bullock 977232
Jeremy Bullock 977232
TPointD Primitive::calculateSnap(TPointD pos) {
Jeremy Bullock 977232
  m_param->m_foundSnap = false;
Jeremy Bullock 977232
  if (Preferences::instance()->getVectorSnappingTarget() == 1) return pos;
Jeremy Bullock 977232
  TVectorImageP vi(TTool::getImage(false));
Jeremy Bullock 977232
  TPointD snapPoint = pos;
Jeremy Bullock 977232
  if (vi && m_param->m_snap.getValue()) {
Jeremy Bullock 977232
    double minDistance2     = m_param->m_minDistance2;
Jeremy Bullock 977232
    m_param->m_strokeIndex1 = -1;
Jeremy Bullock 977232
Jeremy Bullock 977232
    int i, strokeNumber = vi->getStrokeCount();
Jeremy Bullock 977232
Jeremy Bullock 977232
    TStroke *stroke;
Jeremy Bullock 977232
    double distance2, outW;
Jeremy Bullock 977232
Jeremy Bullock 977232
    for (i = 0; i < strokeNumber; i++) {
Jeremy Bullock 977232
      stroke = vi->getStroke(i);
Jeremy Bullock 977232
      if (stroke->getNearestW(pos, outW, distance2) &&
Jeremy Bullock 977232
          distance2 < minDistance2) {
Jeremy Bullock 977232
        minDistance2            = distance2;
Jeremy Bullock 977232
        m_param->m_strokeIndex1 = i;
Jeremy Bullock 977232
        if (areAlmostEqual(outW, 0.0, 1e-3))
Jeremy Bullock 977232
          m_param->m_w1 = 0.0;
Jeremy Bullock 977232
        else if (areAlmostEqual(outW, 1.0, 1e-3))
Jeremy Bullock 977232
          m_param->m_w1 = 1.0;
Jeremy Bullock 977232
        else
shun-iwasawa 036853
          m_param->m_w1 = outW;
Jeremy Bullock 977232
        TThickPoint point1   = stroke->getPoint(m_param->m_w1);
Jeremy Bullock 977232
        snapPoint            = TPointD(point1.x, point1.y);
Jeremy Bullock 977232
        m_param->m_foundSnap = true;
Jeremy Bullock 977232
        m_param->m_snapPoint = snapPoint;
Jeremy Bullock 977232
      }
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
  }
Jeremy Bullock 977232
  return snapPoint;
Jeremy Bullock 977232
}
Jeremy Bullock 977232
Jeremy Bullock 977232
//-----------------------------------------------------------------------------
Jeremy Bullock 977232
Jeremy Bullock 977232
TPointD Primitive::getSnap(TPointD pos) {
Jeremy Bullock 977232
  if (m_param->m_foundSnap)
Jeremy Bullock 977232
    return m_param->m_snapPoint;
Jeremy Bullock 977232
  else
Jeremy Bullock 977232
    return pos;
Jeremy Bullock 977232
}
Jeremy Bullock 977232
Jeremy Bullock 977232
// Primitive::drawSnap and Primitive::checkGuideSnapping are below the
Jeremy Bullock 977232
// Geometric Tool definition since they use the m_tool property of Primitive
Jeremy Bullock 977232
// but it isn't defined yet up here.
Jeremy Bullock 977232
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Rectangle Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RectanglePrimitive final : public Primitive {
Shinya Kitaoka 120a6e
  TRectD m_selectingRect;
Shinya Kitaoka 120a6e
  TPointD m_pos;
Shinya Kitaoka 120a6e
  TPointD m_startPoint;
Shinya Kitaoka 120a6e
  TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RectanglePrimitive(PrimitiveParam *param, GeometricTool *tool,
Shinya Kitaoka 120a6e
                     bool reasterTool)
Shinya Kitaoka 120a6e
      : Primitive(param, tool, reasterTool) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getName() const override {
Shinya Kitaoka 120a6e
    return "Rectangle";
Shinya Kitaoka 120a6e
  }  // W_ToolOptions_ShapeRect"; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  TStroke *makeStroke() const override;
Shinya Kitaoka 473e70
  void draw() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &realPos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void onEnter() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Circle Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class CirclePrimitive final : public Primitive {
Shinya Kitaoka 120a6e
  TPointD m_centre;
Shinya Kitaoka 120a6e
  TPointD m_pos;
Shinya Kitaoka 120a6e
  double m_radius;
Shinya Kitaoka 120a6e
  TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  CirclePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Shinya Kitaoka 120a6e
      : Primitive(param, tool, reasterTool) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getName() const override {
Shinya Kitaoka 120a6e
    return "Circle";
Shinya Kitaoka 120a6e
  }  // W_ToolOptions_ShapeCircle";}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void draw() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  TStroke *makeStroke() const override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void onEnter() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MultiLine Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const double joinDistance = 5.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class MultiLinePrimitive : public Primitive {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  std::vector<tpointd> m_vertex;</tpointd>
Shinya Kitaoka 120a6e
  TPointD m_mousePosition;
Shinya Kitaoka 120a6e
  TPixel32 m_color;
Shinya Kitaoka 120a6e
  bool m_closed, m_isSingleLine;
Shinya Kitaoka 120a6e
  bool m_speedMoved;        //!< True after moveSpeed(), false after addVertex()
Shinya Kitaoka 120a6e
  bool m_beforeSpeedMoved;  //!< Old value of m_speedMoved
Shinya Kitaoka 120a6e
  bool m_ctrlDown;          //!< Whether ctrl is hold down
Shinya Kitaoka 120a6e
  MultilinePrimitiveUndo *m_undo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MultiLinePrimitive(PrimitiveParam *param, GeometricTool *tool,
Shinya Kitaoka 120a6e
                     bool reasterTool)
Shinya Kitaoka 120a6e
      : Primitive(param, tool, reasterTool)
Shinya Kitaoka 120a6e
      , m_closed(false)
Shinya Kitaoka 120a6e
      , m_isSingleLine(false)
Shinya Kitaoka 120a6e
      , m_speedMoved(false)
Shinya Kitaoka 120a6e
      , m_beforeSpeedMoved(false)
Shinya Kitaoka 120a6e
      , m_ctrlDown(false) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getName() const override {
Shinya Kitaoka 120a6e
    return "Polyline";
Shinya Kitaoka 120a6e
  }  // W_ToolOptions_ShapePolyline";}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addVertex(const TPointD &pos);
Shinya Kitaoka 120a6e
  void moveSpeed(const TPointD &delta);
Shinya Kitaoka 473e70
  void draw() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
shun-iwasawa 7f1e30
  bool keyDown(QKeyEvent *event) override;
Shinya Kitaoka 473e70
  TStroke *makeStroke() const override;
Shinya Kitaoka 120a6e
  void endLine();
Shinya Kitaoka 473e70
  void onActivate() override;
Shinya Kitaoka 473e70
  void onDeactivate() override {
Shinya Kitaoka 120a6e
    m_vertex.clear();
Shinya Kitaoka 120a6e
    m_speedMoved       = false;
Shinya Kitaoka 120a6e
    m_beforeSpeedMoved = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void onEnter() override;
Shinya Kitaoka 473e70
  void onImageChanged() override;
Shinya Kitaoka 120a6e
  void setVertexes(const std::vector<tpointd> &vertex) { m_vertex = vertex; };</tpointd>
Shinya Kitaoka 120a6e
  void setSpeedMoved(bool speedMoved) { m_speedMoved = speedMoved; };
shun-iwasawa 71d24f
shun-iwasawa 71d24f
  // Only execute touchImage when clicking the first point of the polyline
shun-iwasawa 71d24f
  bool canTouchImageOnPreLeftClick() override { return m_vertex.empty(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultilinePrimitiveUndo::undo() const {
Shinya Kitaoka 120a6e
  m_tool->setVertexes(m_oldVertex);
Shinya Kitaoka 120a6e
  int count       = m_oldVertex.size();
Shinya Kitaoka 120a6e
  bool speedMoved = (count != 0 && count % 4 != 1);
Shinya Kitaoka 120a6e
  m_tool->setSpeedMoved(speedMoved);
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultilinePrimitiveUndo::redo() const {
Shinya Kitaoka 120a6e
  m_tool->setVertexes(m_newVertex);
Shinya Kitaoka 120a6e
  int count       = m_newVertex.size();
Shinya Kitaoka 120a6e
  bool speedMoved = (count != 0 && count % 4 != 1);
Shinya Kitaoka 120a6e
  m_tool->setSpeedMoved(speedMoved);
Shinya Kitaoka 120a6e
  TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString MultilinePrimitiveUndo::getToolName() {
Shinya Kitaoka 120a6e
  return QString("Geometric Tool %1")
Shinya Kitaoka 120a6e
      .arg(QString::fromStdString(m_tool->getName()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Line Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class LinePrimitive final : public MultiLinePrimitive {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  LinePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Shinya Kitaoka 120a6e
      : MultiLinePrimitive(param, tool, reasterTool) {
Shinya Kitaoka 120a6e
    m_isSingleLine = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getName() const override {
Shinya Kitaoka 120a6e
    return "Line";
Shinya Kitaoka 120a6e
  }  // W_ToolOptions_ShapePolyline";}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void draw() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
Jeremy Bullock 977232
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e) override {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Ellipse Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class EllipsePrimitive final : public Primitive {
Shinya Kitaoka 120a6e
  TPointD m_pos;
Shinya Kitaoka 120a6e
  TRectD m_selectingRect;
Shinya Kitaoka 120a6e
  TPointD m_startPoint;
Shinya Kitaoka 120a6e
  TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  EllipsePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Shinya Kitaoka 120a6e
      : Primitive(param, tool, reasterTool) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getName() const override {
Shinya Kitaoka 120a6e
    return "Ellipse";
Shinya Kitaoka 120a6e
  }  // W_ToolOptions_ShapeEllipse";}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void draw() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &realPos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  TStroke *makeStroke() const override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void onEnter() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
pojienie 5aac48
// Multi Arc Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie 5aac48
class MultiArcPrimitive : public Primitive {
Shinya Kitaoka 120a6e
  TStroke *m_stroke;
pojienie a82098
  TStroke *m_strokeTemp;
Shinya Kitaoka 120a6e
  TPointD m_startPoint, m_endPoint, m_centralPoint;
Shinya Kitaoka 120a6e
  int m_clickNumber;
Shinya Kitaoka 120a6e
  TPixel32 m_color;
pojienie e8ee24
  int m_undoCount;
Toshihiro Shimizu 890ddd
pojienie bdf2c1
protected:
pojienie bdf2c1
  bool m_isSingleArc;
pojienie bdf2c1
Toshihiro Shimizu 890ddd
public:
pojienie 5aac48
  MultiArcPrimitive(PrimitiveParam *param, GeometricTool *tool,
pojienie 5aac48
                    bool reasterTool)
pojienie bdf2c1
      : Primitive(param, tool, reasterTool)
pojienie bdf2c1
      , m_stroke(0)
pojienie a82098
      , m_strokeTemp(0)
pojienie bdf2c1
      , m_clickNumber(0)
pojienie e8ee24
      , m_isSingleArc(false)
pojienie e8ee24
      , m_undoCount(0) {}
Shinya Kitaoka 120a6e
pojienie 5aac48
  ~MultiArcPrimitive() { delete m_stroke; }
Shinya Kitaoka 120a6e
pojienie 5aac48
  std::string getName() const override { return "MultiArc"; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  TStroke *makeStroke() const override;
Shinya Kitaoka 473e70
  void draw() override;
shun-iwasawa 71d24f
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
pojienie a82098
  void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e) override;
pojienie bdf2c1
  bool keyDown(QKeyEvent *event) override;
Shinya Kitaoka 473e70
  void onEnter() override;
pojienie 12059e
  void onDeactivate() override {
pojienie 12059e
    delete m_stroke;
pojienie a82098
    delete m_strokeTemp;
pojienie a82098
    m_stroke      = 0;
pojienie a82098
    m_strokeTemp  = 0;
pojienie a82098
    m_clickNumber = 0;
pojienie e8ee24
    TUndoManager::manager()->popUndo(m_undoCount);
pojienie e8ee24
    m_undoCount = 0;
pojienie 12059e
  }
pojienie e8ee24
pojienie e8ee24
  void replaceData(TStroke *stroke, TStroke *strokeTemp, TPointD startPoint,
pojienie 8f2ac7
                   TPointD endPoint, TPointD centralPoint, int clickNumber) {
pojienie e8ee24
    delete m_stroke;
pojienie e8ee24
    delete m_strokeTemp;
pojienie e8ee24
    m_stroke       = stroke;
pojienie e8ee24
    m_strokeTemp   = strokeTemp;
pojienie e8ee24
    m_startPoint   = startPoint;
pojienie e8ee24
    m_endPoint     = endPoint;
pojienie e8ee24
    m_centralPoint = centralPoint;
pojienie e8ee24
    m_clickNumber  = clickNumber;
pojienie e8ee24
  }
pojienie e8ee24
pojienie e8ee24
  void decreaseUndo() { --m_undoCount; }
pojienie e8ee24
pojienie e8ee24
  void increaseUndo() { ++m_undoCount; }
shun-iwasawa 71d24f
shun-iwasawa 71d24f
  // Only execute touchImage when clicking the first point of the multi arc
shun-iwasawa 71d24f
  bool canTouchImageOnPreLeftClick() override { return m_clickNumber == 0; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
pojienie e8ee24
//-----------------------------------------------------------------------------
pojienie e8ee24
pojienie e8ee24
void MultiArcPrimitiveUndoData::replace(MultiArcPrimitive *tool) const {
pojienie e8ee24
  TStroke *stroke     = 0;
pojienie e8ee24
  TStroke *strokeTemp = 0;
pojienie e8ee24
  if (m_stroke) {
pojienie e8ee24
    stroke = new TStroke(*m_stroke);
pojienie e8ee24
  }
pojienie e8ee24
  if (m_strokeTemp) {
pojienie e8ee24
    strokeTemp = new TStroke(*m_strokeTemp);
pojienie e8ee24
  }
pojienie e8ee24
  tool->replaceData(stroke, strokeTemp, m_startPoint, m_endPoint,
pojienie 8f2ac7
                    m_centralPoint, m_clickNumber);
pojienie e8ee24
}
pojienie e8ee24
pojienie e8ee24
//-----------------------------------------------------------------------------
pojienie e8ee24
pojienie e8ee24
void MultiArcPrimitiveUndo::undo() const {
pojienie e8ee24
  m_undo.replace(m_tool);
pojienie e8ee24
  m_tool->decreaseUndo();
pojienie e8ee24
  TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
pojienie e8ee24
}
pojienie e8ee24
pojienie e8ee24
//-----------------------------------------------------------------------------
pojienie e8ee24
pojienie e8ee24
void MultiArcPrimitiveUndo::redo() const {
pojienie e8ee24
  m_redo->replace(m_tool);
pojienie e8ee24
  m_tool->increaseUndo();
pojienie e8ee24
  TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
pojienie e8ee24
}
pojienie e8ee24
pojienie e8ee24
//----------------------------------------------------------------------------
pojienie e8ee24
pojienie e8ee24
QString MultiArcPrimitiveUndo::getToolName() {
pojienie e8ee24
  return QString("Geometric Tool %1")
pojienie e8ee24
      .arg(QString::fromStdString(m_tool->getName()));
pojienie e8ee24
}
pojienie e8ee24
Toshihiro Shimizu 890ddd
//=============================================================================
pojienie 5aac48
// Arc Primitive Class Declaration
pojienie 5aac48
//-----------------------------------------------------------------------------
pojienie 5aac48
pojienie 5aac48
class ArcPrimitive final : public MultiArcPrimitive {
pojienie 5aac48
public:
pojienie 5aac48
  ArcPrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
pojienie bdf2c1
      : MultiArcPrimitive(param, tool, reasterTool) {
pojienie bdf2c1
    m_isSingleArc = true;
pojienie bdf2c1
  }
pojienie 5aac48
pojienie 5aac48
  std::string getName() const override {
pojienie 5aac48
    return "Arc";
pojienie 5aac48
  }  // _ToolOptions_ShapeArc";}
pojienie 5aac48
};
pojienie 5aac48
pojienie 5aac48
//=============================================================================
Toshihiro Shimizu 890ddd
// Polygon Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class PolygonPrimitive final : public Primitive {
Shinya Kitaoka 120a6e
  TPointD m_startPoint, m_centre;
Shinya Kitaoka 120a6e
  double m_radius;
Shinya Kitaoka 120a6e
  TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PolygonPrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Shinya Kitaoka 120a6e
      : Primitive(param, tool, reasterTool) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  std::string getName() const override {
Shinya Kitaoka 120a6e
    return "Polygon";
Shinya Kitaoka 120a6e
  }  // W_ToolOptions_ShapePolygon";}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  TStroke *makeStroke() const override;
Shinya Kitaoka 473e70
  void draw() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override;
Shinya Kitaoka 473e70
  void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
Jeremy Bullock 977232
  void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Geometric Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
shun-iwasawa a5c4f3
GeometricTool::GeometricTool(int targetType)
shun-iwasawa a5c4f3
    : TTool("T_Geometric")
shun-iwasawa a5c4f3
    , m_primitive(0)
shun-iwasawa a5c4f3
    , m_param(targetType)
shun-iwasawa a5c4f3
    , m_active(false)
shun-iwasawa a5c4f3
    , m_isRotatingOrMoving(false)
shun-iwasawa a5c4f3
    , m_rotatedStroke(0)
shun-iwasawa a5c4f3
    , m_firstTime(true)
shun-iwasawa a5c4f3
    , m_notifier(nullptr)
shun-iwasawa a5c4f3
    , m_tileSaver(nullptr)
shun-iwasawa a5c4f3
    , m_tileSaverCM(nullptr) {
shun-iwasawa a5c4f3
  bind(targetType);
shun-iwasawa a5c4f3
  if ((targetType & TTool::RasterImage) || (targetType & TTool::ToonzImage)) {
shun-iwasawa a5c4f3
    addPrimitive(new RectanglePrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new CirclePrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new EllipsePrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new LinePrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new MultiLinePrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new ArcPrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new MultiArcPrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
    addPrimitive(new PolygonPrimitive(&m_param, this, true));
shun-iwasawa a5c4f3
  } else  // targetType == 1
shun-iwasawa a5c4f3
  {
shun-iwasawa a5c4f3
    // vector
shun-iwasawa a5c4f3
    addPrimitive(m_primitive = new RectanglePrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new CirclePrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new EllipsePrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new LinePrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new MultiLinePrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new ArcPrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new MultiArcPrimitive(&m_param, this, false));
shun-iwasawa a5c4f3
    addPrimitive(new PolygonPrimitive(&m_param, this, false));
Shinya Kitaoka 120a6e
  }
shun-iwasawa a5c4f3
}
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
GeometricTool::~GeometricTool() {
shun-iwasawa a5c4f3
  delete m_rotatedStroke;
shun-iwasawa a5c4f3
  std::map<std::wstring, *="" primitive="">::iterator it;</std::wstring,>
shun-iwasawa a5c4f3
  for (it = m_primitiveTable.begin(); it != m_primitiveTable.end(); ++it)
shun-iwasawa a5c4f3
    delete it->second;
shun-iwasawa a5c4f3
}
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::updateTranslation() { m_param.updateTranslation(); }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::addPrimitive(Primitive *p) {
shun-iwasawa a5c4f3
  // TODO: aggiungere il controllo per evitare nomi ripetuti
shun-iwasawa a5c4f3
  std::wstring name = ::to_wstring(p->getName());
shun-iwasawa a5c4f3
  // wstring name = TStringTable::translate(p->getName());
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  m_primitiveTable[name] = p;
shun-iwasawa a5c4f3
  m_param.m_type.addValue(name);
shun-iwasawa a5c4f3
}
shun-iwasawa 71d24f
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::changeType(std::wstring name) {
shun-iwasawa a5c4f3
  std::map<std::wstring, *="" primitive="">::iterator it =</std::wstring,>
shun-iwasawa a5c4f3
      m_primitiveTable.find(name);
shun-iwasawa a5c4f3
  if (it != m_primitiveTable.end()) {
shun-iwasawa a5c4f3
    if (m_primitive) m_primitive->onDeactivate();
shun-iwasawa a5c4f3
    m_primitive = it->second;
shun-iwasawa 01dafa
  }
shun-iwasawa a5c4f3
}
shun-iwasawa 01dafa
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
bool GeometricTool::preLeftButtonDown() {
shun-iwasawa a5c4f3
  if (getViewer() && getViewer()->getGuidedStrokePickerMode()) return false;
shun-iwasawa a5c4f3
  if (getApplication()->getCurrentObject()->isSpline()) return true;
pojienie 57e1e4
shun-iwasawa a5c4f3
  // in the halfway through the drawing of Polyline / MultiArc primitive, OT
shun-iwasawa a5c4f3
  // should not call touchImage or the m_frameCreated / m_levelCreated flags
shun-iwasawa a5c4f3
  // will be reset.
shun-iwasawa a5c4f3
  if (m_primitive && !m_primitive->canTouchImageOnPreLeftClick()) return true;
shun-iwasawa a5c4f3
  // NEEDS to be done even if(m_active), due
shun-iwasawa a5c4f3
  // to the HORRIBLE m_frameCreated / m_levelCreated
shun-iwasawa a5c4f3
  // mechanism. touchImage() is the ONLY function
shun-iwasawa a5c4f3
  // resetting them to false...                       >_<
shun-iwasawa a5c4f3
  m_active = !!touchImage();
shun-iwasawa a5c4f3
  return true;
shun-iwasawa a5c4f3
}
pojienie 57e1e4
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::leftButtonDown(const TPointD &p, const TMouseEvent &e) {
shun-iwasawa a5c4f3
  if (getViewer() && getViewer()->getGuidedStrokePickerMode()) {
shun-iwasawa a5c4f3
    getViewer()->doPickGuideStroke(p);
shun-iwasawa a5c4f3
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  if (m_isRotatingOrMoving) {
shun-iwasawa a5c4f3
    addStroke();
shun-iwasawa a5c4f3
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->leftButtonDown(p, e);
shun-iwasawa a5c4f3
  invalidate();
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::leftButtonDrag(const TPointD &p, const TMouseEvent &e) {
shun-iwasawa a5c4f3
  if (!m_active) return;
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->leftButtonDrag(p, e);
shun-iwasawa a5c4f3
  invalidate();
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::leftButtonUp(const TPointD &p, const TMouseEvent &e) {
shun-iwasawa a5c4f3
  if (!m_active) return;
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->leftButtonUp(p, e);
shun-iwasawa a5c4f3
  invalidate();
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::leftButtonDoubleClick(const TPointD &p,
shun-iwasawa a5c4f3
                                          const TMouseEvent &e) {
shun-iwasawa a5c4f3
  if (!m_active) return;
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->leftButtonDoubleClick(p, e);
shun-iwasawa a5c4f3
  invalidate();
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
pojienie 57e1e4
shun-iwasawa a5c4f3
bool GeometricTool::keyDown(QKeyEvent *event) {
shun-iwasawa a5c4f3
  return m_primitive->keyDown(event);
shun-iwasawa a5c4f3
}
pojienie 57e1e4
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::onImageChanged() {
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->onImageChanged();
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  m_isRotatingOrMoving = false;
shun-iwasawa a5c4f3
  delete m_rotatedStroke;
shun-iwasawa a5c4f3
  m_rotatedStroke = 0;
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  invalidate();
shun-iwasawa a5c4f3
}
pojienie 3df02e
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::onColorStyleChanged() {
shun-iwasawa a5c4f3
  if (m_param.m_targetType & TTool::ToonzImage ||
shun-iwasawa a5c4f3
      m_param.m_targetType & TTool::RasterImage)
shun-iwasawa a5c4f3
    getApplication()->getCurrentTool()->notifyToolChanged();
shun-iwasawa a5c4f3
}
pojienie 3df02e
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::rightButtonDown(const TPointD &p, const TMouseEvent &e) {
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->rightButtonDown(p, e);
shun-iwasawa a5c4f3
  invalidate();
shun-iwasawa a5c4f3
}
pojienie 3df02e
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::mouseMove(const TPointD &p, const TMouseEvent &e) {
shun-iwasawa a5c4f3
  m_currentCursorPos = p;
shun-iwasawa a5c4f3
  if (m_isRotatingOrMoving) {
shun-iwasawa a5c4f3
    // move
shun-iwasawa a5c4f3
    if (e.isCtrlPressed()) {
shun-iwasawa a5c4f3
      // if ctrl wasn't pressed, it means the user has switched from
shun-iwasawa a5c4f3
      // rotation to move. Thus, re-initiate move-relevant variables
shun-iwasawa a5c4f3
      if (!m_wasCtrlPressed) {
shun-iwasawa a5c4f3
        m_wasCtrlPressed = true;
pojienie 3df02e
pojienie 3df02e
        m_originalCursorPos = m_currentCursorPos;
shun-iwasawa a5c4f3
        m_lastMoveStrokePos = TPointD(0, 0);
pojienie 3df02e
      }
pojienie 3df02e
shun-iwasawa a5c4f3
      // move the stroke to the original location
shun-iwasawa a5c4f3
      double x = -m_lastMoveStrokePos.x;
shun-iwasawa a5c4f3
      double y = -m_lastMoveStrokePos.y;
shun-iwasawa a5c4f3
      m_rotatedStroke->transform(TTranslation(x, y));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      // move the stroke according to current mouse position
shun-iwasawa a5c4f3
      double dx           = m_currentCursorPos.x - m_originalCursorPos.x;
shun-iwasawa a5c4f3
      double dy           = m_currentCursorPos.y - m_originalCursorPos.y;
shun-iwasawa a5c4f3
      m_lastMoveStrokePos = TPointD(dx, dy);
shun-iwasawa a5c4f3
      m_rotatedStroke->transform(TTranslation(dx, dy));
pojienie 57e1e4
      invalidate();
pojienie 57e1e4
      return;
pojienie 57e1e4
    }
pojienie 57e1e4
shun-iwasawa a5c4f3
    // if ctrl was pressed, it means the user has switched from
shun-iwasawa a5c4f3
    // move to rotation. Thus, re-initiate rotation-relevant variables
shun-iwasawa a5c4f3
    if (m_wasCtrlPressed) {
shun-iwasawa a5c4f3
      m_wasCtrlPressed = false;
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
      m_lastRotateAngle   = 0;
shun-iwasawa a5c4f3
      m_originalCursorPos = m_currentCursorPos;
shun-iwasawa a5c4f3
      TRectD bbox         = m_rotatedStroke->getBBox();
shun-iwasawa a5c4f3
      m_rotateCenter      = 0.5 * (bbox.getP11() + bbox.getP00());
pojienie 57e1e4
    }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
    // rotate
shun-iwasawa a5c4f3
    // first, rotate the stroke back to original
shun-iwasawa a5c4f3
    m_rotatedStroke->transform(TRotation(m_rotateCenter, -m_lastRotateAngle));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    // then, rotate it according to mouse position
shun-iwasawa a5c4f3
    // this formula is from: https://stackoverflow.com/a/31334882
shun-iwasawa a5c4f3
    TPointD center = m_rotateCenter;
shun-iwasawa a5c4f3
    TPointD org    = m_originalCursorPos;
shun-iwasawa a5c4f3
    TPointD cur    = m_currentCursorPos;
shun-iwasawa a5c4f3
    double angle1  = atan2(cur.y - center.y, cur.x - center.x);
shun-iwasawa a5c4f3
    double angle2  = atan2(org.y - center.y, org.x - center.x);
shun-iwasawa a5c4f3
    double angle   = (angle1 - angle2) * 180 / 3.14;
shun-iwasawa a5c4f3
    if (e.isShiftPressed()) {
shun-iwasawa a5c4f3
      angle = ((int)angle / 45) * 45;
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
    m_rotatedStroke->transform(TRotation(m_rotateCenter, angle));
shun-iwasawa a5c4f3
    m_lastRotateAngle = angle;
shun-iwasawa a5c4f3
    invalidate();
shun-iwasawa a5c4f3
    return;
Shinya Kitaoka 38fd86
  }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->mouseMove(p, e);
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::onActivate() {
shun-iwasawa a5c4f3
  if (m_firstTime) {
shun-iwasawa a5c4f3
    m_param.m_toolSize.setValue(GeometricSize);
shun-iwasawa a5c4f3
    m_param.m_rasterToolSize.setValue(GeometricRasterSize);
shun-iwasawa a5c4f3
    m_param.m_opacity.setValue(GeometricOpacity);
shun-iwasawa a5c4f3
    m_param.m_hardness.setValue(GeometricBrushHardness);
shun-iwasawa a5c4f3
    m_param.m_selective.setValue(GeometricSelective ? 1 : 0);
shun-iwasawa a5c4f3
    m_param.m_rotate.setValue(GeometricRotate ? 1 : 0);
shun-iwasawa a5c4f3
    m_param.m_autogroup.setValue(GeometricGroupIt ? 1 : 0);
shun-iwasawa a5c4f3
    m_param.m_smooth.setValue(GeometricSmooth ? 1 : 0);
shun-iwasawa a5c4f3
    m_param.m_autofill.setValue(GeometricAutofill ? 1 : 0);
shun-iwasawa a5c4f3
    std::wstring typeCode = ::to_wstring(GeometricType.getValue());
shun-iwasawa a5c4f3
    m_param.m_type.setValue(typeCode);
shun-iwasawa a5c4f3
    GeometricType = ::to_string(typeCode);
shun-iwasawa a5c4f3
    m_typeCode    = typeCode;
shun-iwasawa a5c4f3
    changeType(typeCode);
shun-iwasawa a5c4f3
    m_param.m_edgeCount.setValue(GeometricEdgeCount);
shun-iwasawa a5c4f3
    m_param.m_pencil.setValue(GeometricPencil ? 1 : 0);
shun-iwasawa a5c4f3
    m_param.m_capStyle.setIndex(GeometricCapStyle);
shun-iwasawa a5c4f3
    m_param.m_joinStyle.setIndex(GeometricJoinStyle);
shun-iwasawa a5c4f3
    m_param.m_miterJoinLimit.setValue(GeometricMiterValue);
shun-iwasawa a5c4f3
    m_firstTime = false;
shun-iwasawa a5c4f3
    m_param.m_snap.setValue(GeometricSnap);
shun-iwasawa a5c4f3
    if (m_targetType & TTool::Vectors) {
shun-iwasawa a5c4f3
      m_param.m_snapSensitivity.setIndex(GeometricSnapSensitivity);
Jeremy Bullock 977232
      switch (GeometricSnapSensitivity) {
Jeremy Bullock 977232
      case 0:
Jeremy Bullock 977232
        m_param.m_minDistance2 = SNAPPING_LOW;
Jeremy Bullock 977232
        break;
Jeremy Bullock 977232
      case 1:
Jeremy Bullock 977232
        m_param.m_minDistance2 = SNAPPING_MEDIUM;
Jeremy Bullock 977232
        break;
Jeremy Bullock 977232
      case 2:
Jeremy Bullock 977232
        m_param.m_minDistance2 = SNAPPING_HIGH;
Jeremy Bullock 977232
        break;
Jeremy Bullock 977232
      }
Jeremy Bullock 977232
    }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
    if (m_param.m_targetType & TTool::ToonzImage ||
shun-iwasawa a5c4f3
        m_param.m_targetType & TTool::RasterImage)
shun-iwasawa a5c4f3
      m_notifier = new FullColorGeometricToolNotifier(this);
Shinya Kitaoka 120a6e
  }
shun-iwasawa a5c4f3
  m_primitive->resetSnap();
shun-iwasawa a5c4f3
  /*--
shun-iwasawa a5c4f3
     ショートカットでいきなりスタート(=onEnterを通らない場合)のとき、
shun-iwasawa a5c4f3
          LineToolが反応しないことがある対策 --*/
shun-iwasawa a5c4f3
  m_active =
shun-iwasawa a5c4f3
      (getImage(false) != 0 || Preferences::instance()->isAutoCreateEnabled());
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->onActivate();
shun-iwasawa a5c4f3
  onColorStyleChanged();
shun-iwasawa a5c4f3
}
pojienie 57e1e4
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::onDeactivate() {
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->onDeactivate();
shun-iwasawa a5c4f3
  m_isRotatingOrMoving = false;
shun-iwasawa a5c4f3
  delete m_rotatedStroke;
shun-iwasawa a5c4f3
  m_rotatedStroke = 0;
shun-iwasawa a5c4f3
}
pojienie 57e1e4
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::onEnter() {
shun-iwasawa a5c4f3
  m_active = getImage(false) != 0;
shun-iwasawa a5c4f3
  if (m_active && m_primitive) m_primitive->onEnter();
shun-iwasawa a5c4f3
}
pojienie 57e1e4
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::draw() {
shun-iwasawa a5c4f3
  if (m_isRotatingOrMoving) {
shun-iwasawa a5c4f3
    tglColor(m_color);
shun-iwasawa a5c4f3
    drawStrokeCenterline(*m_rotatedStroke, sqrt(tglGetPixelSize2()));
shun-iwasawa a5c4f3
    return;
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  if (m_primitive) m_primitive->draw();
shun-iwasawa a5c4f3
}
pojienie 1e8e2f
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
int GeometricTool::getCursorId() const {
shun-iwasawa a5c4f3
  if (m_viewer && m_viewer->getGuidedStrokePickerMode())
shun-iwasawa a5c4f3
    return m_viewer->getGuidedStrokePickerCursor();
shun-iwasawa a5c4f3
  return ToolCursor::PenCursor;
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
TPropertyGroup *GeometricTool::getProperties(int idx) {
shun-iwasawa a5c4f3
  return &m_param.m_prop[idx];
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
bool GeometricTool::onPropertyChanged(std::string propertyName) {
shun-iwasawa a5c4f3
  /*---	変更されたPropertyごとに処理を分ける。
shun-iwasawa a5c4f3
          注意:m_toolSizeとm_rasterToolSizeは同じName(="Size:")なので、
shun-iwasawa a5c4f3
          扱っている画像がラスタかどうかで区別する ---*/
shun-iwasawa a5c4f3
  if (propertyName == m_param.m_toolSize.getName()) {
shun-iwasawa a5c4f3
    TImageP img = getImage(false);
shun-iwasawa a5c4f3
    TToonzImageP ri(img); /*-- ラスタかどうかの判定 --*/
shun-iwasawa a5c4f3
    if (ri)
shun-iwasawa a5c4f3
      GeometricRasterSize = m_param.m_rasterToolSize.getValue();
shun-iwasawa a5c4f3
    else
shun-iwasawa a5c4f3
      GeometricSize = m_param.m_toolSize.getValue();
shun-iwasawa a5c4f3
  } else if (propertyName == m_param.m_type.getName()) {
shun-iwasawa a5c4f3
    std::wstring typeCode = m_param.m_type.getValue();
shun-iwasawa a5c4f3
    GeometricType         = ::to_string(typeCode);
shun-iwasawa a5c4f3
    if (typeCode != m_typeCode) {
shun-iwasawa a5c4f3
      m_typeCode = typeCode;
shun-iwasawa a5c4f3
      changeType(typeCode);
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
  } else if (propertyName == m_param.m_edgeCount.getName())
shun-iwasawa a5c4f3
    GeometricEdgeCount = m_param.m_edgeCount.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_rotate.getName())
shun-iwasawa a5c4f3
    GeometricRotate = m_param.m_rotate.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_autogroup.getName()) {
shun-iwasawa a5c4f3
    if (!m_param.m_autogroup.getValue()) {
shun-iwasawa a5c4f3
      m_param.m_autofill.setValue(false);
shun-iwasawa a5c4f3
      // this is ugly: it's needed to refresh the GUI of the toolbar after
shun-iwasawa a5c4f3
      // having set to false the autofill...
shun-iwasawa a5c4f3
      TTool::getApplication()->getCurrentTool()->setTool(
shun-iwasawa a5c4f3
          "");  // necessary, otherwise next setTool is ignored...
shun-iwasawa a5c4f3
      TTool::getApplication()->getCurrentTool()->setTool(
shun-iwasawa a5c4f3
          QString::fromStdString(getName()));
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
    GeometricGroupIt = m_param.m_autogroup.getValue();
shun-iwasawa a5c4f3
  } else if (propertyName == m_param.m_autofill.getName()) {
shun-iwasawa a5c4f3
    if (m_param.m_autofill.getValue()) {
shun-iwasawa a5c4f3
      m_param.m_autogroup.setValue(true);
shun-iwasawa a5c4f3
      // this is ugly: it's needed to refresh the GUI of the toolbar after
shun-iwasawa a5c4f3
      // having set to false the autofill...
shun-iwasawa a5c4f3
      TTool::getApplication()->getCurrentTool()->setTool(
shun-iwasawa a5c4f3
          "");  // necessary, otherwise next setTool is ignored...
shun-iwasawa a5c4f3
      TTool::getApplication()->getCurrentTool()->setTool(
shun-iwasawa a5c4f3
          QString::fromStdString(getName()));
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
    GeometricGroupIt = m_param.m_autofill.getValue();
shun-iwasawa a5c4f3
  } else if (propertyName == m_param.m_smooth.getName()) {
shun-iwasawa a5c4f3
    GeometricSmooth = m_param.m_smooth.getValue();
shun-iwasawa a5c4f3
  } else if (propertyName == m_param.m_selective.getName())
shun-iwasawa a5c4f3
    GeometricSelective = m_param.m_selective.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_pencil.getName())
shun-iwasawa a5c4f3
    GeometricPencil = m_param.m_pencil.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_hardness.getName())
shun-iwasawa a5c4f3
    GeometricBrushHardness = m_param.m_hardness.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_opacity.getName())
shun-iwasawa a5c4f3
    GeometricOpacity = m_param.m_opacity.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_capStyle.getName())
shun-iwasawa a5c4f3
    GeometricCapStyle = m_param.m_capStyle.getIndex();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_joinStyle.getName())
shun-iwasawa a5c4f3
    GeometricJoinStyle = m_param.m_joinStyle.getIndex();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_miterJoinLimit.getName())
shun-iwasawa a5c4f3
    GeometricMiterValue = m_param.m_miterJoinLimit.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_snap.getName())
shun-iwasawa a5c4f3
    GeometricSnap = m_param.m_snap.getValue();
shun-iwasawa a5c4f3
  else if (propertyName == m_param.m_snapSensitivity.getName()) {
shun-iwasawa a5c4f3
    GeometricSnapSensitivity = m_param.m_snapSensitivity.getIndex();
shun-iwasawa a5c4f3
    switch (GeometricSnapSensitivity) {
shun-iwasawa a5c4f3
    case 0:
shun-iwasawa a5c4f3
      m_param.m_minDistance2 = SNAPPING_LOW;
shun-iwasawa a5c4f3
      break;
shun-iwasawa a5c4f3
    case 1:
shun-iwasawa a5c4f3
      m_param.m_minDistance2 = SNAPPING_MEDIUM;
shun-iwasawa a5c4f3
      break;
shun-iwasawa a5c4f3
    case 2:
shun-iwasawa a5c4f3
      m_param.m_minDistance2 = SNAPPING_HIGH;
shun-iwasawa a5c4f3
      break;
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
  }
pojienie 1e8e2f
shun-iwasawa a5c4f3
  return false;
shun-iwasawa a5c4f3
}
pojienie 1e8e2f
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::addRasterMyPaintStroke(const TToonzImageP &ti,
shun-iwasawa a5c4f3
                                           TStroke *stroke, TXshSimpleLevel *sl,
shun-iwasawa a5c4f3
                                           const TFrameId &id) {
shun-iwasawa a5c4f3
  TRasterP ras = ti->getRaster();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
shun-iwasawa a5c4f3
  m_tileSaverCM         = new TTileSaverCM32(ras, tileSet);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TPointD rasCenter = ras->getCenterD();
shun-iwasawa a5c4f3
  stroke->transform(TTranslation(rasCenter.x, rasCenter.y));
shun-iwasawa a5c4f3
  TDimension dim = ras->getSize();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  mypaint::Brush mypaintBrush;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  double modifierSize    = m_param.m_modifierSize.getValue() * log(2.0);
shun-iwasawa a5c4f3
  double modifierOpacity = 0.01 * m_param.m_modifierOpacity.getValue();
shun-iwasawa a5c4f3
  TPixelD color          = PixelConverter<tpixeld>::from(</tpixeld>
shun-iwasawa a5c4f3
      getApplication()->getCurrentLevelStyle()->getMainColor());
shun-iwasawa a5c4f3
  double colorH = 0.0;
shun-iwasawa a5c4f3
  double colorS = 0.0;
shun-iwasawa a5c4f3
  double colorV = 0.0;
shun-iwasawa a5c4f3
  RGB2HSV(color.r, color.g, color.b, &colorH, &colorS, &colorV);
shun-iwasawa a5c4f3
  TMyPaintBrushStyle *mypaintStyle = dynamic_cast<tmypaintbrushstyle *="">(</tmypaintbrushstyle>
shun-iwasawa a5c4f3
      getApplication()->getCurrentLevelStyle());
shun-iwasawa a5c4f3
  mypaintBrush.fromBrush(mypaintStyle->getBrush());
shun-iwasawa a5c4f3
  float baseSize =
shun-iwasawa a5c4f3
      mypaintBrush.getBaseValue(MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC,
shun-iwasawa a5c4f3
                            baseSize + modifierSize);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_COLOR_H, colorH / 360.0);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_COLOR_S, colorS);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_COLOR_V, colorV);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_workRaster = TRaster32P(dim);
shun-iwasawa a5c4f3
  m_workRaster->lock();
shun-iwasawa a5c4f3
  MyPaintToonzBrush toonz_brush(m_workRaster, *this, mypaintBrush);
shun-iwasawa a5c4f3
  m_lastRect.empty();
shun-iwasawa a5c4f3
  m_strokeRect.empty();
shun-iwasawa a5c4f3
  toonz_brush.beginStroke();
shun-iwasawa a5c4f3
  const TThickQuadratic *q = 0;
shun-iwasawa a5c4f3
  for (int i = 0; i < stroke->getChunkCount(); i++) {
shun-iwasawa a5c4f3
    q           = stroke->getChunk(i);
shun-iwasawa a5c4f3
    double step = computeStep(*q, getPixelSize());
shun-iwasawa a5c4f3
    for (double t = 0; t < 1; t += step)
8967c8
      toonz_brush.strokeTo(q->getPoint(t), 0.5, TPointD(), 1.0);
8967c8
    toonz_brush.strokeTo(q->getP2(), 0.5, TPointD(), 1.0);
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  toonz_brush.endStroke();
shun-iwasawa a5c4f3
  if (!m_strokeRect.isEmpty()) {
shun-iwasawa a5c4f3
    TRasterCM32P bkupRas(dim);
shun-iwasawa a5c4f3
    bkupRas->extract(m_strokeRect)->copy(ras->extract(m_strokeRect));
shun-iwasawa a5c4f3
    toonz_brush.updateDrawing(ras, bkupRas, m_strokeRect, stroke->getStyle(),
shun-iwasawa a5c4f3
                              false);
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_workRaster->unlock();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  delete m_tileSaverCM;
shun-iwasawa a5c4f3
  m_tileSaverCM       = nullptr;
shun-iwasawa a5c4f3
  TRasterCM32P subras = ras->extract(m_strokeRect)->clone();
shun-iwasawa a5c4f3
  TUndoManager::manager()->add(new CMappedMyPaintGeometryUndo(
shun-iwasawa a5c4f3
      tileSet, sl, id, m_isFrameCreated, m_isLevelCreated, subras,
shun-iwasawa a5c4f3
      m_strokeRect.getP00()));
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::addFullColorMyPaintStroke(const TRasterImageP &ri,
shun-iwasawa a5c4f3
                                              TStroke *stroke,
shun-iwasawa a5c4f3
                                              TXshSimpleLevel *sl,
shun-iwasawa a5c4f3
                                              const TFrameId &id) {
shun-iwasawa a5c4f3
  TRasterP ras = ri->getRaster();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TTileSetFullColor *tileSet = new TTileSetFullColor(ras->getSize());
shun-iwasawa a5c4f3
  m_tileSaver                = new TTileSaverFullColor(ras, tileSet);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TPointD rasCenter = ras->getCenterD();
shun-iwasawa a5c4f3
  stroke->transform(TTranslation(rasCenter.x, rasCenter.y));
shun-iwasawa a5c4f3
  TDimension dim = ras->getSize();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  mypaint::Brush mypaintBrush;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  double modifierSize    = m_param.m_modifierSize.getValue() * log(2.0);
shun-iwasawa a5c4f3
  double modifierOpacity = 0.01 * m_param.m_modifierOpacity.getValue();
shun-iwasawa a5c4f3
  TPixelD color          = PixelConverter<tpixeld>::from(</tpixeld>
shun-iwasawa a5c4f3
      getApplication()->getCurrentLevelStyle()->getMainColor());
shun-iwasawa a5c4f3
  double colorH = 0.0;
shun-iwasawa a5c4f3
  double colorS = 0.0;
shun-iwasawa a5c4f3
  double colorV = 0.0;
shun-iwasawa a5c4f3
  RGB2HSV(color.r, color.g, color.b, &colorH, &colorS, &colorV);
shun-iwasawa a5c4f3
  TMyPaintBrushStyle *mypaintStyle = dynamic_cast<tmypaintbrushstyle *="">(</tmypaintbrushstyle>
shun-iwasawa a5c4f3
      getApplication()->getCurrentLevelStyle());
shun-iwasawa a5c4f3
  mypaintBrush.fromBrush(mypaintStyle->getBrush());
shun-iwasawa a5c4f3
  float baseSize =
shun-iwasawa a5c4f3
      mypaintBrush.getBaseValue(MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC);
shun-iwasawa a5c4f3
  float baseOpacity = mypaintBrush.getBaseValue(MYPAINT_BRUSH_SETTING_OPAQUE);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC,
shun-iwasawa a5c4f3
                            baseSize + modifierSize);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_OPAQUE,
shun-iwasawa a5c4f3
                            baseOpacity * modifierOpacity);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_COLOR_H, colorH / 360.0);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_COLOR_S, colorS);
shun-iwasawa a5c4f3
  mypaintBrush.setBaseValue(MYPAINT_BRUSH_SETTING_COLOR_V, colorV);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_workRaster = TRaster32P(dim);
shun-iwasawa a5c4f3
  m_workRaster->lock();
shun-iwasawa a5c4f3
  MyPaintToonzBrush toonz_brush(m_workRaster, *this, mypaintBrush);
shun-iwasawa a5c4f3
  m_lastRect.empty();
shun-iwasawa a5c4f3
  m_strokeRect.empty();
shun-iwasawa a5c4f3
  toonz_brush.beginStroke();
shun-iwasawa a5c4f3
  const TThickQuadratic *q = 0;
shun-iwasawa a5c4f3
  for (int i = 0; i < stroke->getChunkCount(); i++) {
shun-iwasawa a5c4f3
    q           = stroke->getChunk(i);
shun-iwasawa a5c4f3
    double step = computeStep(*q, getPixelSize());
shun-iwasawa a5c4f3
    for (double t = 0; t < 1; t += step)
8967c8
      toonz_brush.strokeTo(q->getPoint(t), 0.5, TPointD(), 1.0);
8967c8
    toonz_brush.strokeTo(q->getP2(), 0.5, TPointD(), 1.0);
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  toonz_brush.endStroke();
shun-iwasawa a5c4f3
  if (!m_strokeRect.isEmpty())
shun-iwasawa a5c4f3
    ras->extract(m_strokeRect)->copy(m_workRaster->extract(m_strokeRect));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_workRaster->unlock();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  delete m_tileSaver;
shun-iwasawa a5c4f3
  m_tileSaver     = nullptr;
shun-iwasawa a5c4f3
  TRasterP subras = ras->extract(m_strokeRect)->clone();
shun-iwasawa a5c4f3
  TUndoManager::manager()->add(new FullColorMyPaintGeometryUndo(
shun-iwasawa a5c4f3
      tileSet, sl, id, m_isFrameCreated, subras, m_strokeRect.getP00()));
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
void GeometricTool::addStroke() {
shun-iwasawa a5c4f3
  if (!m_primitive) return;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TStroke *stroke = 0;
shun-iwasawa a5c4f3
  if (!m_isRotatingOrMoving) {
shun-iwasawa a5c4f3
    stroke = m_primitive->makeStroke();
shun-iwasawa a5c4f3
    if (!stroke) return;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    if (m_param.m_rotate.getValue()) {
shun-iwasawa a5c4f3
      m_isRotatingOrMoving = true;
shun-iwasawa a5c4f3
      m_rotatedStroke      = stroke;
shun-iwasawa a5c4f3
      TRectD bbox          = stroke->getBBox();
shun-iwasawa a5c4f3
      m_rotateCenter       = 0.5 * (bbox.getP11() + bbox.getP00());
shun-iwasawa a5c4f3
      m_originalCursorPos  = m_currentCursorPos;
shun-iwasawa a5c4f3
      m_lastRotateAngle    = 0;
shun-iwasawa a5c4f3
      m_lastMoveStrokePos  = TPointD(0, 0);
shun-iwasawa a5c4f3
      m_wasCtrlPressed     = false;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      const TTool::Application *app = TTool::getApplication();
shun-iwasawa a5c4f3
      if (!app) {
shun-iwasawa a5c4f3
        m_color = TPixel32::Red;
shun-iwasawa a5c4f3
        return;
shun-iwasawa a5c4f3
      }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      const TColorStyle *style = app->getCurrentLevelStyle();
shun-iwasawa a5c4f3
      if (!style) {
shun-iwasawa a5c4f3
        m_color = TPixel32::Red;
pojienie 57e1e4
        return;
pojienie 57e1e4
      }
Shinya Kitaoka 120a6e
shun-iwasawa a5c4f3
      m_color = style->getAverageColor();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      return;
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
  } else {
shun-iwasawa a5c4f3
    stroke               = m_rotatedStroke;
shun-iwasawa a5c4f3
    m_isRotatingOrMoving = false;
shun-iwasawa a5c4f3
    m_rotatedStroke      = 0;
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TStroke::OutlineOptions &options = stroke->outlineOptions();
shun-iwasawa a5c4f3
  options.m_capStyle               = m_param.m_capStyle.getIndex();
shun-iwasawa a5c4f3
  options.m_joinStyle              = m_param.m_joinStyle.getIndex();
shun-iwasawa a5c4f3
  options.m_miterUpper             = m_param.m_miterJoinLimit.getValue();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TImage *image = getImage(true);
shun-iwasawa a5c4f3
  TToonzImageP ti(image);
shun-iwasawa a5c4f3
  TVectorImageP vi(image);
shun-iwasawa a5c4f3
  TRasterImageP ri(image);
shun-iwasawa a5c4f3
  TXshSimpleLevel *sl =
shun-iwasawa a5c4f3
      TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
shun-iwasawa a5c4f3
  TFrameId id = getCurrentFid();
shun-iwasawa a5c4f3
  /*-- ToonzImageの場合 --*/
shun-iwasawa a5c4f3
  if (ti) {
shun-iwasawa a5c4f3
    int styleId    = TTool::getApplication()->getCurrentLevelStyleIndex();
shun-iwasawa a5c4f3
    bool selective = m_param.m_selective.getValue();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    bool filled = false;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    stroke->setStyle(styleId);
shun-iwasawa a5c4f3
    // mypaint brush case
shun-iwasawa a5c4f3
    if (getApplication()->getCurrentLevelStyle()->getTagId() == 4001) {
shun-iwasawa a5c4f3
      addRasterMyPaintStroke(ti, stroke, sl, id);
shun-iwasawa a5c4f3
    } else {
Shinya Kitaoka 120a6e
      double hardness = m_param.m_hardness.getValue() * 0.01;
Shinya Kitaoka 120a6e
      TRect savebox;
Shinya Kitaoka 120a6e
      if (hardness == 1 || m_param.m_pencil.getValue()) {
Shinya Kitaoka 120a6e
        TUndoManager::manager()->add(new UndoRasterPencil(
Shinya Kitaoka 120a6e
            sl, id, stroke, selective, filled, !m_param.m_pencil.getValue(),
Shinya Kitaoka 120a6e
            m_isFrameCreated, m_isLevelCreated, m_primitive->getName()));
Shinya Kitaoka 120a6e
        savebox = ToonzImageUtils::addInkStroke(ti, stroke, styleId, selective,
Shinya Kitaoka 120a6e
                                                filled, TConsts::infiniteRectD,
Shinya Kitaoka 120a6e
                                                !m_param.m_pencil.getValue());
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        int thickness = m_param.m_rasterToolSize.getValue();
Shinya Kitaoka 120a6e
        TUndoManager::manager()->add(new CMBluredPrimitiveUndo(
Shinya Kitaoka 120a6e
            sl, id, stroke, thickness, hardness, selective, false,
Shinya Kitaoka 120a6e
            m_isFrameCreated, m_isLevelCreated, m_primitive->getName()));
Shinya Kitaoka 120a6e
        savebox = drawBluredBrush(ti, stroke, thickness, hardness, selective);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa a5c4f3
    ToolUtils::updateSaveBox();
shun-iwasawa a5c4f3
    delete stroke;
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  /*-- VectorImageの場合 --*/
shun-iwasawa a5c4f3
  else if (vi) {
shun-iwasawa a5c4f3
    if (TTool::getApplication()->getCurrentObject()->isSpline()) {
shun-iwasawa a5c4f3
      if (!ToolUtils::isJustCreatedSpline(vi.getPointer())) {
shun-iwasawa a5c4f3
        m_primitive->setIsPrompting(true);
shun-iwasawa a5c4f3
        QString question("Are you sure you want to replace the motion path?");
shun-iwasawa a5c4f3
        int ret =
shun-iwasawa a5c4f3
            DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0);
shun-iwasawa a5c4f3
        m_primitive->setIsPrompting(false);
shun-iwasawa a5c4f3
        if (ret == 2 || ret == 0) return;
Shinya Kitaoka 120a6e
      }
shun-iwasawa a5c4f3
      QMutexLocker lock(vi->getMutex());
shun-iwasawa a5c4f3
      TUndo *undo =
shun-iwasawa a5c4f3
          new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
shun-iwasawa a5c4f3
      while (vi->getStrokeCount() > 0) vi->deleteStroke(0);
shun-iwasawa a5c4f3
      vi->addStroke(stroke, false);
shun-iwasawa a5c4f3
      TUndoManager::manager()->add(undo);
shun-iwasawa a5c4f3
    } else {
shun-iwasawa a5c4f3
      int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
shun-iwasawa a5c4f3
      if (styleId >= 0) stroke->setStyle(styleId);
shun-iwasawa a5c4f3
      QMutexLocker lock(vi->getMutex());
shun-iwasawa a5c4f3
      std::vector<tfilledregioninf> *fillInformation =</tfilledregioninf>
shun-iwasawa a5c4f3
          new std::vector<tfilledregioninf>;</tfilledregioninf>
shun-iwasawa a5c4f3
      ImageUtils::getFillingInformationOverlappingArea(vi, *fillInformation,
shun-iwasawa a5c4f3
                                                       stroke->getBBox());
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      vi->addStroke(stroke);
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      TUndoManager::manager()->add(new UndoPencil(
shun-iwasawa a5c4f3
          vi->getStroke(vi->getStrokeCount() - 1), fillInformation, sl, id,
shun-iwasawa a5c4f3
          m_isFrameCreated, m_isLevelCreated, m_param.m_autogroup.getValue(),
shun-iwasawa a5c4f3
          m_param.m_autofill.getValue()));
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
      if ((Preferences::instance()->getGuidedDrawingType() == 1 ||
shun-iwasawa a5c4f3
           Preferences::instance()->getGuidedDrawingType() == 2) &&
shun-iwasawa a5c4f3
          Preferences::instance()->getGuidedAutoInbetween()) {
shun-iwasawa a5c4f3
        TTool *tool =
shun-iwasawa a5c4f3
            TTool::getTool(T_Brush, TTool::ToolTargetType::VectorImage);
shun-iwasawa a5c4f3
        ToonzVectorBrushTool *vbTool = (ToonzVectorBrushTool *)tool;
shun-iwasawa a5c4f3
        if (vbTool) {
shun-iwasawa a5c4f3
          vbTool->setViewer(m_viewer);
shun-iwasawa a5c4f3
          vbTool->doGuidedAutoInbetween(id, vi, stroke, false,
shun-iwasawa a5c4f3
                                        m_param.m_autogroup.getValue(),
shun-iwasawa a5c4f3
                                        m_param.m_autofill.getValue(), false);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa a5c4f3
    if (m_param.m_autogroup.getValue() && stroke->isSelfLoop()) {
shun-iwasawa a5c4f3
      int index = vi->getStrokeCount() - 1;
shun-iwasawa a5c4f3
      vi->group(index, 1);
shun-iwasawa a5c4f3
      if (m_param.m_autofill.getValue()) {
shun-iwasawa a5c4f3
        // to avoid filling other strokes, I enter into the new stroke group
shun-iwasawa a5c4f3
        int currentGroup = vi->exitGroup();
shun-iwasawa a5c4f3
        vi->enterGroup(index);
shun-iwasawa a5c4f3
        vi->selectFill(stroke->getBBox().enlarge(1, 1), 0, stroke->getStyle(),
shun-iwasawa a5c4f3
                       false, true, false);
shun-iwasawa a5c4f3
        if (currentGroup != -1)
shun-iwasawa a5c4f3
          vi->enterGroup(currentGroup);
shun-iwasawa a5c4f3
        else
shun-iwasawa a5c4f3
          vi->exitGroup();
shun-iwasawa a5c4f3
      }
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
  /*-- RasterImageの場合 --*/
shun-iwasawa a5c4f3
  else if (ri) {
shun-iwasawa a5c4f3
    int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
shun-iwasawa a5c4f3
    stroke->setStyle(styleId);
shun-iwasawa a5c4f3
    // mypaint brush case
shun-iwasawa a5c4f3
    if (getApplication()->getCurrentLevelStyle()->getTagId() == 4001) {
shun-iwasawa a5c4f3
      addFullColorMyPaintStroke(ri, stroke, sl, id);
shun-iwasawa a5c4f3
    } else {
Shinya Kitaoka 120a6e
      double opacity  = m_param.m_opacity.getValue() * 0.01;
Shinya Kitaoka 120a6e
      double hardness = m_param.m_hardness.getValue() * 0.01;
Shinya Kitaoka 120a6e
      TRect savebox;
Shinya Kitaoka 120a6e
      if (hardness == 1) {
Shinya Kitaoka 120a6e
        TUndoManager::manager()->add(new UndoFullColorPencil(
Shinya Kitaoka 120a6e
            sl, id, stroke, opacity, true, m_isFrameCreated, m_isLevelCreated));
Shinya Kitaoka 120a6e
        savebox = TRasterImageUtils::addStroke(ri, stroke, TRectD(), opacity);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        int thickness = m_param.m_rasterToolSize.getValue();
Shinya Kitaoka 120a6e
        TUndoManager::manager()->add(new FullColorBluredPrimitiveUndo(
Shinya Kitaoka 120a6e
            sl, id, stroke, thickness, hardness, opacity, true,
Shinya Kitaoka 120a6e
            m_isFrameCreated, m_isLevelCreated));
Shinya Kitaoka 120a6e
        savebox = drawBluredBrush(ri, stroke, thickness, hardness, opacity);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa a5c4f3
    ToolUtils::updateSaveBox();
shun-iwasawa a5c4f3
    delete stroke;
Shinya Kitaoka 120a6e
  }
shun-iwasawa a5c4f3
  notifyImageChanged();
shun-iwasawa a5c4f3
  m_active = false;
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
void GeometricTool::updateWorkRaster(const TRect &rect) {
shun-iwasawa a5c4f3
  if (rect.isEmpty()) return;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TRasterImageP ri = TImageP(getImage(false, 1));
shun-iwasawa a5c4f3
  if (!ri) return;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  TRasterP ras = ri->getRaster();
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  const int denominator = 8;
shun-iwasawa a5c4f3
  TRect enlargedRect    = rect + m_lastRect;
shun-iwasawa a5c4f3
  int dx                = (enlargedRect.getLx() - 1) / denominator + 1;
shun-iwasawa a5c4f3
  int dy                = (enlargedRect.getLy() - 1) / denominator + 1;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  if (m_lastRect.isEmpty()) {
shun-iwasawa a5c4f3
    enlargedRect.x0 -= dx;
shun-iwasawa a5c4f3
    enlargedRect.y0 -= dy;
shun-iwasawa a5c4f3
    enlargedRect.x1 += dx;
shun-iwasawa a5c4f3
    enlargedRect.y1 += dy;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TRect _rect = enlargedRect * ras->getBounds();
shun-iwasawa a5c4f3
    if (_rect.isEmpty()) return;
Toshihiro Shimizu 890ddd
shun-iwasawa a5c4f3
    m_workRaster->extract(_rect)->copy(ras->extract(_rect));
shun-iwasawa a5c4f3
  } else {
shun-iwasawa a5c4f3
    if (enlargedRect.x0 < m_lastRect.x0) enlargedRect.x0 -= dx;
shun-iwasawa a5c4f3
    if (enlargedRect.y0 < m_lastRect.y0) enlargedRect.y0 -= dy;
shun-iwasawa a5c4f3
    if (enlargedRect.x1 > m_lastRect.x1) enlargedRect.x1 += dx;
shun-iwasawa a5c4f3
    if (enlargedRect.y1 > m_lastRect.y1) enlargedRect.y1 += dy;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TRect _rect = enlargedRect * ras->getBounds();
shun-iwasawa a5c4f3
    if (_rect.isEmpty()) return;
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
    TRect _lastRect    = m_lastRect * ras->getBounds();
shun-iwasawa a5c4f3
    QList<trect> rects = ToolUtils::splitRect(_rect, _lastRect);</trect>
shun-iwasawa a5c4f3
    for (int i = 0; i < rects.size(); i++) {
shun-iwasawa a5c4f3
      m_workRaster->extract(rects[i])->copy(ras->extract(rects[i]));
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
  }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
  m_lastRect = enlargedRect;
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
bool GeometricTool::askRead(const TRect &rect) { return askWrite(rect); }
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//--------------------------------------------------------------------------------------------------
shun-iwasawa a5c4f3
bool GeometricTool::askWrite(const TRect &rect) {
shun-iwasawa a5c4f3
  if (rect.isEmpty()) return true;
shun-iwasawa a5c4f3
  m_strokeRect += rect;
shun-iwasawa a5c4f3
  updateWorkRaster(rect);
shun-iwasawa a5c4f3
  if (m_tileSaver) m_tileSaver->save(rect);
shun-iwasawa a5c4f3
  if (m_tileSaverCM) m_tileSaverCM->save(rect);
shun-iwasawa a5c4f3
  return true;
shun-iwasawa a5c4f3
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//====================================================================================================
Toshihiro Shimizu 890ddd
GeometricTool GeometricVectorTool(TTool::Vectors | TTool::EmptyTarget);
Toshihiro Shimizu 890ddd
GeometricTool GeometricRasterTool(TTool::ToonzImage | TTool::EmptyTarget);
Shinya Kitaoka 120a6e
GeometricTool GeometricRasterFullColorTool(TTool::RasterImage |
Shinya Kitaoka 120a6e
                                           TTool::EmptyTarget);
Toshihiro Shimizu 890ddd
shun-iwasawa a5c4f3
//====================================================================================================
shun-iwasawa a5c4f3
//
Jeremy Bullock 977232
//-------------------------------------------------------------------------------------------------------------
Jeremy Bullock 977232
Jeremy Bullock 977232
void Primitive::drawSnap() {
Jeremy Bullock 977232
  // snapping
Jeremy Bullock 977232
  if ((m_param->m_targetType & TTool::Vectors) && m_param->m_snap.getValue()) {
Jeremy Bullock 977232
    m_param->m_pixelSize = m_tool->getPixelSize();
Jeremy Bullock 977232
    double thick         = 6.0 * m_param->m_pixelSize;
Jeremy Bullock 977232
    if (m_param->m_foundSnap) {
Jeremy Bullock 977232
      tglColor(TPixelD(0.1, 0.9, 0.1));
Jeremy Bullock 977232
      tglDrawCircle(m_param->m_snapPoint, thick);
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
  }
Jeremy Bullock 977232
}
Jeremy Bullock 977232
Jeremy Bullock 977232
//-------------------------------------------------------------------------------------------------------------
Jeremy Bullock 977232
Jeremy Bullock 977232
TPointD Primitive::checkGuideSnapping(TPointD pos) {
Jeremy Bullock 977232
  if (Preferences::instance()->getVectorSnappingTarget() == 0) {
Jeremy Bullock 977232
    if (m_param->m_foundSnap)
Jeremy Bullock 977232
      return m_param->m_snapPoint;
Jeremy Bullock 977232
    else
Jeremy Bullock 977232
      return pos;
Jeremy Bullock 977232
  }
Jeremy Bullock 977232
  if ((m_param->m_targetType & TTool::Vectors) && m_param->m_snap.getValue()) {
Jeremy Bullock 977232
    int vGuideCount = 0, hGuideCount = 0;
Jeremy Bullock 977232
    double guideDistance  = sqrt(m_param->m_minDistance2);
1c557b
    TToolViewer *viewer = m_tool->getViewer();
Jeremy Bullock 977232
    if (viewer) {
Jeremy Bullock 977232
      vGuideCount = viewer->getVGuideCount();
Jeremy Bullock 977232
      hGuideCount = viewer->getHGuideCount();
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
    double distanceToVGuide = -1.0, distanceToHGuide = -1.0;
Jeremy Bullock 977232
    double vGuide, hGuide;
Jeremy Bullock 977232
    bool useGuides = false;
Jeremy Bullock 977232
    if (vGuideCount) {
Jeremy Bullock 977232
      for (int j = 0; j < vGuideCount; j++) {
Jeremy Bullock 977232
        double guide        = viewer->getVGuide(j);
Rozhuk Ivan 823a31
        double tempDistance = std::abs(guide - pos.y);
Jeremy Bullock 977232
        if (tempDistance < guideDistance &&
Jeremy Bullock 977232
            (distanceToVGuide < 0 || tempDistance < distanceToVGuide)) {
Jeremy Bullock 977232
          distanceToVGuide = tempDistance;
Jeremy Bullock 977232
          vGuide           = guide;
Jeremy Bullock 977232
          useGuides        = true;
Jeremy Bullock 977232
        }
Jeremy Bullock 977232
      }
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
    if (hGuideCount) {
Jeremy Bullock 977232
      for (int j = 0; j < hGuideCount; j++) {
Jeremy Bullock 977232
        double guide        = viewer->getHGuide(j);
Rozhuk Ivan 823a31
        double tempDistance = std::abs(guide - pos.x);
Jeremy Bullock 977232
        if (tempDistance < guideDistance &&
Jeremy Bullock 977232
            (distanceToHGuide < 0 || tempDistance < distanceToHGuide)) {
Jeremy Bullock 977232
          distanceToHGuide = tempDistance;
Jeremy Bullock 977232
          hGuide           = guide;
Jeremy Bullock 977232
          useGuides        = true;
Jeremy Bullock 977232
        }
Jeremy Bullock 977232
      }
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
    if (useGuides && m_param->m_foundSnap) {
Rozhuk Ivan 823a31
      double currYDistance = std::abs(m_param->m_snapPoint.y - pos.y);
Rozhuk Ivan 823a31
      double currXDistance = std::abs(m_param->m_snapPoint.x - pos.x);
Jeremy Bullock 977232
      double hypotenuse =
Jeremy Bullock 977232
          sqrt(pow(currYDistance, 2.0) + pow(currXDistance, 2.0));
Jeremy Bullock 977232
      if ((distanceToVGuide >= 0 && distanceToVGuide < hypotenuse) ||
Jeremy Bullock 977232
          (distanceToHGuide >= 0 && distanceToHGuide < hypotenuse))
Jeremy Bullock 977232
        useGuides = true;
Jeremy Bullock 977232
      else
Jeremy Bullock 977232
        useGuides = false;
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
    if (useGuides) {
Jeremy Bullock 977232
      assert(distanceToHGuide >= 0 || distanceToVGuide >= 0);
Jeremy Bullock 977232
      if (distanceToHGuide < 0 ||
Jeremy Bullock 977232
          (distanceToVGuide <= distanceToHGuide && distanceToVGuide >= 0)) {
Jeremy Bullock 977232
        m_param->m_snapPoint.y = vGuide;
Jeremy Bullock 977232
        m_param->m_snapPoint.x = pos.x;
Jeremy Bullock 977232
Jeremy Bullock 977232
      } else {
Jeremy Bullock 977232
        m_param->m_snapPoint.y = pos.y;
Jeremy Bullock 977232
        m_param->m_snapPoint.x = hGuide;
Jeremy Bullock 977232
      }
Jeremy Bullock 977232
      m_param->m_foundSnap = true;
Jeremy Bullock 977232
    }
Jeremy Bullock 977232
    if (m_param->m_foundSnap)
Jeremy Bullock 977232
      return m_param->m_snapPoint;
Jeremy Bullock 977232
    else
Jeremy Bullock 977232
      return pos;
Jeremy Bullock 977232
  } else
Jeremy Bullock 977232
    return pos;
Jeremy Bullock 977232
}
Jeremy Bullock 977232
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Rectangle Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RectanglePrimitive::draw() {
Jeremy Bullock 977232
  drawSnap();
Shinya Kitaoka 120a6e
  if (m_isEditing || m_isPrompting ||
Shinya Kitaoka 120a6e
      areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Shinya Kitaoka 120a6e
      areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1)) {
Shinya Kitaoka 120a6e
    tglColor(m_isEditing ? m_color : TPixel32::Green);
Shinya Kitaoka 120a6e
    glBegin(GL_LINE_LOOP);
Shinya Kitaoka 120a6e
    tglVertex(m_selectingRect.getP00());
Shinya Kitaoka 120a6e
    tglVertex(m_selectingRect.getP01());
Shinya Kitaoka 120a6e
    tglVertex(m_selectingRect.getP11());
Shinya Kitaoka 120a6e
    tglVertex(m_selectingRect.getP10());
Shinya Kitaoka 120a6e
    glEnd();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RectanglePrimitive::leftButtonDown(const TPointD &pos,
Shinya Kitaoka 120a6e
                                        const TMouseEvent &) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_color     = TPixel32::Red;
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // app->getCurrentTool()->getTool()->touchImage();
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
Shinya Kitaoka 120a6e
    m_isEditing              = style != 0 && style->isStrokeStyle();
Shinya Kitaoka 120a6e
    m_color = (style) ? style->getAverageColor() : TPixel32::Black;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Jeremy Bullock 977232
  TPointD newPos = getSnap(pos);
Shinya Kitaoka 120a6e
  if (m_param->m_pencil.getValue() &&
Shinya Kitaoka 120a6e
      (m_param->m_targetType & TTool::ToonzImage ||
Shinya Kitaoka 120a6e
       m_param->m_targetType & TTool::RasterImage)) {
Shinya Kitaoka 120a6e
    if (m_param->m_rasterToolSize.getValue() % 2 != 0)
Shinya Kitaoka 120a6e
      m_startPoint = TPointD((int)pos.x, (int)pos.y);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_startPoint = TPointD((int)pos.x + 0.5, (int)pos.y + 0.5);
Shinya Kitaoka 120a6e
  } else
shun-iwasawa 036853
    m_startPoint = newPos;
Shinya Kitaoka 120a6e
  m_selectingRect.x0 = m_startPoint.x;
Shinya Kitaoka 120a6e
  m_selectingRect.y0 = m_startPoint.y;
Shinya Kitaoka 120a6e
  m_selectingRect.x1 = m_startPoint.x;
Shinya Kitaoka 120a6e
  m_selectingRect.y1 = m_startPoint.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RectanglePrimitive::leftButtonDrag(const TPointD &realPos,
Shinya Kitaoka 120a6e
                                        const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD pos;
Shinya Kitaoka 120a6e
  if (e.isShiftPressed()) {
Shinya Kitaoka 120a6e
    double distance = tdistance(realPos, m_startPoint) * M_SQRT1_2;
Shinya Kitaoka 120a6e
    pos.x           = (realPos.x > m_startPoint.x) ? m_startPoint.x + distance
pojienie 7f72a6
                                                   : m_startPoint.x - distance;
pojienie 7f72a6
    pos.y           = (realPos.y > m_startPoint.y) ? m_startPoint.y + distance
pojienie 7f72a6
                                                   : m_startPoint.y - distance;
Shinya Kitaoka 120a6e
  } else {
Jeremy Bullock 977232
    pos = calculateSnap(realPos);
Jeremy Bullock 977232
    pos = checkGuideSnapping(realPos);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_param->m_pencil.getValue() &&
Shinya Kitaoka 120a6e
      (m_param->m_targetType & TTool::ToonzImage ||
Shinya Kitaoka 120a6e
       m_param->m_targetType & TTool::RasterImage)) {
Shinya Kitaoka 120a6e
    if (m_param->m_rasterToolSize.getValue() % 2 != 0)
Shinya Kitaoka 120a6e
      pos = TPointD((int)pos.x, (int)pos.y);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      pos = TPointD((int)pos.x + 0.5, (int)pos.y + 0.5);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_selectingRect.x1 = pos.x;
Shinya Kitaoka 120a6e
  m_selectingRect.y1 = pos.y;
Shinya Kitaoka 120a6e
  if (!e.isAltPressed()) {
Shinya Kitaoka 120a6e
    m_selectingRect.x0 = m_startPoint.x;
Shinya Kitaoka 120a6e
    m_selectingRect.y0 = m_startPoint.y;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_selectingRect.x0 = m_startPoint.x + m_startPoint.x - pos.x;
Shinya Kitaoka 120a6e
    m_selectingRect.y0 = m_startPoint.y + m_startPoint.y - pos.y;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *RectanglePrimitive::makeStroke() const {
Shinya Kitaoka 120a6e
  if (areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Shinya Kitaoka 120a6e
      areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1))
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD selArea;
Shinya Kitaoka 120a6e
  selArea.x0 = std::min(m_selectingRect.x0, m_selectingRect.x1);
Shinya Kitaoka 120a6e
  selArea.y0 = std::min(m_selectingRect.y0, m_selectingRect.y1);
Shinya Kitaoka 120a6e
  selArea.x1 = std::max(m_selectingRect.x0, m_selectingRect.x1);
Shinya Kitaoka 120a6e
  selArea.y1 = std::max(m_selectingRect.y0, m_selectingRect.y1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double thick = getThickness();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *stroke = 0;
Shinya Kitaoka 120a6e
  if (m_param->m_targetType & TTool::Vectors) {
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points(17);</tthickpoint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0] = TThickPoint(selArea.x1, selArea.y1, thick);
Shinya Kitaoka 120a6e
    points[1] = TThickPoint(selArea.x1, selArea.y1, thick) + TPointD(-0.01, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[3] = TThickPoint(selArea.x0, selArea.y1, thick) + TPointD(0.01, 0);
Shinya Kitaoka 120a6e
    points[4] = TThickPoint(selArea.x0, selArea.y1, thick);
Shinya Kitaoka 120a6e
    points[5] = TThickPoint(selArea.x0, selArea.y1, thick) + TPointD(0, -0.01);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[7] = TThickPoint(selArea.x0, selArea.y0, thick) + TPointD(0, 0.01);
Shinya Kitaoka 120a6e
    points[8] = TThickPoint(selArea.x0, selArea.y0, thick);
Shinya Kitaoka 120a6e
    points[9] = TThickPoint(selArea.x0, selArea.y0, thick) + TPointD(0.01, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[11] = TThickPoint(selArea.x1, selArea.y0, thick) + TPointD(-0.01, 0);
Shinya Kitaoka 120a6e
    points[12] = TThickPoint(selArea.x1, selArea.y0, thick);
Shinya Kitaoka 120a6e
    points[13] = TThickPoint(selArea.x1, selArea.y0, thick) + TPointD(0, 0.01);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[15] = points[0] + TPointD(0, -0.01);
Shinya Kitaoka 120a6e
    points[16] = points[0];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[2]  = 0.5 * (points[1] + points[3]);
Shinya Kitaoka 120a6e
    points[6]  = 0.5 * (points[5] + points[7]);
Shinya Kitaoka 120a6e
    points[10] = 0.5 * (points[9] + points[11]);
Shinya Kitaoka 120a6e
    points[14] = 0.5 * (points[13] + points[15]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    stroke = new TStroke(points);
Shinya Kitaoka 120a6e
  } else if (m_param->m_targetType & TTool::ToonzImage ||
Shinya Kitaoka 120a6e
             m_param->m_targetType & TTool::RasterImage) {
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points(9);</tthickpoint>
Shinya Kitaoka 120a6e
    double middleX = (selArea.x0 + selArea.x1) * 0.5;
Shinya Kitaoka 120a6e
    double middleY = (selArea.y0 + selArea.y1) * 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0] = TThickPoint(selArea.x1, selArea.y1, thick);
Shinya Kitaoka 120a6e
    points[1] = TThickPoint(middleX, selArea.y1, thick);
Shinya Kitaoka 120a6e
    points[2] = TThickPoint(selArea.x0, selArea.y1, thick);
Shinya Kitaoka 120a6e
    points[3] = TThickPoint(selArea.x0, middleY, thick);
Shinya Kitaoka 120a6e
    points[4] = TThickPoint(selArea.x0, selArea.y0, thick);
Shinya Kitaoka 120a6e
    points[5] = TThickPoint(middleX, selArea.y0, thick);
Shinya Kitaoka 120a6e
    points[6] = TThickPoint(selArea.x1, selArea.y0, thick);
Shinya Kitaoka 120a6e
    points[7] = TThickPoint(selArea.x1, middleY, thick);
Shinya Kitaoka 120a6e
    points[8] = points[0];
Shinya Kitaoka 120a6e
    stroke    = new TStroke(points);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  stroke->setSelfLoop();
Shinya Kitaoka 120a6e
  return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RectanglePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
  m_isEditing = false;
Shinya Kitaoka 120a6e
  m_tool->addStroke();
Jeremy Bullock 977232
  resetSnap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RectanglePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  TPointD newPos = calculateSnap(pos);
Jeremy Bullock 977232
  newPos         = checkGuideSnapping(pos);
Jeremy Bullock 977232
  m_pos          = newPos;
Jeremy Bullock 977232
  m_tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RectanglePrimitive::onEnter() {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
    m_color = TPixel32::Red;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
shun-iwasawa 036853
    if (style) m_color = style->getAverageColor();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Circle Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CirclePrimitive::draw() {
Jeremy Bullock 977232
  drawSnap();
Shinya Kitaoka 120a6e
  if (m_isEditing || m_isPrompting) {
Shinya Kitaoka 120a6e
    tglColor(m_isEditing ? m_color : TPixel32::Green);
Shinya Kitaoka 120a6e
    tglDrawCircle(m_centre, m_radius);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CirclePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
Jeremy Bullock 977232
  m_pos    = getSnap(pos);
Jeremy Bullock 977232
  m_centre = m_pos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_color     = TPixel32::Red;
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
Shinya Kitaoka 120a6e
    if (style) {
Shinya Kitaoka 120a6e
      m_isEditing = style->isStrokeStyle();
Shinya Kitaoka 120a6e
      m_color     = style->getAverageColor();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      m_isEditing = false;
Shinya Kitaoka 120a6e
      m_color     = TPixel32::Black;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CirclePrimitive::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_pos    = pos;
shun-iwasawa 7f1e30
  m_pos    = calculateSnap(pos);
shun-iwasawa 7f1e30
  m_pos    = checkGuideSnapping(pos);
Jeremy Bullock 977232
  m_radius = tdistance(m_centre, m_pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *CirclePrimitive::makeStroke() const {
Shinya Kitaoka 120a6e
  return makeEllipticStroke(getThickness(), m_centre, m_radius, m_radius);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CirclePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
  m_isEditing = false;
Shinya Kitaoka 120a6e
  if (isAlmostZero(m_radius)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_tool->addStroke();
Shinya Kitaoka 120a6e
  m_radius = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CirclePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  m_pos = calculateSnap(pos);
Jeremy Bullock 977232
  m_pos = checkGuideSnapping(pos);
Jeremy Bullock 977232
  m_tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CirclePrimitive::onEnter() {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
    m_color = TPixel32::Red;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
shun-iwasawa 036853
    if (style) m_color = style->getAverageColor();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MultiLine Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::addVertex(const TPointD &pos) {
Shinya Kitaoka 120a6e
  int count = m_vertex.size();
Shinya Kitaoka 120a6e
  // Inserisco il primo punto
Shinya Kitaoka 120a6e
  if (count == 0) {
Shinya Kitaoka 120a6e
    m_vertex.push_back(pos);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD &vertex = m_vertex[count - 1];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Caso particolare in cui inizio una curva e la chiudo subito cliccando sul
Shinya Kitaoka 120a6e
  // punto di pertenza
Shinya Kitaoka 120a6e
  if (count == 1 && pos == vertex) {
Shinya Kitaoka 120a6e
    m_vertex.push_back(pos);
Shinya Kitaoka 120a6e
    m_vertex.push_back(pos);
Shinya Kitaoka 120a6e
    m_vertex.push_back(pos);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Calcolo lo speedOut
Shinya Kitaoka 120a6e
  TPointD speedOutPoint;
Shinya Kitaoka 120a6e
  if (!m_speedMoved)  // Se non e' stato mosso lo speedOut devo calcolarlo e
Shinya Kitaoka 120a6e
                      // inserirlo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    speedOutPoint = vertex + computeSpeed(vertex, pos, 0.01);
Shinya Kitaoka 120a6e
    m_vertex.push_back(speedOutPoint);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (m_ctrlDown)
Shinya Kitaoka 120a6e
      vertex =
Shinya Kitaoka 120a6e
          m_vertex[count - 2] + computeSpeed(m_vertex[count - 2], pos, 0.01);
Shinya Kitaoka 120a6e
    speedOutPoint = vertex;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Calcolo lo speedIn
Shinya Kitaoka 120a6e
  TPointD speedInPoint = pos + computeSpeed(pos, speedOutPoint, 0.01);
Shinya Kitaoka 120a6e
  // Calcolo il "punto di mezzo" e lo inserisco
Shinya Kitaoka 120a6e
  TPointD middlePoint = 0.5 * (speedInPoint + speedOutPoint);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Inserisco il "punto di mezzo"
Shinya Kitaoka 120a6e
  m_vertex.push_back(middlePoint);
Shinya Kitaoka 120a6e
  // Inserisco lo speedIn
Shinya Kitaoka 120a6e
  m_vertex.push_back(speedInPoint);
Shinya Kitaoka 120a6e
  // Inserisco il nuovo punto
Shinya Kitaoka 120a6e
  m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::moveSpeed(const TPointD &delta) {
Shinya Kitaoka 120a6e
  int count = m_vertex.size();
Shinya Kitaoka 120a6e
  assert(count > 0);
Shinya Kitaoka 120a6e
  TPointD lastPoint        = m_vertex[count - 1];
Shinya Kitaoka 120a6e
  TPointD newSpeedOutPoint = lastPoint - delta;
Shinya Kitaoka 120a6e
  if (m_speedMoved)
Shinya Kitaoka 120a6e
    m_vertex[count - 1] = newSpeedOutPoint;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    m_vertex.push_back(newSpeedOutPoint);
Shinya Kitaoka 120a6e
    ++count;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (count < 5) {
Shinya Kitaoka 120a6e
    assert(count == 2);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD vertex = m_vertex[count - 2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD v(0, 0);
Shinya Kitaoka 120a6e
  if (newSpeedOutPoint != vertex) v = normalize(newSpeedOutPoint - vertex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double speedOut         = tdistance(newSpeedOutPoint, vertex);
Shinya Kitaoka 120a6e
  TPointD newSpeedInPoint = vertex - TPointD(speedOut * v.x, speedOut * v.y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_vertex[count - 3] = newSpeedInPoint;
Shinya Kitaoka 120a6e
  if (tdistance(m_vertex[count - 5], m_vertex[count - 6]) <= 0.02)
Shinya Kitaoka 120a6e
    // see ControlPointEditorStroke::isSpeedOutLinear() from
Shinya Kitaoka 120a6e
    // controlpointselection.cpp
Shinya Kitaoka 120a6e
    m_vertex[count - 5] =
Shinya Kitaoka 120a6e
        m_vertex[count - 6] +
Shinya Kitaoka 120a6e
        computeSpeed(m_vertex[count - 6], m_vertex[count - 3], 0.01);
Shinya Kitaoka 120a6e
  m_vertex[count - 4] = 0.5 * (m_vertex[count - 3] + m_vertex[count - 5]);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::draw() {
Shinya Kitaoka 120a6e
  UINT size = m_vertex.size();
Shinya Kitaoka 120a6e
Jeremy Bullock 977232
  drawSnap();
Jeremy Bullock 977232
Shinya Kitaoka 120a6e
  if ((m_isEditing || m_isPrompting) && size > 0) {
Shinya Kitaoka 120a6e
    tglColor(m_isEditing ? m_color : TPixel32::Green);
Shinya Kitaoka 120a6e
    std::vector<tpointd> points;</tpointd>
Shinya Kitaoka 120a6e
    points.assign(m_vertex.begin(), m_vertex.end());
Shinya Kitaoka 120a6e
    int count = points.size();
Shinya Kitaoka 120a6e
    if (count % 4 == 1) {
Shinya Kitaoka 120a6e
      // No speedOut
Shinya Kitaoka 120a6e
      points.push_back(points[count - 1]);
Shinya Kitaoka 120a6e
      count++;
Shinya Kitaoka 120a6e
    } else if (m_ctrlDown)
Shinya Kitaoka 120a6e
      points[count - 1] = points[count - 2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points.push_back(0.5 * (m_mousePosition + points[count - 1]));
Shinya Kitaoka 120a6e
    points.push_back(m_mousePosition);
Shinya Kitaoka 120a6e
    points.push_back(m_mousePosition);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double pixelSize = m_tool->getPixelSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *stroke = new TStroke(points);
Shinya Kitaoka 120a6e
    drawStrokeCenterline(*stroke, pixelSize);
Shinya Kitaoka 120a6e
    delete stroke;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_vertex.size() > 1) {
Shinya Kitaoka 120a6e
      tglColor(TPixel(79, 128, 255));
Shinya Kitaoka 120a6e
      int index = (count < 5) ? count - 1 : count - 5;
Shinya Kitaoka 120a6e
      // Disegno lo speedOut precedente (che e' quello corrente solo nel caso in
Shinya Kitaoka 120a6e
      // cui count < 5)
Shinya Kitaoka 120a6e
      TPointD p0 = m_vertex[index];
Shinya Kitaoka 120a6e
      TPointD p1 = m_vertex[index - 1];
Shinya Kitaoka 120a6e
      if (tdistance(p0, p1) > 0.1) {
Shinya Kitaoka 120a6e
        tglDrawSegment(p0, p1);
Shinya Kitaoka 120a6e
        tglDrawDisk(p0, 2 * pixelSize);
Shinya Kitaoka 120a6e
        tglDrawDisk(p1, 4 * pixelSize);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      // Disegno lo speedIn/Out corrente nel caso in cui count > 5
Shinya Kitaoka 120a6e
      if (m_speedMoved && count > 5) {
Shinya Kitaoka 120a6e
        TPointD p0 = m_vertex[count - 1];
Shinya Kitaoka 120a6e
        TPointD p1 = m_vertex[count - 2];
Shinya Kitaoka 120a6e
        TPointD p2 = m_vertex[count - 3];
Shinya Kitaoka 120a6e
        tglDrawSegment(p0, p2);
Shinya Kitaoka 120a6e
        tglDrawDisk(p0, 2 * pixelSize);
Shinya Kitaoka 120a6e
        tglDrawDisk(p1, 4 * pixelSize);
Shinya Kitaoka 120a6e
        tglDrawDisk(p2, 2 * pixelSize);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_closed)
Shinya Kitaoka 120a6e
      tglColor(TPixel32((m_color.r + 127) % 255, m_color.g,
Shinya Kitaoka 120a6e
                        (m_color.b + 127) % 255, m_color.m));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      tglColor(m_color);
Shinya Kitaoka 120a6e
    tglDrawCircle(m_vertex[0], joinDistance * pixelSize);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::leftButtonDown(const TPointD &pos,
Shinya Kitaoka 120a6e
                                        const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_color     = TPixel32::Red;
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
Shinya Kitaoka 120a6e
    if (style) {
Shinya Kitaoka 120a6e
      m_isEditing = style->isStrokeStyle();
Shinya Kitaoka 120a6e
      m_color     = style->getAverageColor();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      m_isEditing = false;
Shinya Kitaoka 120a6e
      m_color     = TPixel32::Black;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_undo = new MultilinePrimitiveUndo(m_vertex, this);
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(m_undo);
Shinya Kitaoka 120a6e
  m_mousePosition = pos;
Shinya Kitaoka 120a6e
Jeremy Bullock 977232
  TPointD newPos;
Jeremy Bullock 977232
  newPos = getSnap(pos);
Jeremy Bullock 977232
Shinya Kitaoka 120a6e
  // Se clicco nell'ultimo vertice chiudo la linea.
shun-iwasawa 036853
  TPointD _pos = pos;
Shinya Kitaoka 120a6e
  if (m_closed) _pos = m_vertex.front();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (e.isShiftPressed() && !m_vertex.empty())
Shinya Kitaoka 120a6e
    addVertex(rectify(m_vertex.back(), _pos));
Shinya Kitaoka 120a6e
  else
Jeremy Bullock 977232
    addVertex(newPos);
Shinya Kitaoka 120a6e
  m_undo->setNewVertex(m_vertex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_beforeSpeedMoved = m_speedMoved;
Shinya Kitaoka 120a6e
  m_speedMoved       = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::leftButtonDrag(const TPointD &pos,
Shinya Kitaoka 120a6e
                                        const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (m_vertex.size() == 0 || m_isSingleLine) return;
shun-iwasawa 036853
  if (m_speedMoved || tdistance2(m_vertex[m_vertex.size() - 1], pos) >
shun-iwasawa 036853
                          sq(7.0 * m_tool->getPixelSize())) {
Shinya Kitaoka 120a6e
    moveSpeed(m_mousePosition - pos);
Shinya Kitaoka 120a6e
    m_speedMoved = true;
Shinya Kitaoka 120a6e
    m_undo->setNewVertex(m_vertex);
Shinya Kitaoka 120a6e
    m_mousePosition = pos;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::leftButtonDoubleClick(const TPointD &,
Shinya Kitaoka 120a6e
                                               const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  endLine();
Jeremy Bullock 977232
  resetSnap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  if (m_closed) endLine();
Jeremy Bullock 977232
  resetSnap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  m_ctrlDown = e.isCtrlPressed();
Jeremy Bullock 977232
  TPointD newPos;
Jeremy Bullock 977232
  newPos = calculateSnap(pos);
Jeremy Bullock 977232
  newPos = checkGuideSnapping(pos);
Jeremy Bullock 977232
Shinya Kitaoka 120a6e
  if (m_isEditing) {
Shinya Kitaoka 120a6e
    if (e.isShiftPressed() && !m_vertex.empty())
Jeremy Bullock 977232
      m_mousePosition = rectify(m_vertex.back(), newPos);
Shinya Kitaoka 120a6e
    else
Jeremy Bullock 977232
      m_mousePosition = newPos;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    double dist = joinDistance * joinDistance;
Toshihiro Shimizu 890ddd
Jeremy Bullock 977232
    if (!m_vertex.empty() &&
Jeremy Bullock 977232
        (tdistance2(pos, m_vertex.front()) < dist * m_tool->getPixelSize())) {
Shinya Kitaoka 120a6e
      m_closed        = true;
Shinya Kitaoka 120a6e
      m_mousePosition = m_vertex.front();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      m_closed = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  } else
Jeremy Bullock 977232
    m_mousePosition = newPos;
Shinya Kitaoka 120a6e
  m_tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 7f1e30
bool MultiLinePrimitive::keyDown(QKeyEvent *event) {
shun-iwasawa 7f1e30
  if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
Jeremy Bullock 2bac7d
    endLine();
Jeremy Bullock 2bac7d
    return true;
Jeremy Bullock 2bac7d
  }
Jeremy Bullock 2bac7d
shun-iwasawa 7f1e30
  if (event->key() != Qt::Key_Escape || !m_isEditing) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT size = m_vertex.size();
Shinya Kitaoka 120a6e
  if (size <= 1) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_isSingleLine) TUndoManager::manager()->popUndo((size - 1) / 4 + 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_isEditing        = false;
Shinya Kitaoka 120a6e
  m_speedMoved       = false;
Shinya Kitaoka 120a6e
  m_beforeSpeedMoved = false;
Shinya Kitaoka 120a6e
  m_closed           = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_vertex.clear();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *MultiLinePrimitive::makeStroke() const {
Shinya Kitaoka 120a6e
  double thick = getThickness();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*---
Shinya Kitaoka 120a6e
   * Pencilの場合は、線幅を減らす。Thickness1の線を1ピクセルにするため。(thick
Shinya Kitaoka 120a6e
   * = 0 になる)---*/
Shinya Kitaoka 120a6e
  if (m_param->m_pencil.getValue()) thick -= 1.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT size = m_vertex.size();
Shinya Kitaoka 120a6e
  if (size <= 1) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_isSingleLine) TUndoManager::manager()->popUndo((size - 1) / 4 + 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TStroke *stroke = 0;
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> points;</tthickpoint>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)size; i++) {
Shinya Kitaoka 120a6e
    TPointD vertex = m_vertex[i];
Shinya Kitaoka 120a6e
    points.push_back(TThickPoint(vertex, thick));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  stroke = new TStroke(points);
Shinya Kitaoka 120a6e
  if (m_closed) stroke->setSelfLoop();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::endLine() {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_isEditing        = false;
Shinya Kitaoka 120a6e
  m_speedMoved       = false;
Shinya Kitaoka 120a6e
  m_beforeSpeedMoved = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_isSingleLine && !m_vertex.empty() &&
Shinya Kitaoka 120a6e
      m_vertex.size() % 4 != 1 /* && !m_rasterTool*/) {
Shinya Kitaoka 120a6e
    m_vertex.erase(--m_vertex.end());
Shinya Kitaoka 120a6e
    assert(m_vertex.size() == 3 || m_vertex.size() % 4 == 1);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_tool->addStroke();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_closed) m_closed = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_vertex.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::onActivate() {
Shinya Kitaoka 120a6e
  m_isEditing = false;
Shinya Kitaoka 120a6e
  m_closed    = false;
Shinya Kitaoka 120a6e
  m_vertex.clear();
Shinya Kitaoka 120a6e
  m_speedMoved       = false;
Shinya Kitaoka 120a6e
  m_beforeSpeedMoved = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::onEnter() {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
    m_color = TPixel32::Red;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
shun-iwasawa 036853
    if (style) m_color = style->getAverageColor();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiLinePrimitive::onImageChanged() { onActivate(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Line Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void LinePrimitive::draw() {
Shinya Kitaoka 120a6e
  UINT size = m_vertex.size();
Toshihiro Shimizu 890ddd
Jeremy Bullock 977232
  drawSnap();
Jeremy Bullock 977232
Shinya Kitaoka 120a6e
  tglColor(TPixel32::Red);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_isEditing || m_isPrompting) {
Shinya Kitaoka 120a6e
    glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
    tglVertex(m_vertex[0]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    tglVertex(m_mousePosition);
Shinya Kitaoka 120a6e
    glEnd();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jeremy Bullock 977232
void LinePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  TPointD newPos = calculateSnap(pos);
Jeremy Bullock 977232
  newPos         = checkGuideSnapping(pos);
Jeremy Bullock 977232
  m_tool->invalidate();
Jeremy Bullock 977232
}
Jeremy Bullock 977232
Jeremy Bullock 977232
//-----------------------------------------------------------------------------
Jeremy Bullock 977232
Shinya Kitaoka 120a6e
void LinePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_color     = TPixel32::Red;
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
Shinya Kitaoka 120a6e
    if (style) {
Shinya Kitaoka 120a6e
      m_isEditing = style->isStrokeStyle();
Shinya Kitaoka 120a6e
      m_color     = style->getAverageColor();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      m_isEditing = false;
Shinya Kitaoka 120a6e
      m_color     = TPixel32::Black;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Jeremy Bullock 977232
  TPointD newPos = getSnap(pos);
Jeremy Bullock 977232
Jeremy Bullock 977232
  m_mousePosition = newPos;
Shinya Kitaoka 120a6e
Jeremy Bullock 977232
  TPointD _pos = newPos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_param->m_pencil.getValue() &&
Shinya Kitaoka 120a6e
      (m_param->m_targetType & TTool::ToonzImage ||
Shinya Kitaoka 120a6e
       m_param->m_targetType & TTool::RasterImage)) {
Shinya Kitaoka 120a6e
    if (m_param->m_rasterToolSize.getValue() % 2 != 0)
Jeremy Bullock 977232
      _pos = TPointD((int)newPos.x, (int)newPos.y);
Shinya Kitaoka 120a6e
    else
Jeremy Bullock 977232
      _pos = TPointD((int)newPos.x + 0.5, (int)newPos.y + 0.5);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_vertex.size() == 0)
Shinya Kitaoka 120a6e
    addVertex(_pos);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    if (e.isShiftPressed() && !m_vertex.empty())
Jeremy Bullock 977232
      addVertex(rectify(m_vertex.back(), pos));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      addVertex(_pos);
Shinya Kitaoka 120a6e
    endLine();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void LinePrimitive::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Jeremy Bullock 977232
  TPointD newPos = calculateSnap(pos);
Jeremy Bullock 977232
  newPos         = checkGuideSnapping(pos);
Toshihiro Shimizu 890ddd
Jeremy Bullock 977232
  m_mousePosition = newPos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void LinePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  // snapping
Jeremy Bullock 977232
  TPointD newPos = getSnap(pos);
Jeremy Bullock 977232
Jeremy Bullock 977232
  m_mousePosition = newPos;
Shinya Kitaoka 120a6e
  if (e.isShiftPressed() && !m_vertex.empty())
Shinya Kitaoka 120a6e
    m_vertex.push_back(rectify(m_vertex.back(), pos));
Shinya Kitaoka 120a6e
  else
Jeremy Bullock 977232
    m_vertex.push_back(newPos);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  endLine();
Jeremy Bullock 977232
Jeremy Bullock 977232
  resetSnap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Ellipse Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EllipsePrimitive::draw() {
Jeremy Bullock 977232
  drawSnap();
Shinya Kitaoka 120a6e
  if (m_isEditing || m_isPrompting ||
Shinya Kitaoka 120a6e
      areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Shinya Kitaoka 120a6e
      areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1)) {
Shinya Kitaoka 120a6e
    tglColor(m_isEditing ? m_color : TPixel32::Green);
Shinya Kitaoka 120a6e
    TPointD centre = TPointD((m_selectingRect.x0 + m_selectingRect.x1) * 0.5,
Shinya Kitaoka 120a6e
                             (m_selectingRect.y0 + m_selectingRect.y1) * 0.5);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    glPushMatrix();
Shinya Kitaoka 120a6e
    tglMultMatrix(TScale(centre, m_selectingRect.x1 - m_selectingRect.x0,
Shinya Kitaoka 120a6e
                         m_selectingRect.y1 - m_selectingRect.y0));
Shinya Kitaoka 120a6e
    tglDrawCircle(centre, 0.5);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    glPopMatrix();
Shinya Kitaoka 120a6e
    drawRect(m_selectingRect, m_color, 0x5555, true);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EllipsePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Jeremy Bullock 977232
  TPointD newPos     = getSnap(pos);
Jeremy Bullock 977232
  m_startPoint       = newPos;
Jeremy Bullock 977232
  m_selectingRect.x0 = newPos.x;
Jeremy Bullock 977232
  m_selectingRect.y0 = newPos.y;
Jeremy Bullock 977232
  m_selectingRect.x1 = newPos.x;
Jeremy Bullock 977232
  m_selectingRect.y1 = newPos.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
    m_color     = TPixel32::Red;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
Shinya Kitaoka 120a6e
    if (style) {
Shinya Kitaoka 120a6e
      m_isEditing = style->isStrokeStyle();
Shinya Kitaoka 120a6e
      m_color     = style->getAverageColor();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      m_isEditing = false;
Shinya Kitaoka 120a6e
      m_color     = TPixel32::Black;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EllipsePrimitive::leftButtonDrag(const TPointD &realPos,
Shinya Kitaoka 120a6e
                                      const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD pos;
Shinya Kitaoka 120a6e
  if (e.isShiftPressed()) {
Shinya Kitaoka 120a6e
    double distance = tdistance(realPos, m_startPoint) * M_SQRT1_2;
Shinya Kitaoka 120a6e
    pos.x           = (realPos.x > m_startPoint.x) ? m_startPoint.x + distance
pojienie 7f72a6
                                                   : m_startPoint.x - distance;
pojienie 7f72a6
    pos.y           = (realPos.y > m_startPoint.y) ? m_startPoint.y + distance
pojienie 7f72a6
                                                   : m_startPoint.y - distance;
Shinya Kitaoka 120a6e
  } else {
Jeremy Bullock 977232
    pos = calculateSnap(realPos);
Jeremy Bullock 977232
    pos = checkGuideSnapping(realPos);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_pos = pos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_selectingRect.x1 = pos.x;
Shinya Kitaoka 120a6e
  m_selectingRect.y1 = pos.y;
Shinya Kitaoka 120a6e
  if (!e.isAltPressed()) {
Shinya Kitaoka 120a6e
    m_selectingRect.x0 = m_startPoint.x;
Shinya Kitaoka 120a6e
    m_selectingRect.y0 = m_startPoint.y;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_selectingRect.x0 = m_startPoint.x + m_startPoint.x - pos.x;
Shinya Kitaoka 120a6e
    m_selectingRect.y0 = m_startPoint.y + m_startPoint.y - pos.y;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *EllipsePrimitive::makeStroke() const {
Shinya Kitaoka 120a6e
  if (areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Shinya Kitaoka 120a6e
      areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1))
Shinya Kitaoka 120a6e
    return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return makeEllipticStroke(
manongjohn 4fae98
      getThickness(),
shun-iwasawa 036853
      TPointD(0.5 * (m_selectingRect.x0 + m_selectingRect.x1),
shun-iwasawa 036853
              0.5 * (m_selectingRect.y0 + m_selectingRect.y1)),
Shinya Kitaoka 120a6e
      fabs(0.5 * (m_selectingRect.x1 - m_selectingRect.x0)),
Shinya Kitaoka 120a6e
      fabs(0.5 * (m_selectingRect.y1 - m_selectingRect.y0)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EllipsePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
  m_isEditing = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_tool->addStroke();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EllipsePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  m_pos = calculateSnap(pos);
Jeremy Bullock 977232
  m_pos = checkGuideSnapping(pos);
Jeremy Bullock 977232
  m_tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void EllipsePrimitive::onEnter() {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_color = TPixel32::Red;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
shun-iwasawa 036853
    if (style) m_color = style->getAverageColor();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Arc Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie 5aac48
void MultiArcPrimitive::draw() {
Jeremy Bullock 977232
  drawSnap();
Jeremy Bullock 977232
pojienie 31992b
  double pixelSize = m_tool->getPixelSize();
pojienie 31992b
Shinya Kitaoka 120a6e
  switch (m_clickNumber) {
Shinya Kitaoka 120a6e
  case 1:
pojienie 2507b7
    tglColor(m_color);
Shinya Kitaoka 120a6e
    tglDrawSegment(m_startPoint, m_endPoint);
pojienie 31992b
pojienie 03f89f
    if (m_stroke) {
pojienie 03f89f
      drawStrokeCenterline(*m_stroke, sqrt(tglGetPixelSize2()));
pojienie fae9d3
      TPointD firstPoint = m_stroke->getControlPoint(0);
pojienie fae9d3
      if (firstPoint == m_endPoint) {
pojienie 2507b7
        tglColor(TPixel32((m_color.r + 127) % 255, m_color.g,
pojienie 2507b7
                          (m_color.b + 127) % 255, m_color.m));
pojienie 2507b7
      }
pojienie 2507b7
      tglDrawCircle(m_stroke->getControlPoint(0), joinDistance * pixelSize);
pojienie 31992b
    }
pojienie 03f89f
Shinya Kitaoka 120a6e
    break;
pojienie 31992b
Shinya Kitaoka 120a6e
  case 2:
pojienie a82098
    tglColor(m_isPrompting ? TPixel32::Green : m_color);
pojienie a82098
    if (!m_isPrompting) {
pojienie a82098
      glLineStipple(1, 0x5555);
pojienie a82098
      glEnable(GL_LINE_STIPPLE);
pojienie a82098
      glBegin(GL_LINE_STRIP);
pojienie a82098
      tglVertex(m_startPoint);
pojienie a82098
      tglVertex(m_centralPoint);
pojienie a82098
      tglVertex(m_endPoint);
pojienie a82098
      glEnd();
pojienie a82098
      glDisable(GL_LINE_STIPPLE);
pojienie a82098
    }
Shinya Kitaoka 120a6e
pojienie a82098
    if (m_stroke) drawStrokeCenterline(*m_stroke, sqrt(tglGetPixelSize2()));
pojienie 31992b
pojienie a82098
    if (m_strokeTemp)
pojienie a82098
      drawStrokeCenterline(*m_strokeTemp, sqrt(tglGetPixelSize2()));
pojienie 31992b
pojienie fae9d3
    if (m_stroke) {
pojienie fae9d3
      TPointD firstPoint = m_stroke->getControlPoint(0);
pojienie fae9d3
      if (firstPoint == m_endPoint) {
pojienie 2507b7
        tglColor(TPixel32((m_color.r + 127) % 255, m_color.g,
pojienie 2507b7
                          (m_color.b + 127) % 255, m_color.m));
pojienie 2507b7
      }
pojienie a82098
      tglDrawCircle(m_stroke->getControlPoint(0), joinDistance * pixelSize);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie 5aac48
TStroke *MultiArcPrimitive::makeStroke() const {
pojienie 5aac48
  return new TStroke(*m_stroke);
pojienie 5aac48
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
shun-iwasawa 71d24f
void MultiArcPrimitive::leftButtonDown(const TPointD &pos,
shun-iwasawa 71d24f
                                       const TMouseEvent &) {
shun-iwasawa 71d24f
  if (m_clickNumber == 0) {
shun-iwasawa 71d24f
    TPointD newPos = calculateSnap(pos);
shun-iwasawa 71d24f
    newPos         = checkGuideSnapping(pos);
shun-iwasawa 71d24f
    m_startPoint   = newPos;
shun-iwasawa 71d24f
  }
shun-iwasawa 71d24f
}
shun-iwasawa 71d24f
shun-iwasawa 71d24f
//-----------------------------------------------------------------------------
shun-iwasawa 71d24f
pojienie a82098
void MultiArcPrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Jeremy Bullock 977232
  TPointD newPos = getSnap(pos);
Jeremy Bullock 977232
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> points(9);</tthickpoint>
pojienie 1e5f57
  double thick     = getThickness();
pojienie 1e5f57
  double dist      = joinDistance * joinDistance;
pojienie 1e5f57
  bool strokeAdded = false;
Shinya Kitaoka 120a6e
pojienie 8f2ac7
  MultiArcPrimitiveUndo *undo =
pojienie 8f2ac7
      new MultiArcPrimitiveUndo(this, m_stroke, m_strokeTemp, m_startPoint,
pojienie 8f2ac7
                                m_endPoint, m_centralPoint, m_clickNumber);
pojienie e8ee24
pojienie 03f89f
  if (app->getCurrentObject()->isSpline()) {
pojienie 03f89f
    m_isEditing = true;
pojienie 03f89f
    m_color     = TPixel32::Red;
pojienie 03f89f
  } else {
pojienie 03f89f
    const TColorStyle *style = app->getCurrentLevelStyle();
pojienie 03f89f
    if (style) {
pojienie 03f89f
      m_isEditing = style->isStrokeStyle();
pojienie 03f89f
      m_color     = style->getAverageColor();
pojienie 03f89f
    } else {
pojienie 03f89f
      m_isEditing = false;
pojienie 03f89f
      m_color     = TPixel32::Black;
pojienie 03f89f
    }
pojienie 03f89f
  }
pojienie 03f89f
Shinya Kitaoka 120a6e
  switch (m_clickNumber) {
Shinya Kitaoka 120a6e
  case 0:
pojienie d94c5a
    m_endPoint = newPos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_clickNumber++;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case 1:
pojienie d94c5a
    m_centralPoint = newPos;
pojienie d94c5a
    points[0]      = TThickPoint(m_startPoint, thick);
pojienie d94c5a
    points[8]      = TThickPoint(m_endPoint, thick);
pojienie d94c5a
    points[4]      = TThickPoint(0.5 * (points[0] + points[8]), thick);
pojienie d94c5a
    points[2]      = TThickPoint(0.5 * (points[0] + points[4]), thick);
pojienie d94c5a
    points[6]      = TThickPoint(0.5 * (points[4] + points[8]), thick);
Shinya Kitaoka 120a6e
pojienie a82098
    points[1]    = TThickPoint(0.5 * (points[0] + points[2]), thick);
pojienie a82098
    points[3]    = TThickPoint(0.5 * (points[2] + points[4]), thick);
pojienie a82098
    points[5]    = TThickPoint(0.5 * (points[4] + points[6]), thick);
pojienie a82098
    points[7]    = TThickPoint(0.5 * (points[6] + points[8]), thick);
pojienie a82098
    m_strokeTemp = new TStroke(points);
Shinya Kitaoka 120a6e
    m_clickNumber++;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case 2:
pojienie d94c5a
    m_startPoint = newPos;
pojienie a82098
    if (!m_isSingleArc) {
pojienie a82098
      m_clickNumber = 1;
pojienie a82098
      if (m_stroke) {
pojienie a82098
        TVectorImageP vi = new TVectorImage();
pojienie a82098
        vi->addStroke(m_stroke);
pojienie a82098
        vi->addStroke(m_strokeTemp);
pojienie a82098
        m_strokeTemp = 0;
pojienie a82098
        vi->joinStroke(0, 1, m_stroke->getControlPointCount() - 1, 0,
pojienie a82098
                       getSmooth());
pojienie a82098
pojienie a82098
        m_stroke           = new TStroke(*vi->getStroke(0));
pojienie a82098
        int count          = m_stroke->getControlPointCount();
pojienie a82098
        TPointD firstPoint = m_stroke->getControlPoint(0);
pojienie a82098
        TPointD lastPoint  = m_stroke->getControlPoint(count - 1);
pojienie fd2822
        m_startPoint       = lastPoint;
pojienie a82098
        if (firstPoint == lastPoint) {
pojienie a82098
          vi->joinStroke(0, 0, 0, m_stroke->getControlPointCount() - 1,
pojienie a82098
                         getSmooth());
pojienie a82098
          delete m_stroke;
pojienie a82098
          m_stroke = new TStroke(*vi->getStroke(0));
pojienie e8ee24
          TUndoManager::manager()->popUndo(m_undoCount);
pojienie e8ee24
          m_undoCount = 0;
pojienie a82098
          m_tool->addStroke();
pojienie a82098
          onDeactivate();
pojienie 1e5f57
          strokeAdded = true;
pojienie a82098
        }
pojienie a82098
      } else {
pojienie a82098
        m_stroke     = m_strokeTemp;
pojienie a82098
        m_strokeTemp = 0;
pojienie fd2822
        m_startPoint = m_endPoint;
pojienie a82098
      }
pojienie 4fea85
    } else {
pojienie e8ee24
      m_stroke     = m_strokeTemp;
pojienie a82098
      m_strokeTemp = 0;
pojienie e8ee24
      TUndoManager::manager()->popUndo(m_undoCount);
pojienie e8ee24
      m_undoCount = 0;
pojienie a82098
      m_tool->addStroke();
pojienie 4fea85
      onDeactivate();
pojienie 1e5f57
      strokeAdded = true;
pojienie bdf2c1
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
pojienie e8ee24
pojienie 1e5f57
  if (strokeAdded) {
pojienie 1e5f57
    delete undo;
pojienie 1e5f57
  } else {
pojienie 1e5f57
    undo->setRedoData(m_stroke, m_strokeTemp, m_startPoint, m_endPoint,
pojienie 1e5f57
                      m_centralPoint, m_clickNumber);
pojienie 1e5f57
    TUndoManager::manager()->add(undo);
pojienie 1e5f57
    ++m_undoCount;
pojienie 1e5f57
  }
pojienie e8ee24
Jeremy Bullock 977232
  resetSnap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie a82098
void MultiArcPrimitive::leftButtonDoubleClick(const TPointD &,
pojienie a82098
                                              const TMouseEvent &e) {
pojienie e8ee24
  if (m_stroke) {
pojienie e8ee24
    TUndoManager::manager()->popUndo(m_undoCount);
pojienie e8ee24
    m_undoCount = 0;
pojienie e8ee24
    m_tool->addStroke();
pojienie e8ee24
  }
pojienie a82098
  onDeactivate();
pojienie a82098
}
pojienie a82098
pojienie a82098
//-----------------------------------------------------------------------------
pojienie a82098
pojienie bdf2c1
bool MultiArcPrimitive::keyDown(QKeyEvent *event) {
pojienie bdf2c1
  if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
pojienie e8ee24
    if (m_stroke) {
pojienie e8ee24
      TUndoManager::manager()->popUndo(m_undoCount);
pojienie e8ee24
      m_undoCount = 0;
pojienie e8ee24
      m_tool->addStroke();
pojienie e8ee24
    }
pojienie 4fea85
    onDeactivate();
pojienie bdf2c1
    return true;
pojienie bdf2c1
  }
pojienie bdf2c1
  return false;
pojienie bdf2c1
}
pojienie bdf2c1
pojienie bdf2c1
//-----------------------------------------------------------------------------
pojienie bdf2c1
pojienie 5aac48
void MultiArcPrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  TPointD newPos = calculateSnap(pos);
Jeremy Bullock 977232
  newPos         = checkGuideSnapping(pos);
Jeremy Bullock 977232
pojienie a82098
  double dist = joinDistance * joinDistance;
pojienie a82098
Shinya Kitaoka 120a6e
  switch (m_clickNumber) {
pojienie a82098
  case 0:
pojienie a82098
    m_startPoint = newPos;
pojienie a82098
    break;
Shinya Kitaoka 120a6e
  case 1:
Shinya Kitaoka 120a6e
    if (e.isShiftPressed())
Shinya Kitaoka 120a6e
      m_endPoint = rectify(m_startPoint, pos);
Shinya Kitaoka 120a6e
    else
Jeremy Bullock 977232
      m_endPoint = newPos;
pojienie a82098
pojienie a82098
    if (m_stroke) {
pojienie a82098
      TPointD firstPoint = m_stroke->getControlPoint(0);
pojienie a82098
      if (tdistance2(m_endPoint, firstPoint) < dist * m_tool->getPixelSize())
pojienie a82098
        m_endPoint = firstPoint;
pojienie a82098
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 2:
pojienie a82098
    m_centralPoint = newPos;
pojienie a82098
    TThickQuadratic q(m_startPoint, TThickPoint(m_centralPoint, getThickness()),
pojienie a82098
                      m_endPoint);
Shinya Kitaoka 120a6e
    TThickQuadratic q0, q1, q00, q01, q10, q11;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    q.split(0.5, q0, q1);
Shinya Kitaoka 120a6e
    q0.split(0.5, q00, q01);
Shinya Kitaoka 120a6e
    q1.split(0.5, q10, q11);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    assert(q00.getP2() == q01.getP0());
Shinya Kitaoka 120a6e
    assert(q01.getP2() == q10.getP0());
Shinya Kitaoka 120a6e
    assert(q10.getP2() == q11.getP0());
Shinya Kitaoka 120a6e
pojienie a82098
    m_strokeTemp->setControlPoint(1, q00.getP1());
pojienie a82098
    m_strokeTemp->setControlPoint(2, q00.getP2());
pojienie a82098
    m_strokeTemp->setControlPoint(3, q01.getP1());
pojienie a82098
    m_strokeTemp->setControlPoint(4, q01.getP2());
pojienie a82098
    m_strokeTemp->setControlPoint(5, q10.getP1());
pojienie a82098
    m_strokeTemp->setControlPoint(6, q10.getP2());
pojienie a82098
    m_strokeTemp->setControlPoint(7, q11.getP1());
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Jeremy Bullock 977232
  m_tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
pojienie 5aac48
void MultiArcPrimitive::onEnter() {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline())
Shinya Kitaoka 120a6e
    m_color = TPixel32::Red;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
shun-iwasawa 036853
    if (style) m_color = style->getAverageColor();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Polygon Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PolygonPrimitive::draw() {
Jeremy Bullock 977232
  drawSnap();
Shinya Kitaoka 120a6e
  if (!m_isEditing && !m_isPrompting) return;
Shinya Kitaoka 120a6e
  tglColor(m_isEditing ? m_color : TPixel32::Green);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int edgeCount = m_param->m_edgeCount.getValue();
Shinya Kitaoka 120a6e
  if (edgeCount == 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double angleDiff = M_2PI / edgeCount;
Shinya Kitaoka 120a6e
  double angle     = (3 * M_PI + angleDiff) * 0.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_LOOP);
Shinya Kitaoka 120a6e
  for (int i = 0; i < edgeCount; i++) {
Shinya Kitaoka 120a6e
    tglVertex(m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius));
Shinya Kitaoka 120a6e
    angle += angleDiff;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PolygonPrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (app->getCurrentObject()->isSpline()) {
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
    m_color     = TPixel32::Red;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    const TColorStyle *style = app->getCurrentLevelStyle();
Shinya Kitaoka 120a6e
    if (style) {
Shinya Kitaoka 120a6e
      m_isEditing = style->isStrokeStyle();
Shinya Kitaoka 120a6e
      m_color     = style->getAverageColor();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      m_isEditing = false;
Shinya Kitaoka 120a6e
      m_color     = TPixel32::Black;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Jeremy Bullock 977232
  m_centre = getSnap(pos);
Shinya Kitaoka 120a6e
  m_radius = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PolygonPrimitive::leftButtonDrag(const TPointD &pos,
Shinya Kitaoka 120a6e
                                      const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Jeremy Bullock 977232
  TPointD newPos = calculateSnap(pos);
shun-iwasawa 7f1e30
  newPos         = checkGuideSnapping(pos);
shun-iwasawa 7f1e30
  m_radius       = tdistance(m_centre, newPos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStroke *PolygonPrimitive::makeStroke() const {
Shinya Kitaoka 120a6e
  double thick = getThickness();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int edgeCount = m_param->m_edgeCount.getValue();
Shinya Kitaoka 120a6e
  if (edgeCount == 0) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double angleDiff = M_2PI / (double)edgeCount;
Shinya Kitaoka 120a6e
  double angle     = (3 * M_PI + angleDiff) * 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *stroke = 0;
Shinya Kitaoka 120a6e
  if (m_param->m_targetType & TTool::Vectors) {
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points(4 * edgeCount + 1);</tthickpoint>
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    // Posiziono gli angoli
Shinya Kitaoka 120a6e
    for (i = 0; i <= (int)points.size(); i += 4) {
Shinya Kitaoka 120a6e
      points[i] = TThickPoint(
Shinya Kitaoka 120a6e
          m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius),
Shinya Kitaoka 120a6e
          thick);
Shinya Kitaoka 120a6e
      angle += angleDiff;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // posiziono i punti medi e i punti per gestire la linearita'
Shinya Kitaoka 120a6e
    for (i = 0; i < (int)points.size() - 1; i += 4) {
Shinya Kitaoka 120a6e
      TPointD vertex           = convert(points[i]);
Shinya Kitaoka 120a6e
      TPointD nextVertex       = convert(points[i + 4]);
Shinya Kitaoka 120a6e
      TPointD speed            = computeSpeed(vertex, nextVertex, 0.01);
Shinya Kitaoka 120a6e
      TPointD speedOutPoint    = vertex + speed;
Shinya Kitaoka 120a6e
      TPointD speedInNextPoint = nextVertex - speed;
Shinya Kitaoka 120a6e
      TPointD middlePoint      = 0.5 * (speedOutPoint + speedInNextPoint);
Shinya Kitaoka 120a6e
      points[i + 1]            = TThickPoint(speedOutPoint, thick);
Shinya Kitaoka 120a6e
      points[i + 2]            = TThickPoint(middlePoint, thick);
Shinya Kitaoka 120a6e
      points[i + 3]            = TThickPoint(speedInNextPoint, thick);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    stroke = new TStroke(points);
Shinya Kitaoka 120a6e
  } else if (m_param->m_targetType & TTool::ToonzImage ||
Shinya Kitaoka 120a6e
             m_param->m_targetType & TTool::RasterImage) {
Shinya Kitaoka 120a6e
    std::vector<tthickpoint> points(edgeCount + edgeCount + 1);</tthickpoint>
Shinya Kitaoka 120a6e
    points[0] = TThickPoint(
Shinya Kitaoka 120a6e
        m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius),
Shinya Kitaoka 120a6e
        thick);
Shinya Kitaoka 120a6e
    for (int i = 1; i <= edgeCount; i++) {
Shinya Kitaoka 120a6e
      angle += angleDiff;
Shinya Kitaoka 120a6e
      points[i + i] = TThickPoint(
Shinya Kitaoka 120a6e
          m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius),
Shinya Kitaoka 120a6e
          thick);
Shinya Kitaoka 120a6e
      points[i + i - 1] = (points[i + i - 2] + points[i + i]) * 0.5;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    stroke = new TStroke(points);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  stroke->setSelfLoop();
Shinya Kitaoka 120a6e
  return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void PolygonPrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  if (!m_isEditing) return;
Shinya Kitaoka 120a6e
  m_isEditing = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_tool->addStroke();
Toshihiro Shimizu 890ddd
}
Jeremy Bullock 977232
Jeremy Bullock 977232
//-----------------------------------------------------------------------------
Jeremy Bullock 977232
Jeremy Bullock 977232
void PolygonPrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock 977232
  TPointD newPos = calculateSnap(pos);
Jeremy Bullock 977232
  newPos         = checkGuideSnapping(pos);
Jeremy Bullock 977232
  m_tool->invalidate();
pojienie 5aac48
}
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
//==========================================================================================================
shun-iwasawa a5c4f3
shun-iwasawa a5c4f3
FullColorGeometricToolNotifier::FullColorGeometricToolNotifier(
shun-iwasawa a5c4f3
    GeometricTool *tool)
shun-iwasawa a5c4f3
    : m_tool(tool) {
shun-iwasawa a5c4f3
  if (TTool::Application *app = m_tool->getApplication()) {
shun-iwasawa a5c4f3
    if (TPaletteHandle *paletteHandle = app->getCurrentPalette()) {
shun-iwasawa a5c4f3
      bool ret;
shun-iwasawa a5c4f3
      ret = connect(paletteHandle, SIGNAL(colorStyleChanged(bool)), this,
shun-iwasawa a5c4f3
                    SLOT(onColorStyleChanged()));
shun-iwasawa a5c4f3
      assert(ret);
shun-iwasawa a5c4f3
      ret = connect(paletteHandle, SIGNAL(colorStyleSwitched()), this,
shun-iwasawa a5c4f3
                    SLOT(onColorStyleChanged()));
shun-iwasawa a5c4f3
      assert(ret);
shun-iwasawa a5c4f3
    }
shun-iwasawa a5c4f3
  }
8967c8
}