Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/imagemanager.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectspline.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/trasterimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelset.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/icongenerator.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/selection.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/strokeselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Shinya Kitaoka 210a8a
#include <qglwidget> // for QGLWidget::convertToGLFormat</qglwidget>
Toshihiro Shimizu 890ddd
#include <qfont></qfont>
Toshihiro Shimizu 890ddd
#include <qfontmetrics></qfontmetrics>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Riempie il vettore \b theVect con gli indici degli stroke contenuti nel mapping \b theMap.
Shinya Kitaoka 3bfa54
void mapToVector(const std::map<int, *="" vistroke=""> &theMap, std::vector<int> &theVect)</int></int,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(theMap.size() == theVect.size());
Shinya Kitaoka 3bfa54
	std::map<int, *="" vistroke="">::const_iterator it = theMap.begin();</int,>
Toshihiro Shimizu 890ddd
	UINT i = 0;
Toshihiro Shimizu 890ddd
	for (; it != theMap.end(); ++it) {
Toshihiro Shimizu 890ddd
		theVect[i++] = it->first;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void updateSaveBox(const TToonzImageP &ti)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (ti) {
Toshihiro Shimizu 890ddd
		assert(ti->getRaster());		   // Image should have a raster
Toshihiro Shimizu 890ddd
		assert(ti->getSubsampling() == 1); // Image should not be subsampled - modified images must be the ORIGINAL ones
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const TRect &savebox = ti->getSavebox();
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			TRect newSaveBox;
Toshihiro Shimizu 890ddd
			TRop::computeBBox(ti->getRaster(), newSaveBox); // This iterates the WHOLE raster to find its new savebox!
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (!Preferences::instance()->isMinimizeSaveboxAfterEditing())
Toshihiro Shimizu 890ddd
				newSaveBox += savebox; // If not minimizing the savebox, it cannot be shrunk.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			ti->setSavebox(newSaveBox);
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
//    ToolUtils namespace
Toshihiro Shimizu 890ddd
//****************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// TODO: Savebox updates should not happen on mouse updates. This is, unfortunately, what currently happens.
Toshihiro Shimizu 890ddd
	sl->setDirtyFlag(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageP img = sl->getFrame(fid, true); // The image will be modified (it should already have been, though)
Toshihiro Shimizu 890ddd
										   // Observe that the returned image will forcedly have subsampling 1
Toshihiro Shimizu 890ddd
	::updateSaveBox(img);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageInfo *info = sl->getFrameInfo(fid, true);
Toshihiro Shimizu 890ddd
	ImageBuilder::setImageInfo(*info, img.getPointer());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid, TImageP img)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	sl->setFrame(fid, img);
Toshihiro Shimizu 890ddd
	ToolUtils::updateSaveBox(sl, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::updateSaveBox()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *application = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!application)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshLevel *xl = application->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	if (!xl)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *sl = xl->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!sl || sl->getType() != TZP_XSHLEVEL)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFrameId fid = getFrameId();
Toshihiro Shimizu 890ddd
	ToolUtils::updateSaveBox(sl, fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//! Return the right value in both case: LevelFrame and SceneFrame.
Toshihiro Shimizu 890ddd
TFrameId ToolUtils::getFrameId()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return TFrameId();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFrameHandle *frameHandle = app->getCurrentFrame();
Toshihiro Shimizu 890ddd
	if (frameHandle->isEditingScene()) {
Toshihiro Shimizu 890ddd
		TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Toshihiro Shimizu 890ddd
		if (!xsh)
Toshihiro Shimizu 890ddd
			return 0;
Toshihiro Shimizu 890ddd
		int row = frameHandle->getFrame();
Toshihiro Shimizu 890ddd
		int col = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
		if (col < 0)
Toshihiro Shimizu 890ddd
			return 0;
Toshihiro Shimizu 890ddd
		TXshCell cell = xsh->getCell(row, col);
Toshihiro Shimizu 890ddd
		return cell.getFrameId();
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return frameHandle->getFid();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawRect(const TRectD &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
Toshihiro Shimizu 890ddd
void ToolUtils::fillRect(const TRectD &rect, const TPixel32 &color)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	tglColor(color);
Toshihiro Shimizu 890ddd
	glBegin(GL_QUADS);
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
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawPoint(const TPointD &q, double pixelSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double size = pixelSize * 2.0;
Toshihiro Shimizu 890ddd
	glBegin(GL_QUADS);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x - size, q.y - size);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x - size, q.y + size);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x + size, q.y + size);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x + size, q.y - size);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawCross(const TPointD &q, double pixelSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double size = pixelSize;
Toshihiro Shimizu 890ddd
	glBegin(GL_LINES);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x - size, q.y);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x + size, q.y);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
	glBegin(GL_LINES);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x, q.y - size);
