Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.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 "tw/keycodes.h"
Toshihiro Shimizu 890ddd
#include "historytypes.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;
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);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricGroupIt("InknpaintGeometricGroupIt", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar GeometricAutofill("InknpaintGeometricAutofill", 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);
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"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Utility Functions
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPointD rectify(const TPointD &oldPos, const TPointD &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const double h = sqrt(2.0) / 2.0;
Toshihiro Shimizu 890ddd
	const TPointD directions[] = {
Toshihiro Shimizu 890ddd
		TPointD(1, 0),
Toshihiro Shimizu 890ddd
		TPointD(h, h),
Toshihiro Shimizu 890ddd
		TPointD(0, 1),
Toshihiro Shimizu 890ddd
		TPointD(-h, h),
Toshihiro Shimizu 890ddd
		TPointD(-1, 0),
Toshihiro Shimizu 890ddd
		TPointD(-h, -h),
Toshihiro Shimizu 890ddd
		TPointD(0, -1),
Toshihiro Shimizu 890ddd
		TPointD(h, -h)};
Toshihiro Shimizu 890ddd
	TPointD v = pos - oldPos;
Toshihiro Shimizu 890ddd
	int j = 0;
Toshihiro Shimizu 890ddd
	double bestValue = v * directions[j];
Toshihiro Shimizu 890ddd
	for (int k = 1; k < 8; k++) {
Toshihiro Shimizu 890ddd
		double value = v * directions[k];
Toshihiro Shimizu 890ddd
		if (value > bestValue) {
Toshihiro Shimizu 890ddd
			bestValue = value;
Toshihiro Shimizu 890ddd
			j = k;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return oldPos + bestValue * directions[j];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPointD computeSpeed(TPointD p0, TPointD p1, double factor)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD d = p1 - p0;
Toshihiro Shimizu 890ddd
	return (d == TPointD()) ? TPointD() : d * (factor / norm(d));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRect drawBluredBrush(const TRasterImageP &ri, TStroke *stroke, int thick, double hardness, double opacity)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStroke *s = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	TPointD riCenter = ri->getRaster()->getCenterD();
Toshihiro Shimizu 890ddd
	s->transform(TTranslation(riCenter));
Toshihiro Shimizu 890ddd
	int styleId = s->getStyle();
Toshihiro Shimizu 890ddd
	TPalette *plt = ri->getPalette();
Toshihiro Shimizu 890ddd
	TPixel32 color = plt->getStyle(styleId)->getMainColor();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD bbox = s->getBBox();
Toshihiro Shimizu 890ddd
	TRect bboxI = convert(bbox).enlarge(1);
Toshihiro Shimizu 890ddd
	TRect rectRender = bboxI * ri->getRaster()->getBounds();
Toshihiro Shimizu 890ddd
	if (rectRender.isEmpty())
Toshihiro Shimizu 890ddd
		return TRect();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P workRas(ri->getRaster()->getSize());
Toshihiro Shimizu 890ddd
	TRaster32P backupRas = ri->getRaster()->clone();
Toshihiro Shimizu 890ddd
	workRas->clear();
Toshihiro Shimizu 890ddd
	QRadialGradient brushPad = ToolUtils::getBrushPad(thick, hardness);
Toshihiro Shimizu 890ddd
	BluredBrush brush(workRas, thick, brushPad, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, chunkCount = s->getChunkCount();
Toshihiro Shimizu 890ddd
	for (i = 0; i < chunkCount; i++) {
Toshihiro Shimizu 890ddd
		const TThickQuadratic *q = s->getChunk(i);
Shinya Kitaoka 3bfa54
		std::vector<tthickpoint> points;</tthickpoint>
Toshihiro Shimizu 890ddd
		points.push_back(q->getThickP0());
Toshihiro Shimizu 890ddd
		points.push_back(q->getThickP1());
Toshihiro Shimizu 890ddd
		points.push_back(q->getThickP2());
Toshihiro Shimizu 890ddd
		//i punti contenuti nello stroke sembra che haano la tickness pari al raggio e non al diametro del punto!
Toshihiro Shimizu 890ddd
		points[0].thick *= 2;
Toshihiro Shimizu 890ddd
		points[1].thick *= 2;
Toshihiro Shimizu 890ddd
		points[2].thick *= 2;
Toshihiro Shimizu 890ddd
		TRect chunkBox = brush.getBoundFromPoints(points);
Toshihiro Shimizu 890ddd
		brush.addArc(points[0], points[1], points[2], 1, 1);
Toshihiro Shimizu 890ddd
		brush.updateDrawing(ri->getRaster(), backupRas, color, chunkBox, opacity);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete s;
Toshihiro Shimizu 890ddd
	return rectRender;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRect drawBluredBrush(const TToonzImageP &ti, TStroke *stroke, int thick, double hardness,
Toshihiro Shimizu 890ddd
					  bool selective)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStroke *s = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	TPointD riCenter = ti->getRaster()->getCenterD();
Toshihiro Shimizu 890ddd
	s->transform(TTranslation(riCenter));
Toshihiro Shimizu 890ddd
	int styleId = s->getStyle();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD bbox = s->getBBox();
Toshihiro Shimizu 890ddd
	TRect bboxI = convert(bbox).enlarge(1);
Toshihiro Shimizu 890ddd
	TRect rectRender = bboxI * ti->getRaster()->getBounds();
Toshihiro Shimizu 890ddd
	if (rectRender.isEmpty())
Toshihiro Shimizu 890ddd
		return TRect();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P workRas(ti->getRaster()->getSize());
Toshihiro Shimizu 890ddd
	TRasterCM32P backupRas = ti->getRaster()->clone();
Toshihiro Shimizu 890ddd
	workRas->clear();
Toshihiro Shimizu 890ddd
	QRadialGradient brushPad = ToolUtils::getBrushPad(thick, hardness);
Toshihiro Shimizu 890ddd
	BluredBrush brush(workRas, thick, brushPad, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, chunkCount = s->getChunkCount();
Toshihiro Shimizu 890ddd
	for (i = 0; i < chunkCount; i++) {
Toshihiro Shimizu 890ddd
		const TThickQuadratic *q = s->getChunk(i);
Shinya Kitaoka 3bfa54
		std::vector<tthickpoint> points;</tthickpoint>
Toshihiro Shimizu 890ddd
		points.push_back(q->getThickP0());
Toshihiro Shimizu 890ddd
		points.push_back(q->getThickP1());
Toshihiro Shimizu 890ddd
		points.push_back(q->getThickP2());
Toshihiro Shimizu 890ddd
		//i punti contenuti nello stroke sembra che haano la tickness pari al raggio e non al diametro del punto!
Toshihiro Shimizu 890ddd
		points[0].thick *= 2;
Toshihiro Shimizu 890ddd
		points[1].thick *= 2;
Toshihiro Shimizu 890ddd
		points[2].thick *= 2;
Toshihiro Shimizu 890ddd
		TRect chunkBox = brush.getBoundFromPoints(points);
Toshihiro Shimizu 890ddd
		brush.addArc(points[0], points[1], points[2], 1, 1);
Toshihiro Shimizu 890ddd
		brush.updateDrawing(ti->getRaster(), backupRas, chunkBox, styleId, selective);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete s;
Toshihiro Shimizu 890ddd
	return rectRender;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class MultilinePrimitiveUndo : public TUndo
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::vector<tpointd> m_oldVertex;</tpointd>
Shinya Kitaoka 3bfa54
	std::vector<tpointd> m_newVertex;</tpointd>
Toshihiro Shimizu 890ddd
	MultiLinePrimitive *m_tool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 3bfa54
	MultilinePrimitiveUndo(const std::vector<tpointd> &vertex, MultiLinePrimitive *tool)</tpointd>
Toshihiro Shimizu 890ddd
		: TUndo(), m_oldVertex(vertex), m_tool(tool), m_newVertex()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~MultilinePrimitiveUndo() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const;
Toshihiro Shimizu 890ddd
	void redo() const;
Shinya Kitaoka 3bfa54
	void setNewVertex(const std::vector<tpointd> &vertex)</tpointd>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_newVertex = vertex;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QString getToolName();
Toshihiro Shimizu 890ddd
	int getHistoryType()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return HistoryType::GeometricTool;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class FullColorBluredPrimitiveUndo : public UndoFullColorPencil
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int m_thickness;
Toshihiro Shimizu 890ddd
	double m_hardness;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	FullColorBluredPrimitiveUndo(TXshSimpleLevel *level, const TFrameId &frameId, TStroke *stroke, int thickness,
Toshihiro Shimizu 890ddd
								 double hardness, double opacity, bool doAntialias, bool createdFrame, bool createdLevel)
Toshihiro Shimizu 890ddd
		: UndoFullColorPencil(level, frameId, stroke, opacity, doAntialias, createdFrame, createdLevel), m_thickness(thickness), m_hardness(hardness)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TRasterP raster = getImage()->getRaster();
Toshihiro Shimizu 890ddd
		TDimension d = raster->getSize();
Toshihiro Shimizu 890ddd
		m_tiles = new TTileSetFullColor(d);
Toshihiro Shimizu 890ddd
		TRect rect = convert(stroke->getBBox()) + TPoint((int)(d.lx * 0.5), (int)(d.ly * 0.5));
Toshihiro Shimizu 890ddd
		m_tiles->add(raster, rect.enlarge(2));
Toshihiro Shimizu 890ddd
		m_stroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~FullColorBluredPrimitiveUndo() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		insertLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
		TRasterImageP ri = getImage();
Toshihiro Shimizu 890ddd
		if (!ri)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		drawBluredBrush(ri, m_stroke, m_thickness, m_hardness, m_opacity);
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
		notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return UndoFullColorPencil::getSize() + sizeof(this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*-- Hardness<100 のときの GeometricToolのUndo --*/
Toshihiro Shimizu 890ddd
class CMBluredPrimitiveUndo : public UndoRasterPencil
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int m_thickness;
Toshihiro Shimizu 890ddd
	double m_hardness;
Toshihiro Shimizu 890ddd
	bool m_selective;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CMBluredPrimitiveUndo(TXshSimpleLevel *level, const TFrameId &frameId, TStroke *stroke, int thickness,
Toshihiro Shimizu 890ddd
						  double hardness, bool selective, bool doAntialias, bool createdFrame, bool createdLevel,
Shinya Kitaoka 3bfa54
						  std::string primitiveName)
Toshihiro Shimizu 890ddd
		: UndoRasterPencil(level, frameId, stroke, selective, false, doAntialias, createdFrame, createdLevel,
Toshihiro Shimizu 890ddd
						   primitiveName),
Toshihiro Shimizu 890ddd
		  m_thickness(thickness), m_hardness(hardness), m_selective(selective)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TRasterCM32P raster = getImage()->getRaster();
Toshihiro Shimizu 890ddd
		TDimension d = raster->getSize();
Toshihiro Shimizu 890ddd
		m_tiles = new TTileSetCM32(d);
Toshihiro Shimizu 890ddd
		TRect rect = convert(stroke->getBBox()) + TPoint((int)(d.lx * 0.5), (int)(d.ly * 0.5));
Toshihiro Shimizu 890ddd
		m_tiles->add(raster, rect.enlarge(2));
Toshihiro Shimizu 890ddd
		m_stroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~CMBluredPrimitiveUndo() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		insertLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
		TToonzImageP ti = getImage();
Toshihiro Shimizu 890ddd
		if (!ti)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		drawBluredBrush(ti, m_stroke, m_thickness, m_hardness, m_selective);
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
		notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return UndoRasterPencil::getSize() + sizeof(this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class PrimitiveParam
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Q_DECLARE_TR_FUNCTIONS(PrimitiveParam)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TDoubleProperty m_toolSize;
Toshihiro Shimizu 890ddd
	TIntProperty m_rasterToolSize;
Toshihiro Shimizu 890ddd
	TDoubleProperty m_opacity;
Toshihiro Shimizu 890ddd
	TDoubleProperty m_hardness;
Toshihiro Shimizu 890ddd
	TEnumProperty m_type;
Toshihiro Shimizu 890ddd
	TIntProperty m_edgeCount;
Toshihiro Shimizu 890ddd
	TBoolProperty m_autogroup;
Toshihiro Shimizu 890ddd
	TBoolProperty m_autofill;
Toshihiro Shimizu 890ddd
	TBoolProperty m_selective;
Toshihiro Shimizu 890ddd
	TBoolProperty m_pencil;
Toshihiro Shimizu 890ddd
	TEnumProperty m_capStyle;
Toshihiro Shimizu 890ddd
	TEnumProperty m_joinStyle;
Toshihiro Shimizu 890ddd
	TIntProperty m_miterJoinLimit;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPropertyGroup m_prop[2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_targetType;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	PrimitiveParam(int targetType)
Toshihiro Shimizu 890ddd
		: m_type("Shape:") // "W_ToolOptions_ShapeType")
Toshihiro Shimizu 890ddd
		  ,
Toshihiro Shimizu 890ddd
		  m_toolSize("Size:", 0, 100, 1) // "W_ToolOptions_ShapeThickness", 0,30,1)
Toshihiro Shimizu 890ddd
		  ,
Toshihiro Shimizu 890ddd
		  m_rasterToolSize("Size:", 1, 100, 1), m_opacity("Opacity:", 0, 100, 100), m_hardness("Hardness:", 0, 100, 100), m_edgeCount("Polygon Sides:", 3, 15, 3), m_autogroup("Auto Group", false), m_autofill("Auto Fill", false), m_selective("Selective", false), m_pencil("Pencil Mode", false), m_capStyle("Cap"), m_joinStyle("Join"), m_miterJoinLimit("Miter:", 0, 100, 4), m_targetType(targetType)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (targetType & TTool::Vectors)
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_toolSize);
Toshihiro Shimizu 890ddd
		if (targetType & TTool::ToonzImage || targetType & TTool::RasterImage) {
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_rasterToolSize);
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_hardness);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (targetType & TTool::RasterImage)
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_opacity);
Toshihiro Shimizu 890ddd
		m_prop[0].bind(m_type);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_prop[0].bind(m_edgeCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (targetType & TTool::Vectors) {
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_autogroup);
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_autofill);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (targetType & TTool::ToonzImage) {
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_selective);
Toshihiro Shimizu 890ddd
			m_prop[0].bind(m_pencil);
Toshihiro Shimizu 890ddd
			m_pencil.setId("PencilMode");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_capStyle.addValue(BUTT_WSTR);
Toshihiro Shimizu 890ddd
		m_capStyle.addValue(ROUNDC_WSTR);
Toshihiro Shimizu 890ddd
		m_capStyle.addValue(PROJECTING_WSTR);
Toshihiro Shimizu 890ddd
		m_capStyle.setId("Cap");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_joinStyle.addValue(MITER_WSTR);
Toshihiro Shimizu 890ddd
		m_joinStyle.addValue(ROUNDJ_WSTR);
Toshihiro Shimizu 890ddd
		m_joinStyle.addValue(BEVEL_WSTR);
Toshihiro Shimizu 890ddd
		m_joinStyle.setId("Join");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_miterJoinLimit.setId("Miter");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_prop[1].bind(m_capStyle);
Toshihiro Shimizu 890ddd
		m_prop[1].bind(m_joinStyle);
Toshihiro Shimizu 890ddd
		m_prop[1].bind(m_miterJoinLimit);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_selective.setId("Selective");
Toshihiro Shimizu 890ddd
		m_autogroup.setId("AutoGroup");
Toshihiro Shimizu 890ddd
		m_autofill.setId("Autofill");
Toshihiro Shimizu 890ddd
		m_type.setId("GeometricShape");
Toshihiro Shimizu 890ddd
		m_edgeCount.setId("GeometricEdge");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void updateTranslation()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_type.setQStringName(tr("Shape:"));
Toshihiro Shimizu 890ddd
		m_toolSize.setQStringName(tr("Size:"));
Toshihiro Shimizu 890ddd
		m_rasterToolSize.setQStringName(tr("Thickness:"));
Toshihiro Shimizu 890ddd
		m_opacity.setQStringName(tr("Opacity:"));
Toshihiro Shimizu 890ddd
		m_hardness.setQStringName(tr("Hardness:"));
Toshihiro Shimizu 890ddd
		m_edgeCount.setQStringName(tr("Polygon Sides:"));
Toshihiro Shimizu 890ddd
		m_autogroup.setQStringName(tr("Auto Group"));
Toshihiro Shimizu 890ddd
		m_autofill.setQStringName(tr("Auto Fill"));
Toshihiro Shimizu 890ddd
		m_selective.setQStringName(tr("Selective"));
Toshihiro Shimizu 890ddd
		m_pencil.setQStringName(tr("Pencil Mode"));
Toshihiro Shimizu 890ddd
		m_capStyle.setQStringName(tr("Cap"));
Toshihiro Shimizu 890ddd
		m_joinStyle.setQStringName(tr("Join"));
Toshihiro Shimizu 890ddd
		m_miterJoinLimit.setQStringName(tr("Miter:"));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Abstract Class Primitive
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	bool m_isEditing, m_rasterTool, m_isPrompting;
Toshihiro Shimizu 890ddd
	GeometricTool *m_tool;
Toshihiro Shimizu 890ddd
	PrimitiveParam *m_param;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	Primitive(PrimitiveParam *param, GeometricTool *tool, bool rasterTool)
Toshihiro Shimizu 890ddd
		: m_param(param), m_tool(tool), m_isEditing(false), m_rasterTool(rasterTool), m_isPrompting(false)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double getThickness() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_rasterTool)
Toshihiro Shimizu 890ddd
			return m_param->m_rasterToolSize.getValue() * 0.5;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			return m_param->m_toolSize.getValue() * 0.5;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void setIsPrompting(bool value) { m_isPrompting = value; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	virtual ~Primitive() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	virtual void leftButtonDown(const TPointD &p, const TMouseEvent &e){};
Toshihiro Shimizu 890ddd
	virtual void leftButtonDrag(const TPointD &p, const TMouseEvent &e){};
Toshihiro Shimizu 890ddd
	virtual void leftButtonUp(const TPointD &p, const TMouseEvent &e){};
Toshihiro Shimizu 890ddd
	virtual void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e){};
Toshihiro Shimizu 890ddd
	virtual void rightButtonDown(const TPointD &p, const TMouseEvent &e){};
Toshihiro Shimizu 890ddd
	virtual void mouseMove(const TPointD &p, const TMouseEvent &e){};
Toshihiro Shimizu 890ddd
	virtual bool keyDown(int key, const TPoint &point) { return false; }
Toshihiro Shimizu 890ddd
	virtual void onEnter(){};
Toshihiro Shimizu 890ddd
	virtual void draw(){};
Toshihiro Shimizu 890ddd
	virtual void onActivate(){};
Toshihiro Shimizu 890ddd
	virtual void onDeactivate(){};
Toshihiro Shimizu 890ddd
	virtual void onImageChanged(){};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	virtual TStroke *makeStroke() const = 0;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Rectangle Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RectanglePrimitive : public Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRectD m_selectingRect;
Toshihiro Shimizu 890ddd
	TPointD m_pos;
Toshihiro Shimizu 890ddd
	TPointD m_startPoint;
Toshihiro Shimizu 890ddd
	TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RectanglePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: Primitive(param, tool, reasterTool)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const { return "Rectangle"; } // W_ToolOptions_ShapeRect"; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *makeStroke() const;
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &realPos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void onEnter();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Circle Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class CirclePrimitive : public Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD m_centre;
Toshihiro Shimizu 890ddd
	TPointD m_pos;
Toshihiro Shimizu 890ddd
	double m_radius;
Toshihiro Shimizu 890ddd
	TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CirclePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: Primitive(param, tool, reasterTool)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const { return "Circle"; } // W_ToolOptions_ShapeCircle";}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	TStroke *makeStroke() const;
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void onEnter();
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
Toshihiro Shimizu 890ddd
class MultiLinePrimitive : public Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 3bfa54
	std::vector<tpointd> m_vertex;</tpointd>
Toshihiro Shimizu 890ddd
	TPointD m_mousePosition;
Toshihiro Shimizu 890ddd
	TPixel32 m_color;
Toshihiro Shimizu 890ddd
	bool m_closed, m_isSingleLine;
Toshihiro Shimizu 890ddd
	bool m_speedMoved;		 //!< True after moveSpeed(), false after addVertex()
Toshihiro Shimizu 890ddd
	bool m_beforeSpeedMoved; //!< Old value of m_speedMoved
Toshihiro Shimizu 890ddd
	bool m_ctrlDown;		 //!< Whether ctrl is hold down
Toshihiro Shimizu 890ddd
	MultilinePrimitiveUndo *m_undo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	MultiLinePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: Primitive(param, tool, reasterTool), m_closed(false), m_isSingleLine(false), m_speedMoved(false), m_beforeSpeedMoved(false), m_ctrlDown(false)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const { return "Polyline"; } // W_ToolOptions_ShapePolyline";}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addVertex(const TPointD &pos);
Toshihiro Shimizu 890ddd
	void moveSpeed(const TPointD &delta);
Toshihiro Shimizu 890ddd
	virtual void draw();
Toshihiro Shimizu 890ddd
	virtual void leftButtonDown(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	virtual void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	bool keyDown(int key, const TPoint &point);
Toshihiro Shimizu 890ddd
	TStroke *makeStroke() const;
Toshihiro Shimizu 890ddd
	void endLine();
Toshihiro Shimizu 890ddd
	void onActivate();
Toshihiro Shimizu 890ddd
	void onDeactivate()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_vertex.clear();
Toshihiro Shimizu 890ddd
		m_speedMoved = false;
Toshihiro Shimizu 890ddd
		m_beforeSpeedMoved = false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void onEnter();
Toshihiro Shimizu 890ddd
	void onImageChanged();
Shinya Kitaoka 3bfa54
	void setVertexes(const std::vector<tpointd> &vertex)</tpointd>
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_vertex = vertex;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
	void setSpeedMoved(bool speedMoved)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_speedMoved = speedMoved;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultilinePrimitiveUndo::undo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_tool->setVertexes(m_oldVertex);
Toshihiro Shimizu 890ddd
	int count = m_oldVertex.size();
Toshihiro Shimizu 890ddd
	bool speedMoved = (count != 0 && count % 4 != 1);
Toshihiro Shimizu 890ddd
	m_tool->setSpeedMoved(speedMoved);
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultilinePrimitiveUndo::redo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_tool->setVertexes(m_newVertex);
Toshihiro Shimizu 890ddd
	int count = m_newVertex.size();
Toshihiro Shimizu 890ddd
	bool speedMoved = (count != 0 && count % 4 != 1);
Toshihiro Shimizu 890ddd
	m_tool->setSpeedMoved(speedMoved);
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QString MultilinePrimitiveUndo::getToolName()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return QString("Geometric Tool %1")
Toshihiro Shimizu 890ddd
		.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
Toshihiro Shimizu 890ddd
class LinePrimitive : public MultiLinePrimitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	LinePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: MultiLinePrimitive(param, tool, reasterTool)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_isSingleLine = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string getName() const { return "Line"; } // W_ToolOptions_ShapePolyline";}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Ellipse Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class EllipsePrimitive : public Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD m_pos;
Toshihiro Shimizu 890ddd
	TRectD m_selectingRect;
Toshihiro Shimizu 890ddd
	TPointD m_startPoint;
Toshihiro Shimizu 890ddd
	TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	EllipsePrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: Primitive(param, tool, reasterTool)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const { return "Ellipse"; } // W_ToolOptions_ShapeEllipse";}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &realPos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	TStroke *makeStroke() const;
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void onEnter();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Arc Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class ArcPrimitive : public Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStroke *m_stroke;
Toshihiro Shimizu 890ddd
	TPointD m_startPoint, m_endPoint, m_centralPoint;
Toshihiro Shimizu 890ddd
	int m_clickNumber;
Toshihiro Shimizu 890ddd
	TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	ArcPrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: Primitive(param, tool, reasterTool), m_stroke(0), m_clickNumber(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~ArcPrimitive()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_stroke)
Toshihiro Shimizu 890ddd
			delete m_stroke;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const { return "Arc"; } // _ToolOptions_ShapeArc";}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *makeStroke() const;
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void onEnter();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Polygon Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class PolygonPrimitive : public Primitive
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD m_startPoint, m_centre;
Toshihiro Shimizu 890ddd
	double m_radius;
Toshihiro Shimizu 890ddd
	TPixel32 m_color;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PolygonPrimitive(PrimitiveParam *param, GeometricTool *tool, bool reasterTool)
Toshihiro Shimizu 890ddd
		: Primitive(param, tool, reasterTool)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	virtual std::string getName() const { return "Polygon"; } // W_ToolOptions_ShapePolygon";}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *makeStroke() const;
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Geometric Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class GeometricTool : public TTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	Primitive *m_primitive;
Shinya Kitaoka 3bfa54
	std::map<std::wstring, *="" primitive=""> m_primitiveTable;</std::wstring,>
Toshihiro Shimizu 890ddd
	PrimitiveParam m_param;
Shinya Kitaoka 3bfa54
	std::wstring m_typeCode;
Toshihiro Shimizu 890ddd
	bool m_active;
Toshihiro Shimizu 890ddd
	bool m_firstTime;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	GeometricTool(int targetType)
Toshihiro Shimizu 890ddd
		: TTool("T_Geometric"), m_primitive(0), m_param(targetType), m_active(false), m_firstTime(true)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		bind(targetType);
Toshihiro Shimizu 890ddd
		if ((targetType & TTool::RasterImage) ||
Toshihiro Shimizu 890ddd
			(targetType & TTool::ToonzImage)) {
Toshihiro Shimizu 890ddd
			addPrimitive(new RectanglePrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
			addPrimitive(new CirclePrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
			addPrimitive(new EllipsePrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
			addPrimitive(new LinePrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
			addPrimitive(new MultiLinePrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
			addPrimitive(new ArcPrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
			addPrimitive(new PolygonPrimitive(&m_param, this, true));
Toshihiro Shimizu 890ddd
		} else //targetType == 1
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			//vector
Toshihiro Shimizu 890ddd
			addPrimitive(m_primitive = new RectanglePrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
			addPrimitive(new CirclePrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
			addPrimitive(new EllipsePrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
			addPrimitive(new LinePrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
			addPrimitive(new MultiLinePrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
			addPrimitive(new ArcPrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
			addPrimitive(new PolygonPrimitive(&m_param, this, false));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~GeometricTool()
Toshihiro Shimizu 890ddd
	{
Shinya Kitaoka 3bfa54
		std::map<std::wstring, *="" primitive="">::iterator it;</std::wstring,>
Toshihiro Shimizu 890ddd
		for (it = m_primitiveTable.begin(); it != m_primitiveTable.end(); ++it)
Toshihiro Shimizu 890ddd
			delete it->second;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolType getToolType() const { return TTool::LevelWriteTool; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void updateTranslation()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_param.updateTranslation();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addPrimitive(Primitive *p)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		// TODO: aggiungere il controllo per evitare nomi ripetuti
Shinya Kitaoka 9eb50d
		std::wstring name = ::to_wstring(p->getName());
Toshihiro Shimizu 890ddd
		//wstring name = TStringTable::translate(p->getName());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_primitiveTable[name] = p;
Toshihiro Shimizu 890ddd
		m_param.m_type.addValue(name);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	void changeType(std::wstring name)
Toshihiro Shimizu 890ddd
	{
Shinya Kitaoka 3bfa54
		std::map<std::wstring, *="" primitive="">::iterator it = m_primitiveTable.find(name);</std::wstring,>
Toshihiro Shimizu 890ddd
		if (it != m_primitiveTable.end())
Toshihiro Shimizu 890ddd
			m_primitive = it->second;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &p, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		/* m_active = getApplication()->getCurrentObject()->isSpline() ||
Toshihiro Shimizu 890ddd
               (bool) getImage(true);*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_active = touchImage(); // NEEDS to be done even if(m_active), due
Toshihiro Shimizu 890ddd
		if (!m_active)			 // to the HORRIBLE m_frameCreated / m_levelCreated
Toshihiro Shimizu 890ddd
			return;				 // mechanism. touchImage() is the ONLY function
Toshihiro Shimizu 890ddd
								 // resetting them to false...                       >_<
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->leftButtonDown(p, e);
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &p, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_active)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->leftButtonDrag(p, e);
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &p, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_active)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->leftButtonUp(p, e);
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	void leftButtonDoubleClick(const TPointD &p, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_active)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->leftButtonDoubleClick(p, e);
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool keyDown(int key, TUINT32 b, const TPoint &point)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return m_primitive->keyDown(key, point);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onImageChanged()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->onImageChanged();
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void rightButtonDown(const TPointD &p, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->rightButtonDown(p, e);
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &p, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->mouseMove(p, e);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onActivate()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_firstTime) {
Toshihiro Shimizu 890ddd
			m_param.m_toolSize.setValue(GeometricSize);
Toshihiro Shimizu 890ddd
			m_param.m_rasterToolSize.setValue(GeometricRasterSize);
Toshihiro Shimizu 890ddd
			m_param.m_opacity.setValue(GeometricOpacity);
Toshihiro Shimizu 890ddd
			m_param.m_hardness.setValue(GeometricBrushHardness);
Toshihiro Shimizu 890ddd
			m_param.m_selective.setValue(GeometricSelective ? 1 : 0);
Toshihiro Shimizu 890ddd
			m_param.m_autogroup.setValue(GeometricGroupIt ? 1 : 0);
Toshihiro Shimizu 890ddd
			m_param.m_autofill.setValue(GeometricAutofill ? 1 : 0);
Shinya Kitaoka 9eb50d
			std::wstring typeCode = ::to_wstring(GeometricType.getValue());
Toshihiro Shimizu 890ddd
			m_param.m_type.setValue(typeCode);
Shinya Kitaoka 9eb50d
			GeometricType = ::to_string(typeCode);
Toshihiro Shimizu 890ddd
			m_typeCode = typeCode;
Toshihiro Shimizu 890ddd
			changeType(typeCode);
Toshihiro Shimizu 890ddd
			m_param.m_edgeCount.setValue(GeometricEdgeCount);
Toshihiro Shimizu 890ddd
			m_param.m_pencil.setValue(GeometricPencil ? 1 : 0);
Toshihiro Shimizu 890ddd
			m_param.m_capStyle.setIndex(GeometricCapStyle);
Toshihiro Shimizu 890ddd
			m_param.m_joinStyle.setIndex(GeometricJoinStyle);
Toshihiro Shimizu 890ddd
			m_param.m_miterJoinLimit.setValue(GeometricMiterValue);
Toshihiro Shimizu 890ddd
			m_firstTime = false;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*--	ショートカットでいきなりスタート(=onEnterを通らない場合)のとき、
Toshihiro Shimizu 890ddd
			LineToolが反応しないことがある対策 --*/
Toshihiro Shimizu 890ddd
		m_active = (getImage(false) != 0 || Preferences::instance()->isAutoCreateEnabled());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->onActivate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onDeactivate()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->onDeactivate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void onEnter()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_active = getImage(false) != 0;
Toshihiro Shimizu 890ddd
		if (m_active && m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->onEnter();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_primitive)
Toshihiro Shimizu 890ddd
			m_primitive->draw();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getCursorId() const { return ToolCursor::PenCursor; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getColorClass() const { return 1; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPropertyGroup *getProperties(int idx)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return &m_param.m_prop[idx];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	bool onPropertyChanged(std::string propertyName)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		/*---	変更されたPropertyごとに処理を分ける。
Toshihiro Shimizu 890ddd
			注意:m_toolSizeとm_rasterToolSizeは同じName(="Size:")なので、
Toshihiro Shimizu 890ddd
			扱っている画像がラスタかどうかで区別する ---*/
Toshihiro Shimizu 890ddd
		if (propertyName == m_param.m_toolSize.getName()) {
Toshihiro Shimizu 890ddd
			TImageP img = getImage(false);
Toshihiro Shimizu 890ddd
			TToonzImageP ri(img); /*-- ラスタかどうかの判定 --*/
Toshihiro Shimizu 890ddd
			if (ri)
Toshihiro Shimizu 890ddd
				GeometricRasterSize = m_param.m_rasterToolSize.getValue();
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				GeometricSize = m_param.m_toolSize.getValue();
Toshihiro Shimizu 890ddd
		} else if (propertyName == m_param.m_type.getName()) {
Shinya Kitaoka 3bfa54
			std::wstring typeCode = m_param.m_type.getValue();
Shinya Kitaoka 9eb50d
			GeometricType = ::to_string(typeCode);
Toshihiro Shimizu 890ddd
			if (typeCode != m_typeCode) {
Toshihiro Shimizu 890ddd
				m_typeCode = typeCode;
Toshihiro Shimizu 890ddd
				changeType(typeCode);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (propertyName == m_param.m_edgeCount.getName())
Toshihiro Shimizu 890ddd
			GeometricEdgeCount = m_param.m_edgeCount.getValue();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_autogroup.getName()) {
Toshihiro Shimizu 890ddd
			if (!m_param.m_autogroup.getValue()) {
Toshihiro Shimizu 890ddd
				m_param.m_autofill.setValue(false);
Toshihiro Shimizu 890ddd
				//this is ugly: it's needed to refresh the GUI of the toolbar after having set to false the autofill...
Toshihiro Shimizu 890ddd
				TTool::getApplication()->getCurrentTool()->setTool(""); //necessary, otherwise next setTool is ignored...
Toshihiro Shimizu 890ddd
				TTool::getApplication()->getCurrentTool()->setTool(QString::fromStdString(getName()));
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			GeometricGroupIt = m_param.m_autogroup.getValue();
Toshihiro Shimizu 890ddd
		} else if (propertyName == m_param.m_autofill.getName()) {
Toshihiro Shimizu 890ddd
			if (m_param.m_autofill.getValue()) {
Toshihiro Shimizu 890ddd
				m_param.m_autogroup.setValue(true);
Toshihiro Shimizu 890ddd
				//this is ugly: it's needed to refresh the GUI of the toolbar after having set to false the autofill...
Toshihiro Shimizu 890ddd
				TTool::getApplication()->getCurrentTool()->setTool(""); //necessary, otherwise next setTool is ignored...
Toshihiro Shimizu 890ddd
				TTool::getApplication()->getCurrentTool()->setTool(QString::fromStdString(getName()));
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			GeometricGroupIt = m_param.m_autofill.getValue();
Toshihiro Shimizu 890ddd
		} else if (propertyName == m_param.m_selective.getName())
Toshihiro Shimizu 890ddd
			GeometricSelective = m_param.m_selective.getValue();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_pencil.getName())
Toshihiro Shimizu 890ddd
			GeometricPencil = m_param.m_pencil.getValue();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_hardness.getName())
Toshihiro Shimizu 890ddd
			GeometricBrushHardness = m_param.m_hardness.getValue();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_opacity.getName())
Toshihiro Shimizu 890ddd
			GeometricOpacity = m_param.m_opacity.getValue();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_capStyle.getName())
Toshihiro Shimizu 890ddd
			GeometricCapStyle = m_param.m_capStyle.getIndex();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_joinStyle.getName())
Toshihiro Shimizu 890ddd
			GeometricJoinStyle = m_param.m_joinStyle.getIndex();
Toshihiro Shimizu 890ddd
		else if (propertyName == m_param.m_miterJoinLimit.getName())
Toshihiro Shimizu 890ddd
			GeometricMiterValue = m_param.m_miterJoinLimit.getValue();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addStroke()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!m_primitive)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TStroke *stroke = m_primitive->makeStroke();
Toshihiro Shimizu 890ddd
		if (!stroke)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStroke::OutlineOptions &options = stroke->outlineOptions();
Toshihiro Shimizu 890ddd
		options.m_capStyle = m_param.m_capStyle.getIndex();
Toshihiro Shimizu 890ddd
		options.m_joinStyle = m_param.m_joinStyle.getIndex();
Toshihiro Shimizu 890ddd
		options.m_miterUpper = m_param.m_miterJoinLimit.getValue();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TImage *image = getImage(true);
Toshihiro Shimizu 890ddd
		TToonzImageP ti(image);
Toshihiro Shimizu 890ddd
		TVectorImageP vi(image);
Toshihiro Shimizu 890ddd
		TRasterImageP ri(image);
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *sl = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
		TFrameId id = getCurrentFid();
Toshihiro Shimizu 890ddd
		/*-- ToonzImageの場合 --*/
Toshihiro Shimizu 890ddd
		if (ti) {
Toshihiro Shimizu 890ddd
			int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
Toshihiro Shimizu 890ddd
			bool selective = m_param.m_selective.getValue();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			bool filled = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			stroke->setStyle(styleId);
Toshihiro Shimizu 890ddd
			double hardness = m_param.m_hardness.getValue() * 0.01;
Toshihiro Shimizu 890ddd
			TRect savebox;
Toshihiro Shimizu 890ddd
			if (hardness == 1 || m_param.m_pencil.getValue()) {
Toshihiro Shimizu 890ddd
				TUndoManager::manager()->add(new UndoRasterPencil(sl, id, stroke, selective, filled, !m_param.m_pencil.getValue(),
Toshihiro Shimizu 890ddd
																  m_isFrameCreated, m_isLevelCreated, m_primitive->getName()));
Toshihiro Shimizu 890ddd
				savebox = ToonzImageUtils::addInkStroke(ti, stroke, styleId,
Toshihiro Shimizu 890ddd
														selective, filled, TConsts::infiniteRectD, !m_param.m_pencil.getValue());
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				int thickness = m_param.m_rasterToolSize.getValue();
Toshihiro Shimizu 890ddd
				TUndoManager::manager()->add(new CMBluredPrimitiveUndo(sl, id, stroke, thickness, hardness, selective, false,
Toshihiro Shimizu 890ddd
																	   m_isFrameCreated, m_isLevelCreated, m_primitive->getName()));
Toshihiro Shimizu 890ddd
				savebox = drawBluredBrush(ti, stroke, thickness, hardness, selective);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
			delete stroke;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*-- VectorImageの場合 --*/
Toshihiro Shimizu 890ddd
		else if (vi) {
Toshihiro Shimizu 890ddd
			if (TTool::getApplication()->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
				if (!ToolUtils::isJustCreatedSpline(vi.getPointer())) {
Toshihiro Shimizu 890ddd
					m_primitive->setIsPrompting(true);
Toshihiro Shimizu 890ddd
					QString question("Are you sure you want to replace the motion path?");
Toshihiro Shimizu 890ddd
					int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0);
Toshihiro Shimizu 890ddd
					m_primitive->setIsPrompting(false);
Toshihiro Shimizu 890ddd
					if (ret == 2 || ret == 0)
Toshihiro Shimizu 890ddd
						return;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				TUndo *undo = new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
Toshihiro Shimizu 890ddd
				while (vi->getStrokeCount() > 0)
Toshihiro Shimizu 890ddd
					vi->deleteStroke(0);
Toshihiro Shimizu 890ddd
				vi->addStroke(stroke, false);
Toshihiro Shimizu 890ddd
				notifyImageChanged();
Toshihiro Shimizu 890ddd
				TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
Toshihiro Shimizu 890ddd
				if (styleId >= 0)
Toshihiro Shimizu 890ddd
					stroke->setStyle(styleId);
Toshihiro Shimizu 890ddd
				QMutexLocker lock(vi->getMutex());
Shinya Kitaoka 3bfa54
				std::vector<tfilledregioninf> *fillInformation = new std::vector<tfilledregioninf>;</tfilledregioninf></tfilledregioninf>
Toshihiro Shimizu 890ddd
				ImageUtils::getFillingInformationOverlappingArea(vi, *fillInformation, stroke->getBBox());
Toshihiro Shimizu 890ddd
				vi->addStroke(stroke);
Toshihiro Shimizu 890ddd
				TUndoManager::manager()->add(new UndoPencil(vi->getStroke(vi->getStrokeCount() - 1), fillInformation, sl, id,
Toshihiro Shimizu 890ddd
															m_isFrameCreated, m_isLevelCreated,
Toshihiro Shimizu 890ddd
															m_param.m_autogroup.getValue(), m_param.m_autofill.getValue()));
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (m_param.m_autogroup.getValue() && stroke->isSelfLoop()) {
Toshihiro Shimizu 890ddd
				int index = vi->getStrokeCount() - 1;
Toshihiro Shimizu 890ddd
				vi->group(index, 1);
Toshihiro Shimizu 890ddd
				if (m_param.m_autofill.getValue()) {
Toshihiro Shimizu 890ddd
					//to avoid filling other strokes, I enter into the new stroke group
Toshihiro Shimizu 890ddd
					int currentGroup = vi->exitGroup();
Toshihiro Shimizu 890ddd
					vi->enterGroup(index);
Toshihiro Shimizu 890ddd
					vi->selectFill(stroke->getBBox().enlarge(1, 1), 0, stroke->getStyle(), false, true, false);
Toshihiro Shimizu 890ddd
					if (currentGroup != -1)
Toshihiro Shimizu 890ddd
						vi->enterGroup(currentGroup);
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						vi->exitGroup();
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		/*-- RasterImageの場合 --*/
Toshihiro Shimizu 890ddd
		else if (ri) {
Toshihiro Shimizu 890ddd
			int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
Toshihiro Shimizu 890ddd
			stroke->setStyle(styleId);
Toshihiro Shimizu 890ddd
			double opacity = m_param.m_opacity.getValue() * 0.01;
Toshihiro Shimizu 890ddd
			double hardness = m_param.m_hardness.getValue() * 0.01;
Toshihiro Shimizu 890ddd
			TRect savebox;
Toshihiro Shimizu 890ddd
			if (hardness == 1) {
Toshihiro Shimizu 890ddd
				TUndoManager::manager()->add(new UndoFullColorPencil(sl, id, stroke, opacity, true, m_isFrameCreated, m_isLevelCreated));
Toshihiro Shimizu 890ddd
				savebox = TRasterImageUtils::addStroke(ri, stroke, TRectD(), opacity);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				int thickness = m_param.m_rasterToolSize.getValue();
Toshihiro Shimizu 890ddd
				TUndoManager::manager()->add(new FullColorBluredPrimitiveUndo(sl, id, stroke, thickness,
Toshihiro Shimizu 890ddd
																			  hardness, opacity, true, m_isFrameCreated, m_isLevelCreated));
Toshihiro Shimizu 890ddd
				savebox = drawBluredBrush(ri, stroke, thickness, hardness, opacity);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
			delete stroke;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		notifyImageChanged();
Toshihiro Shimizu 890ddd
		m_active = false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
GeometricTool GeometricVectorTool(TTool::Vectors | TTool::EmptyTarget);
Toshihiro Shimizu 890ddd
GeometricTool GeometricRasterTool(TTool::ToonzImage | TTool::EmptyTarget);
Toshihiro Shimizu 890ddd
GeometricTool GeometricRasterFullColorTool(TTool::RasterImage | TTool::EmptyTarget);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Rectangle Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectanglePrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_isEditing || m_isPrompting ||
Toshihiro Shimizu 890ddd
		areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Toshihiro Shimizu 890ddd
		areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1)) {
Toshihiro Shimizu 890ddd
		tglColor(m_isEditing ? m_color : TPixel32::Green);
Toshihiro Shimizu 890ddd
		glBegin(GL_LINE_LOOP);
Toshihiro Shimizu 890ddd
		tglVertex(m_selectingRect.getP00());
Toshihiro Shimizu 890ddd
		tglVertex(m_selectingRect.getP01());
Toshihiro Shimizu 890ddd
		tglVertex(m_selectingRect.getP11());
Toshihiro Shimizu 890ddd
		tglVertex(m_selectingRect.getP10());
Toshihiro Shimizu 890ddd
		glEnd();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectanglePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
		m_isEditing = true;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		//app->getCurrentTool()->getTool()->touchImage();
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		m_isEditing = style != 0 && style->isStrokeStyle();
Toshihiro Shimizu 890ddd
		m_color = (style) ? style->getAverageColor() : TPixel32::Black;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_param->m_pencil.getValue() &&
Toshihiro Shimizu 890ddd
		(m_param->m_targetType & TTool::ToonzImage || m_param->m_targetType & TTool::RasterImage)) {
Toshihiro Shimizu 890ddd
		if (m_param->m_rasterToolSize.getValue() % 2 != 0)
Toshihiro Shimizu 890ddd
			m_startPoint = TPointD((int)pos.x, (int)pos.y);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			m_startPoint = TPointD((int)pos.x + 0.5, (int)pos.y + 0.5);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_startPoint = pos;
Toshihiro Shimizu 890ddd
	m_selectingRect.x0 = m_startPoint.x;
Toshihiro Shimizu 890ddd
	m_selectingRect.y0 = m_startPoint.y;
Toshihiro Shimizu 890ddd
	m_selectingRect.x1 = m_startPoint.x;
Toshihiro Shimizu 890ddd
	m_selectingRect.y1 = m_startPoint.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectanglePrimitive::leftButtonDrag(const TPointD &realPos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD pos;
Toshihiro Shimizu 890ddd
	if (e.isShiftPressed()) {
Shinya Kitaoka ee259f
		double distance = tdistance(realPos, m_startPoint) * M_SQRT1_2;
Toshihiro Shimizu 890ddd
		pos.x = (realPos.x > m_startPoint.x) ? m_startPoint.x + distance
Toshihiro Shimizu 890ddd
											 : m_startPoint.x - distance;
Toshihiro Shimizu 890ddd
		pos.y = (realPos.y > m_startPoint.y) ? m_startPoint.y + distance
Toshihiro Shimizu 890ddd
											 : m_startPoint.y - distance;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		pos = realPos;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_param->m_pencil.getValue() &&
Toshihiro Shimizu 890ddd
		(m_param->m_targetType & TTool::ToonzImage || m_param->m_targetType & TTool::RasterImage)) {
Toshihiro Shimizu 890ddd
		if (m_param->m_rasterToolSize.getValue() % 2 != 0)
Toshihiro Shimizu 890ddd
			pos = TPointD((int)pos.x, (int)pos.y);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			pos = TPointD((int)pos.x + 0.5, (int)pos.y + 0.5);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_selectingRect.x1 = pos.x;
Toshihiro Shimizu 890ddd
	m_selectingRect.y1 = pos.y;
Toshihiro Shimizu 890ddd
	if (!e.isAltPressed()) {
Toshihiro Shimizu 890ddd
		m_selectingRect.x0 = m_startPoint.x;
Toshihiro Shimizu 890ddd
		m_selectingRect.y0 = m_startPoint.y;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		m_selectingRect.x0 = m_startPoint.x + m_startPoint.x - pos.x;
Toshihiro Shimizu 890ddd
		m_selectingRect.y0 = m_startPoint.y + m_startPoint.y - pos.y;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *RectanglePrimitive::makeStroke() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Toshihiro Shimizu 890ddd
		areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1))
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD selArea;
Shinya Kitaoka 12c444
	selArea.x0 = std::min(m_selectingRect.x0, m_selectingRect.x1);
Shinya Kitaoka 12c444
	selArea.y0 = std::min(m_selectingRect.y0, m_selectingRect.y1);
Shinya Kitaoka 12c444
	selArea.x1 = std::max(m_selectingRect.x0, m_selectingRect.x1);
Shinya Kitaoka 12c444
	selArea.y1 = std::max(m_selectingRect.y0, m_selectingRect.y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double thick = getThickness();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = 0;
Toshihiro Shimizu 890ddd
	if (m_param->m_targetType & TTool::Vectors) {
Shinya Kitaoka 3bfa54
		std::vector<tthickpoint> points(17);</tthickpoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[0] = TThickPoint(selArea.x1, selArea.y1, thick);
Toshihiro Shimizu 890ddd
		points[1] = TThickPoint(selArea.x1, selArea.y1, thick) + TPointD(-0.01, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[3] = TThickPoint(selArea.x0, selArea.y1, thick) + TPointD(0.01, 0);
Toshihiro Shimizu 890ddd
		points[4] = TThickPoint(selArea.x0, selArea.y1, thick);
Toshihiro Shimizu 890ddd
		points[5] = TThickPoint(selArea.x0, selArea.y1, thick) + TPointD(0, -0.01);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[7] = TThickPoint(selArea.x0, selArea.y0, thick) + TPointD(0, 0.01);
Toshihiro Shimizu 890ddd
		points[8] = TThickPoint(selArea.x0, selArea.y0, thick);
Toshihiro Shimizu 890ddd
		points[9] = TThickPoint(selArea.x0, selArea.y0, thick) + TPointD(0.01, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[11] = TThickPoint(selArea.x1, selArea.y0, thick) + TPointD(-0.01, 0);
Toshihiro Shimizu 890ddd
		points[12] = TThickPoint(selArea.x1, selArea.y0, thick);
Toshihiro Shimizu 890ddd
		points[13] = TThickPoint(selArea.x1, selArea.y0, thick) + TPointD(0, 0.01);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[15] = points[0] + TPointD(0, -0.01);
Toshihiro Shimizu 890ddd
		points[16] = points[0];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[2] = 0.5 * (points[1] + points[3]);
Toshihiro Shimizu 890ddd
		points[6] = 0.5 * (points[5] + points[7]);
Toshihiro Shimizu 890ddd
		points[10] = 0.5 * (points[9] + points[11]);
Toshihiro Shimizu 890ddd
		points[14] = 0.5 * (points[13] + points[15]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
	} else if (m_param->m_targetType & TTool::ToonzImage || m_param->m_targetType & TTool::RasterImage) {
Shinya Kitaoka 3bfa54
		std::vector<tthickpoint> points(9);</tthickpoint>
Toshihiro Shimizu 890ddd
		double middleX = (selArea.x0 + selArea.x1) * 0.5;
Toshihiro Shimizu 890ddd
		double middleY = (selArea.y0 + selArea.y1) * 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[0] = TThickPoint(selArea.x1, selArea.y1, thick);
Toshihiro Shimizu 890ddd
		points[1] = TThickPoint(middleX, selArea.y1, thick);
Toshihiro Shimizu 890ddd
		points[2] = TThickPoint(selArea.x0, selArea.y1, thick);
Toshihiro Shimizu 890ddd
		points[3] = TThickPoint(selArea.x0, middleY, thick);
Toshihiro Shimizu 890ddd
		points[4] = TThickPoint(selArea.x0, selArea.y0, thick);
Toshihiro Shimizu 890ddd
		points[5] = TThickPoint(middleX, selArea.y0, thick);
Toshihiro Shimizu 890ddd
		points[6] = TThickPoint(selArea.x1, selArea.y0, thick);
Toshihiro Shimizu 890ddd
		points[7] = TThickPoint(selArea.x1, middleY, thick);
Toshihiro Shimizu 890ddd
		points[8] = points[0];
Toshihiro Shimizu 890ddd
		stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop();
Toshihiro Shimizu 890ddd
	return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectanglePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
	m_tool->addStroke();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectanglePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectanglePrimitive::onEnter()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style)
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Circle Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CirclePrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_isEditing || m_isPrompting) {
Toshihiro Shimizu 890ddd
		tglColor(m_isEditing ? m_color : TPixel32::Green);
Toshihiro Shimizu 890ddd
		tglDrawCircle(m_centre, m_radius);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CirclePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
	m_centre = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
		m_isEditing = true;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style) {
Toshihiro Shimizu 890ddd
			m_isEditing = style->isStrokeStyle();
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_isEditing = false;
Toshihiro Shimizu 890ddd
			m_color = TPixel32::Black;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CirclePrimitive::leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
	m_radius = tdistance(m_centre, pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *CirclePrimitive::makeStroke() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return makeEllipticStroke(getThickness(), m_centre, m_radius, m_radius);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CirclePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
	if (isAlmostZero(m_radius))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_tool->addStroke();
Toshihiro Shimizu 890ddd
	m_radius = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CirclePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CirclePrimitive::onEnter()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style)
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MultiLine Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::addVertex(const TPointD &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int count = m_vertex.size();
Toshihiro Shimizu 890ddd
	//Inserisco il primo punto
Toshihiro Shimizu 890ddd
	if (count == 0) {
Toshihiro Shimizu 890ddd
		m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD &vertex = m_vertex[count - 1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Caso particolare in cui inizio una curva e la chiudo subito cliccando sul punto di pertenza
Toshihiro Shimizu 890ddd
	if (count == 1 && pos == vertex) {
Toshihiro Shimizu 890ddd
		m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
		m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
		m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Calcolo lo speedOut
Toshihiro Shimizu 890ddd
	TPointD speedOutPoint;
Toshihiro Shimizu 890ddd
	if (!m_speedMoved) //Se non e' stato mosso lo speedOut devo calcolarlo e inserirlo
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		speedOutPoint = vertex + computeSpeed(vertex, pos, 0.01);
Toshihiro Shimizu 890ddd
		m_vertex.push_back(speedOutPoint);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if (m_ctrlDown)
Toshihiro Shimizu 890ddd
			vertex = m_vertex[count - 2] + computeSpeed(m_vertex[count - 2], pos, 0.01);
Toshihiro Shimizu 890ddd
		speedOutPoint = vertex;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Calcolo lo speedIn
Toshihiro Shimizu 890ddd
	TPointD speedInPoint = pos + computeSpeed(pos, speedOutPoint, 0.01);
Toshihiro Shimizu 890ddd
	//Calcolo il "punto di mezzo" e lo inserisco
Toshihiro Shimizu 890ddd
	TPointD middlePoint = 0.5 * (speedInPoint + speedOutPoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Inserisco il "punto di mezzo"
Toshihiro Shimizu 890ddd
	m_vertex.push_back(middlePoint);
Toshihiro Shimizu 890ddd
	//Inserisco lo speedIn
Toshihiro Shimizu 890ddd
	m_vertex.push_back(speedInPoint);
Toshihiro Shimizu 890ddd
	//Inserisco il nuovo punto
Toshihiro Shimizu 890ddd
	m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::moveSpeed(const TPointD &delta)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int count = m_vertex.size();
Toshihiro Shimizu 890ddd
	assert(count > 0);
Toshihiro Shimizu 890ddd
	TPointD lastPoint = m_vertex[count - 1];
Toshihiro Shimizu 890ddd
	TPointD newSpeedOutPoint = lastPoint - delta;
Toshihiro Shimizu 890ddd
	if (m_speedMoved)
Toshihiro Shimizu 890ddd
		m_vertex[count - 1] = newSpeedOutPoint;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		m_vertex.push_back(newSpeedOutPoint);
Toshihiro Shimizu 890ddd
		++count;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (count < 5) {
Toshihiro Shimizu 890ddd
		assert(count == 2);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD vertex = m_vertex[count - 2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD v(0, 0);
Toshihiro Shimizu 890ddd
	if (newSpeedOutPoint != vertex)
Toshihiro Shimizu 890ddd
		v = normalize(newSpeedOutPoint - vertex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double speedOut = tdistance(newSpeedOutPoint, vertex);
Toshihiro Shimizu 890ddd
	TPointD newSpeedInPoint = vertex - TPointD(speedOut * v.x, speedOut * v.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_vertex[count - 3] = newSpeedInPoint;
Toshihiro Shimizu 890ddd
	if (tdistance(m_vertex[count - 5], m_vertex[count - 6]) <= 0.02)
Toshihiro Shimizu 890ddd
		//see ControlPointEditorStroke::isSpeedOutLinear() from controlpointselection.cpp
Toshihiro Shimizu 890ddd
		m_vertex[count - 5] = m_vertex[count - 6] + computeSpeed(m_vertex[count - 6], m_vertex[count - 3], 0.01);
Toshihiro Shimizu 890ddd
	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
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT size = m_vertex.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((m_isEditing || m_isPrompting) && size > 0) {
Toshihiro Shimizu 890ddd
		tglColor(m_isEditing ? m_color : TPixel32::Green);
Toshihiro Shimizu 890ddd
		std::vector<tpointd> points;</tpointd>
Toshihiro Shimizu 890ddd
		points.assign(m_vertex.begin(), m_vertex.end());
Toshihiro Shimizu 890ddd
		int count = points.size();
Toshihiro Shimizu 890ddd
		if (count % 4 == 1) {
Toshihiro Shimizu 890ddd
			//No speedOut
Toshihiro Shimizu 890ddd
			points.push_back(points[count - 1]);
Toshihiro Shimizu 890ddd
			count++;
Toshihiro Shimizu 890ddd
		} else if (m_ctrlDown)
Toshihiro Shimizu 890ddd
			points[count - 1] = points[count - 2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points.push_back(0.5 * (m_mousePosition + points[count - 1]));
Toshihiro Shimizu 890ddd
		points.push_back(m_mousePosition);
Toshihiro Shimizu 890ddd
		points.push_back(m_mousePosition);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double pixelSize = m_tool->getPixelSize();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStroke *stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
		drawStrokeCenterline(*stroke, pixelSize);
Toshihiro Shimizu 890ddd
		delete stroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_vertex.size() > 1) {
Toshihiro Shimizu 890ddd
			tglColor(TPixel(79, 128, 255));
Toshihiro Shimizu 890ddd
			int index = (count < 5) ? count - 1 : count - 5;
Toshihiro Shimizu 890ddd
			//Disegno lo speedOut precedente (che e' quello corrente solo nel caso in cui count < 5)
Toshihiro Shimizu 890ddd
			TPointD p0 = m_vertex[index];
Toshihiro Shimizu 890ddd
			TPointD p1 = m_vertex[index - 1];
Toshihiro Shimizu 890ddd
			if (tdistance(p0, p1) > 0.1) {
Toshihiro Shimizu 890ddd
				tglDrawSegment(p0, p1);
Toshihiro Shimizu 890ddd
				tglDrawDisk(p0, 2 * pixelSize);
Toshihiro Shimizu 890ddd
				tglDrawDisk(p1, 4 * pixelSize);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			//Disegno lo speedIn/Out corrente nel caso in cui count > 5
Toshihiro Shimizu 890ddd
			if (m_speedMoved && count > 5) {
Toshihiro Shimizu 890ddd
				TPointD p0 = m_vertex[count - 1];
Toshihiro Shimizu 890ddd
				TPointD p1 = m_vertex[count - 2];
Toshihiro Shimizu 890ddd
				TPointD p2 = m_vertex[count - 3];
Toshihiro Shimizu 890ddd
				tglDrawSegment(p0, p2);
Toshihiro Shimizu 890ddd
				tglDrawDisk(p0, 2 * pixelSize);
Toshihiro Shimizu 890ddd
				tglDrawDisk(p1, 4 * pixelSize);
Toshihiro Shimizu 890ddd
				tglDrawDisk(p2, 2 * pixelSize);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_closed)
Toshihiro Shimizu 890ddd
			tglColor(TPixel32((m_color.r + 127) % 255, m_color.g, (m_color.b + 127) % 255, m_color.m));
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			tglColor(m_color);
Toshihiro Shimizu 890ddd
		tglDrawCircle(m_vertex[0], joinDistance * pixelSize);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
		m_isEditing = true;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style) {
Toshihiro Shimizu 890ddd
			m_isEditing = style->isStrokeStyle();
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_isEditing = false;
Toshihiro Shimizu 890ddd
			m_color = TPixel32::Black;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_undo = new MultilinePrimitiveUndo(m_vertex, this);
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(m_undo);
Toshihiro Shimizu 890ddd
	m_mousePosition = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Se clicco nell'ultimo vertice chiudo la linea.
Toshihiro Shimizu 890ddd
	TPointD _pos = pos;
Toshihiro Shimizu 890ddd
	if (m_closed)
Toshihiro Shimizu 890ddd
		_pos = m_vertex.front();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (e.isShiftPressed() && !m_vertex.empty())
Toshihiro Shimizu 890ddd
		addVertex(rectify(m_vertex.back(), _pos));
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		addVertex(_pos);
Toshihiro Shimizu 890ddd
	m_undo->setNewVertex(m_vertex);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_beforeSpeedMoved = m_speedMoved;
Toshihiro Shimizu 890ddd
	m_speedMoved = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_vertex.size() == 0 || m_isSingleLine)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_speedMoved || tdistance2(m_vertex[m_vertex.size() - 1], pos) > sq(7.0 * m_tool->getPixelSize())) {
Toshihiro Shimizu 890ddd
		moveSpeed(m_mousePosition - pos);
Toshihiro Shimizu 890ddd
		m_speedMoved = true;
Toshihiro Shimizu 890ddd
		m_undo->setNewVertex(m_vertex);
Toshihiro Shimizu 890ddd
		m_mousePosition = pos;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::leftButtonDoubleClick(const TPointD &, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	endLine();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_closed)
Toshihiro Shimizu 890ddd
		endLine();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_ctrlDown = e.isCtrlPressed();
Toshihiro Shimizu 890ddd
	if (m_isEditing) {
Toshihiro Shimizu 890ddd
		if (e.isShiftPressed() && !m_vertex.empty())
Toshihiro Shimizu 890ddd
			m_mousePosition = rectify(m_vertex.back(), pos);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			m_mousePosition = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double dist = joinDistance * joinDistance;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!m_vertex.empty() && (tdistance2(m_mousePosition, m_vertex.front()) < dist * m_tool->getPixelSize())) {
Toshihiro Shimizu 890ddd
			m_closed = true;
Toshihiro Shimizu 890ddd
			m_mousePosition = m_vertex.front();
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			m_closed = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_mousePosition = pos;
Toshihiro Shimizu 890ddd
	m_tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool MultiLinePrimitive::keyDown(int key, const TPoint &point)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (key != TwConsts::TK_Esc || !m_isEditing)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT size = m_vertex.size();
Toshihiro Shimizu 890ddd
	if (size <= 1)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isSingleLine)
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->popUndo((size - 1) / 4 + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
	m_speedMoved = false;
Toshihiro Shimizu 890ddd
	m_beforeSpeedMoved = false;
Toshihiro Shimizu 890ddd
	m_closed = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_vertex.clear();
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *MultiLinePrimitive::makeStroke() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double thick = getThickness();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*--- Pencilの場合は、線幅を減らす。Thickness1の線を1ピクセルにするため。(thick = 0 になる)---*/
Toshihiro Shimizu 890ddd
	if (m_param->m_pencil.getValue())
Toshihiro Shimizu 890ddd
		thick -= 1.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT size = m_vertex.size();
Toshihiro Shimizu 890ddd
	if (size <= 1)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isSingleLine)
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->popUndo((size - 1) / 4 + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = 0;
Shinya Kitaoka 3bfa54
	std::vector<tthickpoint> points;</tthickpoint>
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)size; i++) {
Toshihiro Shimizu 890ddd
		TPointD vertex = m_vertex[i];
Toshihiro Shimizu 890ddd
		points.push_back(TThickPoint(vertex, thick));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
	if (m_closed)
Toshihiro Shimizu 890ddd
		stroke->setSelfLoop();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::endLine()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
	m_speedMoved = false;
Toshihiro Shimizu 890ddd
	m_beforeSpeedMoved = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isSingleLine && !m_vertex.empty() && m_vertex.size() % 4 != 1 /* && !m_rasterTool*/) {
Toshihiro Shimizu 890ddd
		m_vertex.erase(--m_vertex.end());
Toshihiro Shimizu 890ddd
		assert(m_vertex.size() == 3 || m_vertex.size() % 4 == 1);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_tool->addStroke();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_closed)
Toshihiro Shimizu 890ddd
		m_closed = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_vertex.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::onActivate()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
	m_closed = false;
Toshihiro Shimizu 890ddd
	m_vertex.clear();
Toshihiro Shimizu 890ddd
	m_speedMoved = false;
Toshihiro Shimizu 890ddd
	m_beforeSpeedMoved = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::onEnter()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style)
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MultiLinePrimitive::onImageChanged()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	onActivate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Line Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void LinePrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT size = m_vertex.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tglColor(TPixel32::Red);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_isEditing || m_isPrompting) {
Toshihiro Shimizu 890ddd
		glBegin(GL_LINE_STRIP);
Toshihiro Shimizu 890ddd
		tglVertex(m_vertex[0]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		tglVertex(m_mousePosition);
Toshihiro Shimizu 890ddd
		glEnd();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void LinePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
		m_isEditing = true;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style) {
Toshihiro Shimizu 890ddd
			m_isEditing = style->isStrokeStyle();
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_isEditing = false;
Toshihiro Shimizu 890ddd
			m_color = TPixel32::Black;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_mousePosition = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD _pos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_param->m_pencil.getValue() &&
Toshihiro Shimizu 890ddd
		(m_param->m_targetType & TTool::ToonzImage || m_param->m_targetType & TTool::RasterImage)) {
Toshihiro Shimizu 890ddd
		if (m_param->m_rasterToolSize.getValue() % 2 != 0)
Toshihiro Shimizu 890ddd
			_pos = TPointD((int)pos.x, (int)pos.y);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			_pos = TPointD((int)pos.x + 0.5, (int)pos.y + 0.5);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_vertex.size() == 0)
Toshihiro Shimizu 890ddd
		addVertex(_pos);
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		if (e.isShiftPressed() && !m_vertex.empty())
Toshihiro Shimizu 890ddd
			addVertex(rectify(m_vertex.back(), _pos));
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			addVertex(_pos);
Toshihiro Shimizu 890ddd
		endLine();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void LinePrimitive::leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_mousePosition = pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void LinePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_mousePosition = pos;
Toshihiro Shimizu 890ddd
	if (e.isShiftPressed() && !m_vertex.empty())
Toshihiro Shimizu 890ddd
		m_vertex.push_back(rectify(m_vertex.back(), pos));
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_vertex.push_back(pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	endLine();
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
Toshihiro Shimizu 890ddd
void EllipsePrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_isEditing || m_isPrompting ||
Toshihiro Shimizu 890ddd
		areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Toshihiro Shimizu 890ddd
		areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1)) {
Toshihiro Shimizu 890ddd
		tglColor(m_isEditing ? m_color : TPixel32::Green);
Toshihiro Shimizu 890ddd
		TPointD centre = TPointD((m_selectingRect.x0 + m_selectingRect.x1) * 0.5,
Toshihiro Shimizu 890ddd
								 (m_selectingRect.y0 + m_selectingRect.y1) * 0.5);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		glPushMatrix();
Toshihiro Shimizu 890ddd
		tglMultMatrix(TScale(centre, m_selectingRect.x1 - m_selectingRect.x0, m_selectingRect.y1 - m_selectingRect.y0));
Toshihiro Shimizu 890ddd
		tglDrawCircle(centre, 0.5);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		glPopMatrix();
Toshihiro Shimizu 890ddd
		drawRect(m_selectingRect, m_color, 0x5555, true);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void EllipsePrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_startPoint = pos;
Toshihiro Shimizu 890ddd
	m_selectingRect.x0 = pos.x;
Toshihiro Shimizu 890ddd
	m_selectingRect.y0 = pos.y;
Toshihiro Shimizu 890ddd
	m_selectingRect.x1 = pos.x;
Toshihiro Shimizu 890ddd
	m_selectingRect.y1 = pos.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_isEditing = true;
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style) {
Toshihiro Shimizu 890ddd
			m_isEditing = style->isStrokeStyle();
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_isEditing = false;
Toshihiro Shimizu 890ddd
			m_color = TPixel32::Black;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void EllipsePrimitive::leftButtonDrag(const TPointD &realPos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD pos;
Toshihiro Shimizu 890ddd
	if (e.isShiftPressed()) {
Shinya Kitaoka ee259f
		double distance = tdistance(realPos, m_startPoint) * M_SQRT1_2;
Toshihiro Shimizu 890ddd
		pos.x = (realPos.x > m_startPoint.x) ? m_startPoint.x + distance : m_startPoint.x - distance;
Toshihiro Shimizu 890ddd
		pos.y = (realPos.y > m_startPoint.y) ? m_startPoint.y + distance : m_startPoint.y - distance;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		pos = realPos;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_selectingRect.x1 = pos.x;
Toshihiro Shimizu 890ddd
	m_selectingRect.y1 = pos.y;
Toshihiro Shimizu 890ddd
	if (!e.isAltPressed()) {
Toshihiro Shimizu 890ddd
		m_selectingRect.x0 = m_startPoint.x;
Toshihiro Shimizu 890ddd
		m_selectingRect.y0 = m_startPoint.y;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		m_selectingRect.x0 = m_startPoint.x + m_startPoint.x - pos.x;
Toshihiro Shimizu 890ddd
		m_selectingRect.y0 = m_startPoint.y + m_startPoint.y - pos.y;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *EllipsePrimitive::makeStroke() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (areAlmostEqual(m_selectingRect.x0, m_selectingRect.x1) ||
Toshihiro Shimizu 890ddd
		areAlmostEqual(m_selectingRect.y0, m_selectingRect.y1))
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return makeEllipticStroke(getThickness(),
Toshihiro Shimizu 890ddd
							  TPointD(0.5 * (m_selectingRect.x0 + m_selectingRect.x1),
Toshihiro Shimizu 890ddd
									  0.5 * (m_selectingRect.y0 + m_selectingRect.y1)),
Toshihiro Shimizu 890ddd
							  fabs(0.5 * (m_selectingRect.x1 - m_selectingRect.x0)),
Toshihiro Shimizu 890ddd
							  fabs(0.5 * (m_selectingRect.y1 - m_selectingRect.y0)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void EllipsePrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_tool->addStroke();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void EllipsePrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pos = pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void EllipsePrimitive::onEnter()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style)
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Arc Primitive Class Implementation
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ArcPrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (m_clickNumber) {
Toshihiro Shimizu 890ddd
	case 1:
Toshihiro Shimizu 890ddd
		tglColor(m_color);
Toshihiro Shimizu 890ddd
		tglDrawSegment(m_startPoint, m_endPoint);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 2:
Toshihiro Shimizu 890ddd
		assert(m_stroke);
Toshihiro Shimizu 890ddd
		if (m_stroke) {
Toshihiro Shimizu 890ddd
			tglColor(m_isPrompting ? TPixel32::Green : m_color);
Toshihiro Shimizu 890ddd
			if (!m_isPrompting) {
Toshihiro Shimizu 890ddd
				glLineStipple(1, 0x5555);
Toshihiro Shimizu 890ddd
				glEnable(GL_LINE_STIPPLE);
Toshihiro Shimizu 890ddd
				glBegin(GL_LINE_STRIP);
Toshihiro Shimizu 890ddd
				tglVertex(m_stroke->getControlPoint(0));
Toshihiro Shimizu 890ddd
				tglVertex(m_centralPoint);
Toshihiro Shimizu 890ddd
				tglVertex(m_stroke->getControlPoint(8));
Toshihiro Shimizu 890ddd
				glEnd();
Toshihiro Shimizu 890ddd
				glDisable(GL_LINE_STIPPLE);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			drawStrokeCenterline(*m_stroke, sqrt(tglGetPixelSize2()));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *ArcPrimitive::makeStroke() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return new TStroke(*m_stroke);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ArcPrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::vector<tthickpoint> points(9);</tthickpoint>
Toshihiro Shimizu 890ddd
	double thick = getThickness();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (m_clickNumber) {
Toshihiro Shimizu 890ddd
	case 0:
Toshihiro Shimizu 890ddd
		if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
			m_isEditing = true;
Toshihiro Shimizu 890ddd
			m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
			if (style) {
Toshihiro Shimizu 890ddd
				m_isEditing = style->isStrokeStyle();
Toshihiro Shimizu 890ddd
				m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				m_isEditing = false;
Toshihiro Shimizu 890ddd
				m_color = TPixel32::Black;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!m_isEditing)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_endPoint = m_startPoint = pos;
Toshihiro Shimizu 890ddd
		m_clickNumber++;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case 1:
Toshihiro Shimizu 890ddd
		points[0] = TThickPoint(m_startPoint, thick);
Toshihiro Shimizu 890ddd
		points[8] = TThickPoint(pos, thick);
Toshihiro Shimizu 890ddd
		points[4] = TThickPoint(0.5 * (points[0] + points[8]), thick);
Toshihiro Shimizu 890ddd
		points[2] = TThickPoint(0.5 * (points[0] + points[4]), thick);
Toshihiro Shimizu 890ddd
		points[6] = TThickPoint(0.5 * (points[4] + points[8]), thick);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		points[1] = TThickPoint(0.5 * (points[0] + points[2]), thick);
Toshihiro Shimizu 890ddd
		points[3] = TThickPoint(0.5 * (points[2] + points[4]), thick);
Toshihiro Shimizu 890ddd
		points[5] = TThickPoint(0.5 * (points[4] + points[6]), thick);
Toshihiro Shimizu 890ddd
		points[7] = TThickPoint(0.5 * (points[6] + points[8]), thick);
Toshihiro Shimizu 890ddd
		if (m_stroke)
Toshihiro Shimizu 890ddd
			delete m_stroke;
Toshihiro Shimizu 890ddd
		m_stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
		m_clickNumber++;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case 2:
Toshihiro Shimizu 890ddd
		m_tool->addStroke();
Toshihiro Shimizu 890ddd
		m_stroke = 0;
Toshihiro Shimizu 890ddd
		m_clickNumber = 0;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ArcPrimitive::mouseMove(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	switch (m_clickNumber) {
Toshihiro Shimizu 890ddd
	case 1:
Toshihiro Shimizu 890ddd
		if (e.isShiftPressed())
Toshihiro Shimizu 890ddd
			m_endPoint = rectify(m_startPoint, pos);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			m_endPoint = pos;
Toshihiro Shimizu 890ddd
		m_tool->invalidate();
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 2:
Toshihiro Shimizu 890ddd
		m_centralPoint = TThickPoint(pos, getThickness());
Toshihiro Shimizu 890ddd
		TThickQuadratic q(m_stroke->getControlPoint(0),
Toshihiro Shimizu 890ddd
						  m_centralPoint,
Toshihiro Shimizu 890ddd
						  m_stroke->getControlPoint(8));
Toshihiro Shimizu 890ddd
		TThickQuadratic q0, q1, q00, q01, q10, q11;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		q.split(0.5, q0, q1);
Toshihiro Shimizu 890ddd
		q0.split(0.5, q00, q01);
Toshihiro Shimizu 890ddd
		q1.split(0.5, q10, q11);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(q00.getP2() == q01.getP0());
Toshihiro Shimizu 890ddd
		assert(q01.getP2() == q10.getP0());
Toshihiro Shimizu 890ddd
		assert(q10.getP2() == q11.getP0());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(0, q00.getP0());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(1, q00.getP1());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(2, q00.getP2());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(3, q01.getP1());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(4, q01.getP2());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(5, q10.getP1());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(6, q10.getP2());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(7, q11.getP1());
Toshihiro Shimizu 890ddd
		m_stroke->setControlPoint(8, q11.getP2());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_tool->invalidate();
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ArcPrimitive::onEnter()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style)
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Polygon Primitive Class Declaration
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PolygonPrimitive::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing && !m_isPrompting)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	tglColor(m_isEditing ? m_color : TPixel32::Green);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
	int edgeCount = m_param->m_edgeCount.getValue();
Toshihiro Shimizu 890ddd
	if (edgeCount == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka ee259f
	double angleDiff = M_2PI / edgeCount;
Shinya Kitaoka ee259f
	double angle = (3 * M_PI + angleDiff) * 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glBegin(GL_LINE_LOOP);
Toshihiro Shimizu 890ddd
	for (int i = 0; i < edgeCount; i++) {
Toshihiro Shimizu 890ddd
		tglVertex(m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius));
Toshihiro Shimizu 890ddd
		angle += angleDiff;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PolygonPrimitive::leftButtonDown(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (app->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		m_isEditing = true;
Toshihiro Shimizu 890ddd
		m_color = TPixel32::Red;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		const TColorStyle *style = app->getCurrentLevelStyle();
Toshihiro Shimizu 890ddd
		if (style) {
Toshihiro Shimizu 890ddd
			m_isEditing = style->isStrokeStyle();
Toshihiro Shimizu 890ddd
			m_color = style->getAverageColor();
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_isEditing = false;
Toshihiro Shimizu 890ddd
			m_color = TPixel32::Black;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_centre = pos;
Toshihiro Shimizu 890ddd
	m_radius = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PolygonPrimitive::leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_radius = tdistance(m_centre, pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *PolygonPrimitive::makeStroke() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double thick = getThickness();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
	int edgeCount = m_param->m_edgeCount.getValue();
Toshihiro Shimizu 890ddd
	if (edgeCount == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka ee259f
	double angleDiff = M_2PI / (double)edgeCount;
Shinya Kitaoka ee259f
	double angle = (3 * M_PI + angleDiff) * 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = 0;
Toshihiro Shimizu 890ddd
	if (m_param->m_targetType & TTool::Vectors) {
Shinya Kitaoka 3bfa54
		std::vector<tthickpoint> points(4 * edgeCount + 1);</tthickpoint>
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		//Posiziono gli angoli
Toshihiro Shimizu 890ddd
		for (i = 0; i <= (int)points.size(); i += 4) {
Toshihiro Shimizu 890ddd
			points[i] = TThickPoint(m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius), thick);
Toshihiro Shimizu 890ddd
			angle += angleDiff;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		//posiziono i punti medi e i punti per gestire la linearita'
Toshihiro Shimizu 890ddd
		for (i = 0; i < (int)points.size() - 1; i += 4) {
Toshihiro Shimizu 890ddd
			TPointD vertex = convert(points[i]);
Toshihiro Shimizu 890ddd
			TPointD nextVertex = convert(points[i + 4]);
Toshihiro Shimizu 890ddd
			TPointD speed = computeSpeed(vertex, nextVertex, 0.01);
Toshihiro Shimizu 890ddd
			TPointD speedOutPoint = vertex + speed;
Toshihiro Shimizu 890ddd
			TPointD speedInNextPoint = nextVertex - speed;
Toshihiro Shimizu 890ddd
			TPointD middlePoint = 0.5 * (speedOutPoint + speedInNextPoint);
Toshihiro Shimizu 890ddd
			points[i + 1] = TThickPoint(speedOutPoint, thick);
Toshihiro Shimizu 890ddd
			points[i + 2] = TThickPoint(middlePoint, thick);
Toshihiro Shimizu 890ddd
			points[i + 3] = TThickPoint(speedInNextPoint, thick);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
	} else if (m_param->m_targetType & TTool::ToonzImage || m_param->m_targetType & TTool::RasterImage) {
Shinya Kitaoka 3bfa54
		std::vector<tthickpoint> points(edgeCount + edgeCount + 1);</tthickpoint>
Toshihiro Shimizu 890ddd
		points[0] = TThickPoint(m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius), thick);
Toshihiro Shimizu 890ddd
		for (int i = 1; i <= edgeCount; i++) {
Toshihiro Shimizu 890ddd
			angle += angleDiff;
Toshihiro Shimizu 890ddd
			points[i + i] = TThickPoint(m_centre + TPointD(cos(angle) * m_radius, sin(angle) * m_radius), thick);
Toshihiro Shimizu 890ddd
			points[i + i - 1] = (points[i + i - 2] + points[i + i]) * 0.5;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		stroke = new TStroke(points);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop();
Toshihiro Shimizu 890ddd
	return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PolygonPrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_isEditing)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_isEditing = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_tool->addStroke();
Toshihiro Shimizu 890ddd
}