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