Toshihiro Shimizu 890ddd
	glVertex2d(q.x, q.y + size);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawArrow(const TSegment &s, double pixelSize)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD v, vn;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double length = s.getLength() * pixelSize;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (length == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	v = normalize(s.getSpeed());
Toshihiro Shimizu 890ddd
	vn = v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD p1 = s.getP0() + v * length;
Toshihiro Shimizu 890ddd
	glBegin(GL_LINES);
Toshihiro Shimizu 890ddd
	tglVertex(s.getP0());
Toshihiro Shimizu 890ddd
	tglVertex(p1);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	v = v * length * 0.7;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vn = vn * length * 0.2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD p;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glBegin(GL_TRIANGLES);
Toshihiro Shimizu 890ddd
	p = s.getP0() + v + rotate90(vn);
Toshihiro Shimizu 890ddd
	tglVertex(p);
Toshihiro Shimizu 890ddd
	tglVertex(p1);
Toshihiro Shimizu 890ddd
	p = s.getP0() + v + rotate270(vn);
Toshihiro Shimizu 890ddd
	tglVertex(p);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawSquare(const TPointD &pos, double r, const TPixel32 &color)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRectD rect(pos - TPointD(r, r), pos + TPointD(r, r));
Toshihiro Shimizu 890ddd
	tglColor(color);
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
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawRectWhitArrow(const TPointD &pos, double r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TTool::getApplication()->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TRectD rect(pos - TPointD(14 * r, 2 * r), pos + TPointD(14 * r, 2 * r));
Toshihiro Shimizu 890ddd
	tglColor(TPixel32::Black);
Toshihiro Shimizu 890ddd
	glBegin(GL_POLYGON);
Toshihiro Shimizu 890ddd
	tglVertex(rect.getP00());
Toshihiro Shimizu 890ddd
	tglVertex(rect.getP10());
Toshihiro Shimizu 890ddd
	tglVertex(rect.getP11());
Toshihiro Shimizu 890ddd
	tglVertex(rect.getP01());
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double par = 5 * r;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD p01 = 0.5 * (rect.getP00() + rect.getP10());
Toshihiro Shimizu 890ddd
	TPointD p02 = 0.5 * (rect.getP01() + rect.getP11());
Toshihiro Shimizu 890ddd
	TPointD p11 = TPointD(p01.x, p01.y - par);
Toshihiro Shimizu 890ddd
	TPointD p12 = TPointD(p02.x, p02.y + par);
Toshihiro Shimizu 890ddd
	TPointD p;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tglColor(TPixel32(130, 130, 130));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glBegin(GL_TRIANGLES);
Toshihiro Shimizu 890ddd
	p = p11 + rotate90(TPointD(0, par));
Toshihiro Shimizu 890ddd
	tglVertex(p);
Toshihiro Shimizu 890ddd
	tglVertex(p01);
Toshihiro Shimizu 890ddd
	p = p11 + rotate270(TPointD(0, par));
Toshihiro Shimizu 890ddd
	tglVertex(p);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glBegin(GL_TRIANGLES);
Toshihiro Shimizu 890ddd
	p = p12 + rotate90(TPointD(0, -par));
Toshihiro Shimizu 890ddd
	tglVertex(p);
Toshihiro Shimizu 890ddd
	tglVertex(p02);
Toshihiro Shimizu 890ddd
	p = p12 + rotate270(TPointD(0, -par));
Toshihiro Shimizu 890ddd
	tglVertex(p);
Toshihiro Shimizu 890ddd
	glEnd();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QRadialGradient ToolUtils::getBrushPad(int size, double hardness)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	hardness = tcrop(hardness, 0.0, 0.97);
Toshihiro Shimizu 890ddd
	double halfSize = size * 0.5;
Toshihiro Shimizu 890ddd
	double x = halfSize * hardness;
Toshihiro Shimizu 890ddd
	TQuadratic q(TPointD(x, 1.0), TPointD((halfSize + x) * 0.5, 0.0), TPointD(halfSize, 0.0));
Toshihiro Shimizu 890ddd
	QRadialGradient rd(QPointF(halfSize, halfSize), halfSize, QPointF(halfSize, halfSize));
Toshihiro Shimizu 890ddd
	rd.setColorAt(0, QColor(0, 0, 0));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double t;
Toshihiro Shimizu 890ddd
	double offset = halfSize - x;
Toshihiro Shimizu 890ddd
	assert(offset > 0);
Toshihiro Shimizu 890ddd
	for (t = 0; t <= 1; t += 1.0 / offset) {
Toshihiro Shimizu 890ddd
		TPointD p = q.getPoint(t);
Toshihiro Shimizu 890ddd
		int value = 255 * p.y;
Toshihiro Shimizu 890ddd
		rd.setColorAt(p.x / halfSize, QColor(0, 0, 0, value));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return rd;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QList<trect> ToolUtils::splitRect(const TRect &first, const TRect &second)</trect>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRect intersection = first * second;
Toshihiro Shimizu 890ddd
	QList<trect> rects;</trect>
Toshihiro Shimizu 890ddd
	if (intersection.isEmpty()) {
Toshihiro Shimizu 890ddd
		rects.append(first);
Toshihiro Shimizu 890ddd
		return rects;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRect rect;
Toshihiro Shimizu 890ddd
	if (first.x0 < intersection.x0) {
Toshihiro Shimizu 890ddd
		rect = TRect(first.getP00(), TPoint(intersection.x0 - 1, first.y1));
Toshihiro Shimizu 890ddd
		rects.append(rect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (intersection.x1 < first.x1) {
Toshihiro Shimizu 890ddd
		rect = TRect(TPoint(intersection.x1 + 1, first.y0), first.getP11());
Toshihiro Shimizu 890ddd
		rects.append(rect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (intersection.y1 < first.y1) {
Toshihiro Shimizu 890ddd
		rect = TRect(intersection.x0, intersection.y1 + 1, intersection.x1, first.y1);
Toshihiro Shimizu 890ddd
		rects.append(rect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (first.y0 < intersection.y0) {
Toshihiro Shimizu 890ddd
		rect = TRect(intersection.x0, first.y0, intersection.x1, intersection.y0 - 1);
Toshihiro Shimizu 890ddd
		rects.append(rect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return rects;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRaster32P ToolUtils::convertStrokeToImage(TStroke *stroke, const TRect &imageBounds, TPoint &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int count = stroke->getControlPointCount();
Toshihiro Shimizu 890ddd
	if (count == 0)
Toshihiro Shimizu 890ddd
		return TRaster32P();
Toshihiro Shimizu 890ddd
	TPointD imgCenter = TPointD((imageBounds.x0 + imageBounds.x1) * 0.5, (imageBounds.y0 + imageBounds.y1) * 0.5);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke s(*stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//check self looped stroke
Toshihiro Shimizu 890ddd
	TThickPoint first = s.getControlPoint(0);
Toshihiro Shimizu 890ddd
	TThickPoint back = s.getControlPoint(count - 1);
Toshihiro Shimizu 890ddd
	if (first != back) {
Toshihiro Shimizu 890ddd
		TPointD mid = (first + back) * 0.5;
Toshihiro Shimizu 890ddd
		s.setControlPoint(count, mid);
Toshihiro Shimizu 890ddd
		s.setControlPoint(count + 1, first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//check bounds intersection
Toshihiro Shimizu 890ddd
	s.transform(TTranslation(imgCenter));
Toshihiro Shimizu 890ddd
	TRectD bbox = s.getBBox();
Toshihiro Shimizu 890ddd
	TRect rect(tfloor(bbox.x0), tfloor(bbox.y0), tfloor(bbox.x1), tfloor(bbox.y1));
Toshihiro Shimizu 890ddd
	pos = rect.getP00();
Toshihiro Shimizu 890ddd
	pos = TPoint(pos.x > 0 ? pos.x : 0, pos.y > 0 ? pos.y : 0);
Toshihiro Shimizu 890ddd
	rect *= imageBounds;
Toshihiro Shimizu 890ddd
	if (rect.isEmpty())
Toshihiro Shimizu 890ddd
		return TRaster32P();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//creates the image
Toshihiro Shimizu 890ddd
	QImage img(rect.getLx(), rect.getLy(), QImage::Format_ARGB32);
Toshihiro Shimizu 890ddd
	img.fill(Qt::transparent);
Toshihiro Shimizu 890ddd
	QColor color = Qt::black;
Toshihiro Shimizu 890ddd
	QPainter p(&img);
Toshihiro Shimizu 890ddd
	p.setPen(QPen(color, 1, Qt::SolidLine));
Toshihiro Shimizu 890ddd
	p.setBrush(color);
Toshihiro Shimizu 890ddd
	p.setRenderHint(QPainter::Antialiasing, true);
Toshihiro Shimizu 890ddd
	QPainterPath path = strokeToPainterPath(&s);
Toshihiro Shimizu 890ddd
	QRectF pathRect = path.boundingRect();
Toshihiro Shimizu 890ddd
	p.translate(-toQPoint(pos));
Toshihiro Shimizu 890ddd
	p.drawPath(path);
Toshihiro Shimizu 890ddd
	return rasterFromQImage(img, true, false);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke *ToolUtils::merge(const ArrayOfStroke &a)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::vector<tthickpoint> v;</tthickpoint>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *ref = 0;
Toshihiro Shimizu 890ddd
	int controlPoints = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < a.size(); ++i) {
Toshihiro Shimizu 890ddd
		ref = a[i];
Toshihiro Shimizu 890ddd
		assert(ref);
Toshihiro Shimizu 890ddd
		if (!ref)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		controlPoints = ref->getControlPointCount() - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int j = 0; j < controlPoints; ++j)
Toshihiro Shimizu 890ddd
			v.push_back(ref->getControlPoint(j));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (controlPoints > 0)
Toshihiro Shimizu 890ddd
		v.push_back(ref->getControlPoint(controlPoints));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *out = new TStroke(v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//TToolUndo
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TToolUndo::TToolUndo(TXshSimpleLevel *level, const TFrameId &frameId,
Toshihiro Shimizu 890ddd
								bool createdFrame, bool createdLevel, const TPaletteP &oldPalette)
Toshihiro Shimizu 890ddd
	: TUndo(), m_level(level), m_frameId(frameId), m_oldPalette(oldPalette), m_col(-2), m_row(-1), m_isEditingLevel(false), m_createdFrame(createdFrame), m_createdLevel(createdLevel), m_imageId("")
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_animationSheetEnabled = Preferences::instance()->isAnimationSheetEnabled();
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	m_isEditingLevel = app->getCurrentFrame()->isEditingLevel();
Toshihiro Shimizu 890ddd
	if (!m_isEditingLevel) {
Toshihiro Shimizu 890ddd
		m_col = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
		m_row = app->getCurrentFrame()->getFrameIndex();
Toshihiro Shimizu 890ddd
		if (m_animationSheetEnabled) {
Toshihiro Shimizu 890ddd
			m_cellsData = TTool::m_cellsData;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (createdFrame) {
Shinya Kitaoka 9eb50d
		m_imageId = "TToolUndo" + std::to_string(m_idCount++);
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(m_imageId, level->getFrame(frameId, false), false);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TToolUndo::~TToolUndo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TImageCache::instance()->remove(m_imageId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::TToolUndo::insertLevelAndFrameIfNeeded() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (m_createdLevel) {
Toshihiro Shimizu 890ddd
		TLevelSet *levelSet = app->getCurrentScene()->getScene()->getLevelSet();
Toshihiro Shimizu 890ddd
		if (levelSet) {
Toshihiro Shimizu 890ddd
			levelSet->insertLevel(m_level.getPointer());
Toshihiro Shimizu 890ddd
			app->getCurrentScene()->notifyCastChange();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_createdFrame) {
Toshihiro Shimizu 890ddd
		TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Toshihiro Shimizu 890ddd
		TImageP img = TImageCache::instance()->get(m_imageId, false);
Toshihiro Shimizu 890ddd
		m_level->setFrame(m_frameId, img);
Toshihiro Shimizu 890ddd
		if (!m_isEditingLevel) {
Toshihiro Shimizu 890ddd
			if (m_animationSheetEnabled) {
Toshihiro Shimizu 890ddd
				int m = m_cellsData.size() / 3;
Toshihiro Shimizu 890ddd
				for (int i = 0; i < m; i++) {
Toshihiro Shimizu 890ddd
					int r0 = m_cellsData[i * 3];
Toshihiro Shimizu 890ddd
					int r1 = m_cellsData[i * 3 + 1];
Toshihiro Shimizu 890ddd
					int type = m_cellsData[i * 3 + 2];
Toshihiro Shimizu 890ddd
					TXshCell cell;
Toshihiro Shimizu 890ddd
					if (type == 1)
Toshihiro Shimizu 890ddd
						cell = xsh->getCell(r0 - 1, m_col);
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						cell = TXshCell(m_level.getPointer(), m_frameId);
Toshihiro Shimizu 890ddd
					for (int r = r0; r <= r1; r++)
Toshihiro Shimizu 890ddd
						xsh->setCell(r, m_col, cell);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				TXshCell cell(m_level.getPointer(), m_frameId);
Toshihiro Shimizu 890ddd
				xsh->setCell(m_row, m_col, cell);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		app->getCurrentLevel()->notifyLevelChange();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::TToolUndo::removeLevelAndFrameIfNeeded() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (m_createdFrame) {
Toshihiro Shimizu 890ddd
		m_level->eraseFrame(m_frameId);
Toshihiro Shimizu 890ddd
		if (!m_isEditingLevel) {
Toshihiro Shimizu 890ddd
			TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Toshihiro Shimizu 890ddd
			if (m_animationSheetEnabled) {
Toshihiro Shimizu 890ddd
				int m = m_cellsData.size() / 3;
Toshihiro Shimizu 890ddd
				for (int i = 0; i < m; i++) {
Toshihiro Shimizu 890ddd
					int r0 = m_cellsData[i * 3];
Toshihiro Shimizu 890ddd
					int r1 = m_cellsData[i * 3 + 1];
Toshihiro Shimizu 890ddd
					int type = m_cellsData[i * 3 + 2];
Toshihiro Shimizu 890ddd
					TXshCell cell;
Toshihiro Shimizu 890ddd
					if (type == 0)
Toshihiro Shimizu 890ddd
						cell = xsh->getCell(r0 - 1, m_col);
Toshihiro Shimizu 890ddd
					for (int r = r0; r <= r1; r++)
Toshihiro Shimizu 890ddd
						xsh->setCell(r, m_col, cell);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				xsh->clearCells(m_row, m_col);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (m_createdLevel) {
Toshihiro Shimizu 890ddd
			// butta il livello
Toshihiro Shimizu 890ddd
			TLevelSet *levelSet = app->getCurrentScene()->getScene()->getLevelSet();
Toshihiro Shimizu 890ddd
			if (levelSet) {
Toshihiro Shimizu 890ddd
				levelSet->removeLevel(m_level.getPointer());
Toshihiro Shimizu 890ddd
				app->getCurrentScene()->notifyCastChange();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		app->getCurrentLevel()->notifyLevelChange();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_oldPalette.getPointer()) {
Toshihiro Shimizu 890ddd
		m_level->getPalette()->assign(m_oldPalette->clone());
Toshihiro Shimizu 890ddd
		app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::TToolUndo::notifyImageChanged() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *currentSl = 0;
Toshihiro Shimizu 890ddd
	TFrameId currentFrameId;
Toshihiro Shimizu 890ddd
	if (app->getCurrentFrame()->isEditingLevel()) {
Toshihiro Shimizu 890ddd
		TXshLevel *xl = app->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
		if (!xl)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		currentSl = xl->getSimpleLevel();
Toshihiro Shimizu 890ddd
		currentFrameId = app->getCurrentFrame()->getFid();
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		int row = app->getCurrentFrame()->getFrame();
Toshihiro Shimizu 890ddd
		int col = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
		if (col < 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
Toshihiro Shimizu 890ddd
		if (!xsh)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TXshCell cell = xsh->getCell(row, col);
Toshihiro Shimizu 890ddd
		currentSl = cell.getSimpleLevel();
Toshihiro Shimizu 890ddd
		currentFrameId = cell.getFrameId();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (currentSl == m_level.getPointer() && currentFrameId == m_frameId) {
Toshihiro Shimizu 890ddd
		TTool *tool = app->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
		if (tool)
Toshihiro Shimizu 890ddd
			tool->onImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	IconGenerator::instance()->invalidate(m_level.getPointer(), m_frameId);
Toshihiro Shimizu 890ddd
	IconGenerator::instance()->invalidateSceneIcon();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_level && m_level->getType() == PLI_XSHLEVEL) {
Shinya Kitaoka 3bfa54
		std::string id = m_level->getImageId(m_frameId) + "_rasterized";
Toshihiro Shimizu 890ddd
		ImageManager::instance()->invalidate(id);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::TToolUndo::m_idCount = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TRasterUndo::TRasterUndo(TTileSetCM32 *tiles, TXshSimpleLevel *level, const TFrameId &frameId,
Toshihiro Shimizu 890ddd
									bool createdFrame, bool createdLevel, const TPaletteP &oldPalette)
Toshihiro Shimizu 890ddd
	: TToolUndo(level, frameId, createdFrame, createdLevel, oldPalette), m_tiles(tiles)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TRasterUndo::~TRasterUndo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_tiles)
Toshihiro Shimizu 890ddd
		delete m_tiles;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TToonzImageP ToolUtils::TRasterUndo::getImage() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_level->isFid(m_frameId))
Toshihiro Shimizu 890ddd
		return (TToonzImageP)m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::TRasterUndo::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int size = sizeof(*this);
Toshihiro Shimizu 890ddd
	size += sizeof(*(m_level.getPointer()));
Toshihiro Shimizu 890ddd
	size += sizeof(*(m_oldPalette.getPointer()));
Toshihiro Shimizu 890ddd
	return m_tiles ? m_tiles->getMemorySize() + size : size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::TRasterUndo::undo() const
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 (m_tiles && m_tiles->getTileCount() > 0) {
Toshihiro Shimizu 890ddd
		TToonzImageP image = getImage();
Toshihiro Shimizu 890ddd
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToonzImageUtils::paste(image, m_tiles);
Toshihiro Shimizu 890ddd
		ToolUtils::updateSaveBox(m_level, m_frameId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	removeLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TFullColorRasterUndo::TFullColorRasterUndo(TTileSetFullColor *tiles, TXshSimpleLevel *level,
Toshihiro Shimizu 890ddd
													  const TFrameId &frameId, bool createdFrame,
Toshihiro Shimizu 890ddd
													  bool createdLevel, const TPaletteP &oldPalette)
Toshihiro Shimizu 890ddd
	: TToolUndo(level, frameId, createdFrame, createdLevel, oldPalette), m_tiles(tiles)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::TFullColorRasterUndo::~TFullColorRasterUndo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_tiles;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterImageP ToolUtils::TFullColorRasterUndo::getImage() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_level->isFid(m_frameId))
Toshihiro Shimizu 890ddd
		return (TRasterImageP)m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::TFullColorRasterUndo::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int size = sizeof(*this);
Toshihiro Shimizu 890ddd
	size += sizeof(*(m_level.getPointer()));
Toshihiro Shimizu 890ddd
	size += sizeof(*(m_oldPalette.getPointer()));
Toshihiro Shimizu 890ddd
	return m_tiles ? m_tiles->getMemorySize() + size : size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::TFullColorRasterUndo::undo() const
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 (m_tiles && m_tiles->getTileCount() > 0) {
Toshihiro Shimizu 890ddd
		TRasterImageP image = getImage();
Toshihiro Shimizu 890ddd
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Shinya Kitaoka 3bfa54
		std::vector<trect> rects = paste(image, m_tiles);</trect>
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		TRect resRect = rects[0];
Toshihiro Shimizu 890ddd
		for (i = 1; i < (int)rects.size(); i++)
Toshihiro Shimizu 890ddd
			resRect += rects[i];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	removeLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::vector<trect> ToolUtils::TFullColorRasterUndo::paste(const TRasterImageP &ti, const TTileSetFullColor *tileSet) const</trect>
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::vector<trect> rects;</trect>
Toshihiro Shimizu 890ddd
	TRasterP raster = ti->getRaster();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < tileSet->getTileCount(); i++) {
Toshihiro Shimizu 890ddd
		const TTileSetFullColor::Tile *tile = tileSet->getTile(i);
Toshihiro Shimizu 890ddd
		TRasterP ras;
Toshihiro Shimizu 890ddd
		tile->getRaster(ras);
Toshihiro Shimizu 890ddd
		assert(!!ras);
Toshihiro Shimizu 890ddd
		raster->copy(ras, tile->m_rasterBounds.getP00());
Toshihiro Shimizu 890ddd
		rects.push_back(tile->m_rasterBounds);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return rects;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyStroke::UndoModifyStroke(TXshSimpleLevel *level, const TFrameId &frameId, int strokeIndex)
Toshihiro Shimizu 890ddd
	: TToolUndo(level, frameId), m_strokeIndex(strokeIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP image = level->getFrame(frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	TStroke *stroke = image->getStroke(m_strokeIndex);
Toshihiro Shimizu 890ddd
	int n = stroke->getControlPointCount();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < n; i++)
Toshihiro Shimizu 890ddd
		m_before.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_selfLoopBefore = stroke->isSelfLoop();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	m_row = app->getCurrentFrame()->getFrame();
Toshihiro Shimizu 890ddd
	m_column = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyStroke::~UndoModifyStroke() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyStroke::onAdd()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = image->getStroke(m_strokeIndex);
Toshihiro Shimizu 890ddd
	assert(stroke);
Toshihiro Shimizu 890ddd
	int n = stroke->getControlPointCount();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < n; i++)
Toshihiro Shimizu 890ddd
		m_after.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_selfLoopAfter = stroke->isSelfLoop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyStroke::undo() const
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->getCurrentFrame()->isEditingScene()) {
Toshihiro Shimizu 890ddd
		app->getCurrentColumn()->setColumnIndex(m_column);
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFrame(m_row);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFid(m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
	TStroke *stroke = 0;
Toshihiro Shimizu 890ddd
	if (image->getStrokeCount() == 1) // && image->getStroke(0)->getStyle()==SplineStyle)
Toshihiro Shimizu 890ddd
		stroke = image->getStroke(0);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		stroke = image->getStroke(m_strokeIndex);
Toshihiro Shimizu 890ddd
	if (!stroke)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TStroke *oldStroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	stroke->reshape(&m_before[0], m_before.size());
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop(m_selfLoopBefore);
Toshihiro Shimizu 890ddd
	image->notifyChangedStrokes(m_strokeIndex, oldStroke);
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
	delete oldStroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyStroke::redo() const
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->getCurrentFrame()->isEditingScene()) {
Toshihiro Shimizu 890ddd
		app->getCurrentColumn()->setColumnIndex(m_column);
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFrame(m_row);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFid(m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
	TStroke *stroke = 0;
Toshihiro Shimizu 890ddd
	if (image->getStrokeCount() == 1) //&& image->getStroke(0)->getStyle()==SplineStyle)
Toshihiro Shimizu 890ddd
		stroke = image->getStroke(0);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		stroke = image->getStroke(m_strokeIndex);
Toshihiro Shimizu 890ddd
	if (!stroke)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TStroke *oldStroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	stroke->reshape(&m_after[0], m_after.size());
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop(m_selfLoopAfter);
Toshihiro Shimizu 890ddd
	image->notifyChangedStrokes(m_strokeIndex, oldStroke);
Toshihiro Shimizu 890ddd
	delete oldStroke;
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoModifyStroke::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_before.capacity() + m_after.capacity()) * sizeof(TThickPoint) +
Toshihiro Shimizu 890ddd
		   sizeof(*this) + 500;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyStrokeAndPaint::UndoModifyStrokeAndPaint(TXshSimpleLevel *level, const TFrameId &frameId,
Toshihiro Shimizu 890ddd
															  int strokeIndex)
Toshihiro Shimizu 890ddd
	: UndoModifyStroke(level, frameId, strokeIndex), m_fillInformation(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP image = level->getFrame(frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	TStroke *stroke = image->getStroke(strokeIndex);
Toshihiro Shimizu 890ddd
	m_oldBBox = stroke->getBBox();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyStrokeAndPaint::onAdd()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(!!image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UndoModifyStroke::onAdd();
Toshihiro Shimizu 890ddd
	TStroke *stroke = image->getStroke(m_strokeIndex);
Shinya Kitaoka 3bfa54
	m_fillInformation = new std::vector<tfilledregioninf>;</tfilledregioninf>
Toshihiro Shimizu 890ddd
	ImageUtils::getFillingInformationOverlappingArea(image, *m_fillInformation, m_oldBBox, stroke->getBBox());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyStrokeAndPaint::undo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *application = TTool::getApplication();
Toshihiro Shimizu 890ddd
	if (!application)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UndoModifyStroke::undo();
Toshihiro Shimizu 890ddd
	TRegion *reg;
Toshihiro Shimizu 890ddd
	UINT size = m_fillInformation->size();
Toshihiro Shimizu 890ddd
	if (!size) {
Toshihiro Shimizu 890ddd
		application->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
		notifyImageChanged();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(!!image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//image->validateRegions();
Toshihiro Shimizu 890ddd
	image->findRegions();
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < size; i++) {
Toshihiro Shimizu 890ddd
		reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Toshihiro Shimizu 890ddd
		assert(reg);
Toshihiro Shimizu 890ddd
		if (reg)
Toshihiro Shimizu 890ddd
			reg->setStyle((*m_fillInformation)[i].m_styleId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	application->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyStrokeAndPaint::~UndoModifyStrokeAndPaint()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_fillInformation;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoModifyStrokeAndPaint::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int size = m_fillInformation ? m_fillInformation->size() * sizeof(TFilledRegionInf) : 0;
Toshihiro Shimizu 890ddd
	return UndoModifyStroke::getSize() + size;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyListStroke::UndoModifyListStroke(TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 3bfa54
													  const std::vector<tstroke *=""> &strokeVect)</tstroke>
Toshihiro Shimizu 890ddd
	: TToolUndo(level, frameId), m_fillInformation(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT strokeNum = strokeVect.size();
Toshihiro Shimizu 890ddd
	TVectorImageP image = level->getFrame(frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < strokeNum; i++) {
Toshihiro Shimizu 890ddd
		m_oldBBox += (strokeVect[i])->getBBox();
Toshihiro Shimizu 890ddd
		int strokeIndex = image->getStrokeIndex(strokeVect[i]);
Toshihiro Shimizu 890ddd
		m_strokeList.push_back(new UndoModifyStroke(level, frameId, strokeIndex));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_beginIt = m_strokeList.begin();
Toshihiro Shimizu 890ddd
	m_endIt = m_strokeList.end();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoModifyListStroke::~UndoModifyListStroke()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	clearPointerContainer(m_strokeList);
Toshihiro Shimizu 890ddd
	delete m_fillInformation;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyListStroke::onAdd()
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 3bfa54
	std::list<undomodifystroke *="">::iterator it = m_beginIt;</undomodifystroke>
Toshihiro Shimizu 890ddd
	TRectD newBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(!!image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (; it != m_endIt; ++it) {
Toshihiro Shimizu 890ddd
		TStroke *s = image->getStroke((*it)->m_strokeIndex);
Toshihiro Shimizu 890ddd
		(*it)->onAdd();
Toshihiro Shimizu 890ddd
	}
Shinya Kitaoka 3bfa54
	m_fillInformation = new std::vector<tfilledregioninf>;</tfilledregioninf>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_beginIt != m_endIt)
Toshihiro Shimizu 890ddd
		ImageUtils::getFillingInformationOverlappingArea(image, *m_fillInformation, m_oldBBox, newBBox);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyListStroke::undo() const
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::list<undomodifystroke *="">::iterator stroke_it = m_beginIt;</undomodifystroke>
Toshihiro Shimizu 890ddd
	if (m_beginIt == m_endIt)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (; stroke_it != m_endIt; ++stroke_it) {
Toshihiro Shimizu 890ddd
		(*stroke_it)->undo();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT size = m_fillInformation->size();
Toshihiro Shimizu 890ddd
	if (!size) {
Toshihiro Shimizu 890ddd
		app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
		app->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(!!image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	image->findRegions();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRegion *reg;
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < size; i++) {
Toshihiro Shimizu 890ddd
		reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Toshihiro Shimizu 890ddd
		assert(reg);
Toshihiro Shimizu 890ddd
		if (reg)
Toshihiro Shimizu 890ddd
			reg->setStyle((*m_fillInformation)[i].m_styleId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoModifyListStroke::redo() const
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::list<undomodifystroke *="">::iterator it = m_beginIt;</undomodifystroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (; it != m_endIt; ++it) {
Toshihiro Shimizu 890ddd
		(*it)->redo();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoModifyListStroke::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int sum = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::list<undomodifystroke *="">::iterator it = m_beginIt;</undomodifystroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (; it != m_endIt; ++it) {
Toshihiro Shimizu 890ddd
		sum += (*it)->getSize();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_fillInformation)
Toshihiro Shimizu 890ddd
		sum += m_fillInformation->capacity() * sizeof(TFilledRegionInf);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return sum;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoPencil::UndoPencil(TStroke *stroke,
Shinya Kitaoka 3bfa54
								  std::vector<tfilledregioninf> *fillInformation,</tfilledregioninf>
Toshihiro Shimizu 890ddd
								  TXshSimpleLevel *level, const TFrameId &frameId,
Toshihiro Shimizu 890ddd
								  bool createdFrame, bool createdLevel,
Toshihiro Shimizu 890ddd
								  bool autogroup, bool autofill)
Toshihiro Shimizu 890ddd
	: TToolUndo(level, frameId, createdFrame, createdLevel, 0), m_strokeId(stroke->getId()), m_fillInformation(fillInformation), m_autogroup(autogroup), m_autofill(autofill)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_stroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoPencil::~UndoPencil()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_fillInformation;
Toshihiro Shimizu 890ddd
	delete m_stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoPencil::undo() const
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->getCurrentFrame()->isEditingScene() && m_col!=-2 && m_row!=-1)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		app->getCurrentColumn()->setColumnIndex(m_col);
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFrame(m_row);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFid(m_frameId);*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker sl(image->getMutex());
Toshihiro Shimizu 890ddd
	VIStroke *stroke = image->getStrokeById(m_strokeId);
Toshihiro Shimizu 890ddd
	if (!stroke)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	image->deleteStroke(stroke);
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (StrokeSelection *strokeSelection = (StrokeSelection *)selection)
Toshihiro Shimizu 890ddd
		strokeSelection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT size = m_fillInformation->size();
Toshihiro Shimizu 890ddd
	TRegion *reg;
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < size; i++) {
Toshihiro Shimizu 890ddd
		reg = image->getRegion((*m_fillInformation)[i].m_regionId);
Toshihiro Shimizu 890ddd
		assert(reg);
Toshihiro Shimizu 890ddd
		if (reg)
Toshihiro Shimizu 890ddd
			reg->setStyle((*m_fillInformation)[i].m_styleId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	removeLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoPencil::redo() const
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
	insertLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*if(app->getCurrentFrame()->isEditingScene())
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		app->getCurrentColumn()->setColumnIndex(m_col);
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFrame(m_row);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFid(m_frameId);*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMutexLocker sl(image->getMutex());
Toshihiro Shimizu 890ddd
	TStroke *stroke = new TStroke(*m_stroke);
Toshihiro Shimizu 890ddd
	stroke->setId(m_strokeId);
Toshihiro Shimizu 890ddd
	image->addStroke(stroke);
Toshihiro Shimizu 890ddd
	if (image->isComputedRegionAlmostOnce())
Toshihiro Shimizu 890ddd
		image->findRegions();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_autogroup && stroke->isSelfLoop()) {
Toshihiro Shimizu 890ddd
		int index = image->getStrokeCount() - 1;
Toshihiro Shimizu 890ddd
		image->group(index, 1);
Toshihiro Shimizu 890ddd
		if (m_autofill) {
Toshihiro Shimizu 890ddd
			//to avoid filling other strokes, I enter into the new stroke group
Toshihiro Shimizu 890ddd
			int currentGroup = image->exitGroup();
Toshihiro Shimizu 890ddd
			image->enterGroup(index);
Toshihiro Shimizu 890ddd
			image->selectFill(stroke->getBBox().enlarge(1, 1), 0, stroke->getStyle(), false, true, false);
Toshihiro Shimizu 890ddd
			if (currentGroup != -1)
Toshihiro Shimizu 890ddd
				image->enterGroup(currentGroup);
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				image->exitGroup();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoPencil::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return sizeof(*this) + m_fillInformation->capacity() * sizeof(TFilledRegionInf) + 500;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoRasterPencil::UndoRasterPencil(TXshSimpleLevel *level, const TFrameId &frameId, TStroke *stroke,
Toshihiro Shimizu 890ddd
											  bool selective, bool filled, bool doAntialias, bool createdFrame,
Shinya Kitaoka 3bfa54
												bool createdLevel, std::string primitiveName)
Toshihiro Shimizu 890ddd
	: TRasterUndo(0, level, frameId, createdFrame, createdLevel, 0), m_selective(selective), m_filled(filled), m_doAntialias(doAntialias), m_primitiveName(primitiveName)
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
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoRasterPencil::~UndoRasterPencil()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoRasterPencil::redo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	insertLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
	TToonzImageP image = getImage();
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToonzImageUtils::addInkStroke(image, m_stroke, m_stroke->getStyle(), m_selective, m_filled, TConsts::infiniteRectD, m_doAntialias);
Toshihiro Shimizu 890ddd
	ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoRasterPencil::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TRasterUndo::getSize() + m_stroke->getControlPointCount() * sizeof(TThickPoint) + 100 + sizeof(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoFullColorPencil::UndoFullColorPencil(TXshSimpleLevel *level, const TFrameId &frameId,
Toshihiro Shimizu 890ddd
													TStroke *stroke, double opacity, bool doAntialias,
Toshihiro Shimizu 890ddd
													bool createdFrame, bool createdLevel)
Toshihiro Shimizu 890ddd
	: TFullColorRasterUndo(0, level, frameId, createdFrame, createdLevel, 0), m_opacity(opacity), m_doAntialias(doAntialias)
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
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoFullColorPencil::~UndoFullColorPencil()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	delete m_stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoFullColorPencil::redo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	insertLevelAndFrameIfNeeded();
Toshihiro Shimizu 890ddd
	TRasterImageP image = getImage();
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TRasterImageUtils::addStroke(image, m_stroke, TRectD(), m_opacity, m_doAntialias);
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoFullColorPencil::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TFullColorRasterUndo::getSize() + m_stroke->getControlPointCount() * sizeof(TThickPoint) + 100 + sizeof(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// undo class (path strokes). call it BEFORE and register it AFTER path change
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
ToolUtils::UndoPath::UndoPath(TStageObjectSpline *spline)
Toshihiro Shimizu 890ddd
	: m_spline(spline)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!!m_spline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TStroke *stroke = m_spline->getStroke();
Toshihiro Shimizu 890ddd
	assert(stroke);
Toshihiro Shimizu 890ddd
	int n = stroke->getControlPointCount();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < n; i++)
Toshihiro Shimizu 890ddd
		m_before.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
	m_selfLoopBefore = stroke->isSelfLoop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoPath::~UndoPath()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoPath::onAdd()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!!m_spline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TStroke *stroke = m_spline->getStroke();
Toshihiro Shimizu 890ddd
	assert(stroke);
Toshihiro Shimizu 890ddd
	int n = stroke->getControlPointCount();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < n; i++)
Toshihiro Shimizu 890ddd
		m_after.push_back(stroke->getControlPoint(i));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoPath::undo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!!m_spline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = new TStroke(*m_spline->getStroke());
Toshihiro Shimizu 890ddd
	stroke->reshape(&m_before[0], m_before.size());
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop(m_selfLoopBefore);
Toshihiro Shimizu 890ddd
	m_spline->setStroke(stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!app->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStageObjectId currentObjectId = app->getCurrentObject()->getObjectId();
Toshihiro Shimizu 890ddd
	TStageObject *stageObject = app->getCurrentXsheet()->getXsheet()->getStageObject(currentObjectId);
Toshihiro Shimizu 890ddd
	if (stageObject->getSpline()->getId() == m_spline->getId())
Toshihiro Shimizu 890ddd
		app->getCurrentObject()->setSplineObject(m_spline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoPath::redo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!!m_spline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStroke *stroke = new TStroke(*m_spline->getStroke());
Toshihiro Shimizu 890ddd
	stroke->reshape(&m_after[0], m_after.size());
Toshihiro Shimizu 890ddd
	stroke->setSelfLoop(m_selfLoopBefore);
Toshihiro Shimizu 890ddd
	m_spline->setStroke(stroke);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!app->getCurrentObject()->isSpline())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TStageObjectId currentObjectId = app->getCurrentObject()->getObjectId();
Toshihiro Shimizu 890ddd
	TStageObject *stageObject = app->getCurrentXsheet()->getXsheet()->getStageObject(currentObjectId);
Toshihiro Shimizu 890ddd
	if (stageObject->getSpline()->getId() == m_spline->getId())
Toshihiro Shimizu 890ddd
		app->getCurrentObject()->setSplineObject(m_spline);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::UndoPath::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return sizeof(*this) + 500;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// UndoControlPointEditor
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoControlPointEditor::UndoControlPointEditor(TXshSimpleLevel *level, const TFrameId &frameId)
Toshihiro Shimizu 890ddd
	: TToolUndo(level, frameId), m_isStrokeDelete(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP image = level->getFrame(frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
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_row = app->getCurrentFrame()->getFrame();
Toshihiro Shimizu 890ddd
	m_column = app->getCurrentColumn()->getColumnIndex();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::UndoControlPointEditor::~UndoControlPointEditor()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	deleteVIStroke(m_oldStroke.second);
Toshihiro Shimizu 890ddd
	if (!m_isStrokeDelete)
Toshihiro Shimizu 890ddd
		deleteVIStroke(m_newStroke.second);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoControlPointEditor::onAdd()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
	if (m_isStrokeDelete)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	addNewStroke(m_oldStroke.first, image->getVIStroke(m_oldStroke.first));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoControlPointEditor::addOldStroke(int index, VIStroke *vs)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	VIStroke *s = cloneVIStroke(vs);
Toshihiro Shimizu 890ddd
	m_oldStroke = std::make_pair(index, s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoControlPointEditor::addNewStroke(int index, VIStroke *vs)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	VIStroke *s = cloneVIStroke(vs);
Toshihiro Shimizu 890ddd
	m_newStroke = std::make_pair(index, s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoControlPointEditor::undo() const
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->getCurrentFrame()->isEditingScene()) {
Toshihiro Shimizu 890ddd
		app->getCurrentColumn()->setColumnIndex(m_column);
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFrame(m_row);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFid(m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isStrokeDelete)
Toshihiro Shimizu 890ddd
		image->removeStroke(m_newStroke.first, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT i = 0;
Toshihiro Shimizu 890ddd
	VIStroke *s = cloneVIStroke(m_oldStroke.second);
Toshihiro Shimizu 890ddd
	image->insertStrokeAt(s, m_oldStroke.first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (image->isComputedRegionAlmostOnce())
Toshihiro Shimizu 890ddd
		image->findRegions(); //in futuro togliere. Serve perche' la  removeStrokes, se gli si dice
Toshihiro Shimizu 890ddd
							  //di non calcolare le regioni, e' piu' veloce ma poi chrash tutto
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::UndoControlPointEditor::redo() const
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->getCurrentFrame()->isEditingScene()) {
Toshihiro Shimizu 890ddd
		app->getCurrentColumn()->setColumnIndex(m_column);
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFrame(m_row);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		app->getCurrentFrame()->setFid(m_frameId);
Toshihiro Shimizu 890ddd
	TSelection *selection = app->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
	TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
	assert(image);
Toshihiro Shimizu 890ddd
	if (!image)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	image->removeStroke(m_oldStroke.first, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_isStrokeDelete) {
Toshihiro Shimizu 890ddd
		VIStroke *s = cloneVIStroke(m_newStroke.second);
Toshihiro Shimizu 890ddd
		image->insertStrokeAt(s, m_newStroke.first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (image->isComputedRegionAlmostOnce())
Toshihiro Shimizu 890ddd
		image->findRegions(); //in futuro togliere. Serve perche' la  removeStrokes, se gli si dice
Toshihiro Shimizu 890ddd
							  //di non calcolare le regioni, e' piu' veloce ma poi chrash tutto
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
	notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Menu
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::DragMenu::DragMenu()
Toshihiro Shimizu 890ddd
	: QMenu()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QAction *ToolUtils::DragMenu::exec(const QPoint &p, QAction *action)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QAction *execAct = QMenu::exec(p, action);
Toshihiro Shimizu 890ddd
	if (execAct)
Toshihiro Shimizu 890ddd
		return execAct;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return defaultAction();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::DragMenu::mouseReleaseEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMenu::mouseReleaseEvent(e);
Toshihiro Shimizu 890ddd
	hide();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// ColumChooserMenu
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
ToolUtils::ColumChooserMenu::ColumChooserMenu(TXsheet *xsh, const std::vector<int> &columnIndexes)</int>
Toshihiro Shimizu 890ddd
	: DragMenu()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int size = columnIndexes.size();
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = size - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
		int index = columnIndexes[i];
Toshihiro Shimizu 890ddd
		TStageObjectId id = TStageObjectId::ColumnId(index);
Toshihiro Shimizu 890ddd
		TStageObject *stageObject = xsh->getStageObject(id);
Toshihiro Shimizu 890ddd
		QString cmdStr = "Column " + QString::fromStdString(stageObject->getName());
Toshihiro Shimizu 890ddd
		QAction *act = new QAction(cmdStr, this);
Toshihiro Shimizu 890ddd
		act->setData(index);
Toshihiro Shimizu 890ddd
		addAction(act);
Toshihiro Shimizu 890ddd
		if (size - 1 == i) {
Toshihiro Shimizu 890ddd
			setDefaultAction(act);
Toshihiro Shimizu 890ddd
			setActiveAction(act);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int ToolUtils::ColumChooserMenu::execute()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QAction *executeAct = exec(QCursor::pos());
Toshihiro Shimizu 890ddd
	return (!executeAct) ? -1 : executeAct->data().toInt();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double ToolUtils::ConeSubVolume::compute(double cover)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double x = (10 * tcrop(cover, -1.0, 1.0)) + 10;
Toshihiro Shimizu 890ddd
	assert(0 <= x && x <= 20);
Toshihiro Shimizu 890ddd
	int i = tfloor(x);
Toshihiro Shimizu 890ddd
	if (i == 20)
Toshihiro Shimizu 890ddd
		return m_values[i];
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		//Interpolazione lineare.
Toshihiro Shimizu 890ddd
		return (-(x - (i + 1)) * m_values[i]) - (-(x - i) * m_values[i + 1]);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const double ToolUtils::ConeSubVolume::m_values[] = {
Toshihiro Shimizu 890ddd
	1.0, 0.99778, 0.987779, 0.967282, 0.934874,
Toshihiro Shimizu 890ddd
	0.889929, 0.832457, 0.763067, 0.683002, 0.594266,
Toshihiro Shimizu 890ddd
	0.5, 0.405734, 0.316998, 0.236933, 0.167543,
Toshihiro Shimizu 890ddd
	0.110071, 0.0651259, 0.0327182, 0.0122208, 0.00221986,
Toshihiro Shimizu 890ddd
	0.0};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawBalloon(
Toshihiro Shimizu 890ddd
	const TPointD &pos,
Toshihiro Shimizu 890ddd
	std::string text,
Toshihiro Shimizu 890ddd
	const TPixel32 &color,
Toshihiro Shimizu 890ddd
	TPoint delta,
Toshihiro Shimizu 890ddd
	bool isPicking,
Toshihiro Shimizu 890ddd
	std::vector<trectd> *otherBalloons)</trectd>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QString qText = QString::fromStdString(text);
Toshihiro Shimizu 890ddd
	QFont font("Arial", 10); // ,QFont::Bold);
Toshihiro Shimizu 890ddd
	QFontMetrics fm(font);
Toshihiro Shimizu 890ddd
	QRect textRect = fm.boundingRect(qText);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int baseLine = -textRect.top();
Toshihiro Shimizu 890ddd
	int mrg = 3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// avoid other balloons
Toshihiro Shimizu 890ddd
	if (otherBalloons) {
Toshihiro Shimizu 890ddd
		double pixelSize = sqrt(tglGetPixelSize2());
Toshihiro Shimizu 890ddd
		std::vector<trectd> &balloons = *otherBalloons;</trectd>
Toshihiro Shimizu 890ddd
		int n = (int)balloons.size();
Toshihiro Shimizu 890ddd
		TDimensionD balloonSize(pixelSize * (textRect.width() + mrg * 2), pixelSize * (textRect.height() + mrg * 2));
Toshihiro Shimizu 890ddd
		TRectD balloonRect;
Toshihiro Shimizu 890ddd
		for (;;) {
Toshihiro Shimizu 890ddd
			balloonRect = TRectD(pos + TPointD(delta.x * pixelSize, delta.y * pixelSize), balloonSize);
Toshihiro Shimizu 890ddd
			int i = 0;
Toshihiro Shimizu 890ddd
			while (i < n && !balloons[i].overlaps(balloonRect))
Toshihiro Shimizu 890ddd
				i++;
Toshihiro Shimizu 890ddd
			if (i == n)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			double y = balloons[i].y0 - balloonSize.ly - 2 * mrg * pixelSize;
Toshihiro Shimizu 890ddd
			delta.y = (y - pos.y) / pixelSize;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		balloons.push_back(balloonRect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	textRect.moveTo(qMax(delta.x, 10 + mrg), qMax(mrg + 2, -delta.y - baseLine));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int y = textRect.top() + baseLine;
Toshihiro Shimizu 890ddd
	int x0 = textRect.left() - mrg;
Toshihiro Shimizu 890ddd
	int x1 = textRect.right() + mrg;
Toshihiro Shimizu 890ddd
	int y0 = textRect.top() - mrg;
Toshihiro Shimizu 890ddd
	int y1 = textRect.bottom() + mrg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double pixelSize = sqrt(tglGetPixelSize2());
Toshihiro Shimizu 890ddd
	if (isPicking) {
Toshihiro Shimizu 890ddd
		TTool::Viewer *viewer = TTool::getApplication()->getCurrentTool()->getTool()->getViewer();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (viewer->is3DView()) {
Toshihiro Shimizu 890ddd
			double x0 = pos.x + textRect.left() * pixelSize, y0 = pos.y + delta.y * pixelSize;
Toshihiro Shimizu 890ddd
			double x1 = x0 + pixelSize * textRect.width();
Toshihiro Shimizu 890ddd
			double y1 = y0 + pixelSize * textRect.height();
Toshihiro Shimizu 890ddd
			double d = pixelSize * 5;
Toshihiro Shimizu 890ddd
			glRectd(x0 - d, y0 - d, x1 + d, y1 + d);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			TPoint posBalloon = viewer->worldToPos(pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			double d = 5;
Toshihiro Shimizu 890ddd
			double x0 = posBalloon.x + textRect.left() - d;
Toshihiro Shimizu 890ddd
			double y0 = posBalloon.y + delta.y - d;
Toshihiro Shimizu 890ddd
			double x1 = x0 + textRect.width() + d;
Toshihiro Shimizu 890ddd
			double y1 = y0 + textRect.height() + d;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TPoint p1(x0, y0);
Toshihiro Shimizu 890ddd
			TPoint p2(x1, y0);
Toshihiro Shimizu 890ddd
			TPoint p3(x0, y1);
Toshihiro Shimizu 890ddd
			TPoint p4(x1, y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TPointD w1(viewer->winToWorld(p1));
Toshihiro Shimizu 890ddd
			TPointD w2(viewer->winToWorld(p2));
Toshihiro Shimizu 890ddd
			TPointD w3(viewer->winToWorld(p3));
Toshihiro Shimizu 890ddd
			TPointD w4(viewer->winToWorld(p4));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			glBegin(GL_QUADS);
Toshihiro Shimizu 890ddd
			glVertex2d(w1.x, w1.y);
Toshihiro Shimizu 890ddd
			glVertex2d(w2.x, w2.y);
Toshihiro Shimizu 890ddd
			glVertex2d(w4.x, w4.y);
Toshihiro Shimizu 890ddd
			glVertex2d(w3.x, w3.y);
Toshihiro Shimizu 890ddd
			glEnd();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QSize size(
Toshihiro Shimizu 890ddd
		textRect.width() + textRect.left() + mrg,
Toshihiro Shimizu 890ddd
		qMax(textRect.bottom() + mrg, y + delta.y) + 3);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QImage label(size.width(), size.height(), QImage::Format_ARGB32);
Toshihiro Shimizu 890ddd
	label.fill(Qt::transparent);
Toshihiro Shimizu 890ddd
	// label.fill(qRgba(200,200,0,200));
Toshihiro Shimizu 890ddd
	QPainter p(&label);
Toshihiro Shimizu 890ddd
	p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
Toshihiro Shimizu 890ddd
	p.setBrush(QColor(color.r, color.g, color.b, color.m));
Toshihiro Shimizu 890ddd
	p.setPen(Qt::NoPen);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QPainterPath pp;
Toshihiro Shimizu 890ddd
	pp.moveTo(x0, y - 8);
Toshihiro Shimizu 890ddd
	pp.lineTo(0, y + delta.y);
Toshihiro Shimizu 890ddd
	pp.lineTo(x0, y);
Toshihiro Shimizu 890ddd
	/* bordi arrotondati
Toshihiro Shimizu 890ddd
  int arcSize = 10;
Toshihiro Shimizu 890ddd
  pp.arcTo(x0,y1-arcSize,arcSize,arcSize,180,90);
Toshihiro Shimizu 890ddd
  pp.arcTo(x1-arcSize,y1-arcSize,arcSize,arcSize,270,90);
Toshihiro Shimizu 890ddd
  pp.arcTo(x1-arcSize,y0,arcSize,arcSize,0,90);
Toshihiro Shimizu 890ddd
  pp.arcTo(x0,y0,arcSize,arcSize,90,90);
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	// bordi acuti
Toshihiro Shimizu 890ddd
	pp.lineTo(x0, y1);
Toshihiro Shimizu 890ddd
	pp.lineTo(x1, y1);
Toshihiro Shimizu 890ddd
	pp.lineTo(x1, y0);
Toshihiro Shimizu 890ddd
	pp.lineTo(x0, y0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pp.closeSubpath();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	p.drawPath(pp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	p.setPen(Qt::black);
Toshihiro Shimizu 890ddd
	p.setFont(font);
Toshihiro Shimizu 890ddd
	p.drawText(textRect, Qt::AlignCenter | Qt::TextDontClip, qText);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QImage texture = QGLWidget::convertToGLFormat(label);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	glRasterPos2f(pos.x, pos.y);
Toshihiro Shimizu 890ddd
	glBitmap(0, 0, 0, 0, 0, -size.height() + (y + delta.y), NULL); //
Toshihiro Shimizu 890ddd
	glEnable(GL_BLEND);
Toshihiro Shimizu 890ddd
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Toshihiro Shimizu 890ddd
	glDrawPixels(texture.width(), texture.height(), GL_RGBA, GL_UNSIGNED_BYTE, texture.bits());
Toshihiro Shimizu 890ddd
	glDisable(GL_BLEND);
Toshihiro Shimizu 890ddd
	glColor3d(0, 0, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ToolUtils::drawHook(
Toshihiro Shimizu 890ddd
	const TPointD &pos,
Toshihiro Shimizu 890ddd
	ToolUtils::HookType type,
Toshihiro Shimizu 890ddd
	bool highlighted, bool onionSkin)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int r = 10, d = r + r;
Toshihiro Shimizu 890ddd
	QImage image(d, d, QImage::Format_ARGB32);
Toshihiro Shimizu 890ddd
	image.fill(Qt::transparent);
Toshihiro Shimizu 890ddd
	// image.fill(qRgba(200,200,0,200));
Toshihiro Shimizu 890ddd
	QPainter painter(&image);
Toshihiro Shimizu 890ddd
	// painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int matte = onionSkin ? 100 : 255;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QColor color(0, 0, 0, matte);
Toshihiro Shimizu 890ddd
	if (highlighted)
Toshihiro Shimizu 890ddd
		color = QColor(0, 175, 175, matte);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (type == NormalHook || type == PassHookA) {
Toshihiro Shimizu 890ddd
		painter.setPen(QPen(QColor(255, 255, 255, matte), 3));
Toshihiro Shimizu 890ddd
		painter.drawEllipse(5, 5, d - 10, d - 10);
Toshihiro Shimizu 890ddd
		painter.setPen(color);
Toshihiro Shimizu 890ddd
		painter.drawEllipse(5, 5, d - 10, d - 10);
Toshihiro Shimizu 890ddd
	} else if (type == OtherLevelHook) {
Toshihiro Shimizu 890ddd
		QColor color(0, 200, 200, 200);
Toshihiro Shimizu 890ddd
		//painter.setPen(QPen(Qt::white,3));
Toshihiro Shimizu 890ddd
		//painter.drawEllipse(5,5,d-10,d-10);
Toshihiro Shimizu 890ddd
		painter.setPen(Qt::white);
Toshihiro Shimizu 890ddd
		painter.setBrush(color);
Toshihiro Shimizu 890ddd
		painter.drawEllipse(6, 6, d - 12, d - 12);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (type == NormalHook || type == PassHookB) {
Toshihiro Shimizu 890ddd
		painter.setPen(QPen(QColor(255, 255, 255, matte), 3));
Toshihiro Shimizu 890ddd
		painter.drawLine(0, r, d, r);
Toshihiro Shimizu 890ddd
		painter.drawLine(r, 0, r, d);
Toshihiro Shimizu 890ddd
		painter.setPen(color);
Toshihiro Shimizu 890ddd
		painter.drawLine(0, r, d, r);
Toshihiro Shimizu 890ddd
		painter.drawLine(r, 0, r, d);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QImage texture = QGLWidget::convertToGLFormat(image);
Toshihiro Shimizu 890ddd
	glRasterPos2f(pos.x, pos.y);
Toshihiro Shimizu 890ddd
	glBitmap(0, 0, 0, 0, -r, -r, NULL);
Toshihiro Shimizu 890ddd
	glEnable(GL_BLEND);
Toshihiro Shimizu 890ddd
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Toshihiro Shimizu 890ddd
	glDrawPixels(texture.width(), texture.height(), GL_RGBA, GL_UNSIGNED_BYTE, texture.bits());
Toshihiro Shimizu 890ddd
	glDisable(GL_BLEND);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool ToolUtils::isJustCreatedSpline(TImage *image)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP vi = image;
Toshihiro Shimizu 890ddd
	if (!vi)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (vi->getStrokeCount() != 1)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TStroke *stroke = vi->getStroke(0);
Toshihiro Shimizu 890ddd
	if (stroke->getControlPointCount() != 3)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TPointD p0 = stroke->getControlPoint(0);
Toshihiro Shimizu 890ddd
	TPointD p1 = stroke->getControlPoint(1);
Toshihiro Shimizu 890ddd
	TPointD p2 = stroke->getControlPoint(2);
Toshihiro Shimizu 890ddd
	double d = 30.0;
Toshihiro Shimizu 890ddd
	return p0 == TPointD(-d, 0) && p1 == TPointD(0, 0) && p2 == TPointD(d, 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD ToolUtils::interpolateRect(const TRectD &rect1, const TRectD &rect2, double t)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(rect1.x0 <= rect1.x1);
Toshihiro Shimizu 890ddd
	assert(rect1.y0 <= rect1.y1);
Toshihiro Shimizu 890ddd
	assert(rect2.x0 <= rect2.x1);
Toshihiro Shimizu 890ddd
	assert(rect2.y0 <= rect2.y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TRectD(
Toshihiro Shimizu 890ddd
		rect1.x0 + (rect2.x0 - rect1.x0) * t,
Toshihiro Shimizu 890ddd
		rect1.y0 + (rect2.y0 - rect1.y0) * t,
Toshihiro Shimizu 890ddd
		rect1.x1 + (rect2.x1 - rect1.x1) * t,
Toshihiro Shimizu 890ddd
		rect1.y1 + (rect2.y1 - rect1.y1) * t);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 3bfa54
bool ToolUtils::isASubRegion(int reg, const std::vector<tregion*> ®ions)</tregion*>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRegion *region=regions[reg];
Toshihiro Shimizu 890ddd
	for (int i=0; i<(int)regions.size(); i++)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if(i!=reg)
Toshihiro Shimizu 890ddd
			if(region->isSubRegionOf(*regions[i]))
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
Shinya Kitaoka 3bfa54
TRectD ToolUtils::getBounds(const std::vector<tthickpoint> &points, double maxThickness)</tthickpoint>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TThickPoint p = points[0];
Toshihiro Shimizu 890ddd
	double radius = maxThickness == 0 ? p.thick * 0.5 : maxThickness * 0.5;
Toshihiro Shimizu 890ddd
	TRectD rect(p - TPointD(radius, radius), p + TPointD(radius, radius));
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 1; i < (int)points.size(); i++) {
Toshihiro Shimizu 890ddd
		p = points[i];
Toshihiro Shimizu 890ddd
		radius = maxThickness == 0 ? p.thick * 0.5 : maxThickness * 0.5;
Toshihiro Shimizu 890ddd
		rect = rect + TRectD(p - TPointD(radius, radius), p + TPointD(radius, radius));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return rect;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
template <typename pixel=""></typename>
Toshihiro Shimizu 890ddd
TRasterPT<pixel> ToolUtils::rotate90(const TRasterPT<pixel> &ras, bool toRight)</pixel></pixel>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if(!ras)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	int lx=ras->getLy();
Toshihiro Shimizu 890ddd
	int ly=ras->getLx();
Toshihiro Shimizu 890ddd
	TRasterPT<pixel> workRas(lx,ly);</pixel>
Toshihiro Shimizu 890ddd
	for (int i=0; i<ras->getLx(); i++)</ras->
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		for (int j=0; j<ras->getLy(); j++)</ras->
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			if(toRight)
Toshihiro Shimizu 890ddd
				workRas->pixels(ly-1-i)[j]=ras->pixels(j)[i];
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				workRas->pixels(i)[lx-1-j]=ras->pixels(j)[i];
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return workRas;	
Toshihiro Shimizu 890ddd
}*/