Toshihiro Shimizu 890ddd
//------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Finger Tool : 線のノイズを埋めるツール
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
#include "toonz/strokegenerator.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttilesaver.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/observer.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/rasterstrokegenerator.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tinbetween.h"
Toshihiro Shimizu 890ddd
#include "ttile.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// For Qt translation support
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/stylepicker.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/styleselection.h"
Toshihiro Shimizu 890ddd
#include "historytypes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace ToolUtils;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TEnv::IntVar FingerInvert("InknpaintFingerInvert", 0);
Toshihiro Shimizu 890ddd
TEnv::DoubleVar FingerSize("InknpaintFingerSize", 10);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int BackgroundStyle = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class FingerUndo : public TRasterUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	vector<tthickpoint> m_points;</tthickpoint>
Toshihiro Shimizu 890ddd
	int m_styleId;
Toshihiro Shimizu 890ddd
	bool m_invert;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	FingerUndo(TTileSetCM32 *tileSet,
Toshihiro Shimizu 890ddd
			   const vector<tthickpoint> &points,</tthickpoint>
Toshihiro Shimizu 890ddd
			   int styleId, bool invert,
Toshihiro Shimizu 890ddd
			   TXshSimpleLevel *level,
Toshihiro Shimizu 890ddd
			   const TFrameId &frameId)
Toshihiro Shimizu 890ddd
		: TRasterUndo(tileSet, level, frameId, false, false, 0), m_points(points), m_styleId(styleId), m_invert(invert)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TToonzImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		TRasterCM32P ras = image->getRaster();
Toshihiro Shimizu 890ddd
		RasterStrokeGenerator m_rasterTrack(ras, FINGER, INK, m_styleId, m_points[0], m_invert, 0, false);
Toshihiro Shimizu 890ddd
		m_rasterTrack.setPointsSequence(m_points);
Toshihiro Shimizu 890ddd
		m_rasterTrack.generateStroke(true);
Toshihiro Shimizu 890ddd
		image->setSavebox(image->getSavebox() + m_rasterTrack.getBBox(m_rasterTrack.getPointsSequence()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
		notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this) + TRasterUndo::getSize();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	virtual QString getToolName()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return QString("Finger Tool");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	int getHistoryType()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return HistoryType::FingerTool;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void drawLine(const TPointD &point, const TPointD ¢re, bool horizontal, bool isDecimal)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!isDecimal) {
Toshihiro Shimizu 890ddd
		if (horizontal) {
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 1.5, point.y + 0.5) + centre, TPointD(point.x - 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y - 0.5, -point.x + 1.5) + centre, TPointD(point.y - 0.5, -point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, -point.y + 0.5) + centre, TPointD(-point.x - 0.5, -point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre, TPointD(-point.y - 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y - 0.5, point.x + 0.5) + centre, TPointD(point.y - 0.5, point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 0.5, -point.y + 0.5) + centre, TPointD(point.x - 1.5, -point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 0.5) + centre, TPointD(-point.y - 0.5, -point.x + 1.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x - 0.5, point.y + 0.5) + centre, TPointD(-point.x + 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 1.5, point.y + 1.5) + centre, TPointD(point.x - 1.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 1.5, point.y + 0.5) + centre, TPointD(point.x - 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 0.5, -point.x + 1.5) + centre, TPointD(point.y - 0.5, -point.x + 1.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y - 0.5, -point.x + 1.5) + centre, TPointD(point.y - 0.5, -point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, -point.y - 0.5) + centre, TPointD(-point.x + 0.5, -point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, -point.y + 0.5) + centre, TPointD(-point.x - 0.5, -point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 1.5, point.x - 0.5) + centre, TPointD(-point.y - 0.5, point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre, TPointD(-point.y - 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 0.5, point.x - 0.5) + centre, TPointD(point.y - 0.5, point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y - 0.5, point.x - 0.5) + centre, TPointD(point.y - 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 1.5, -point.y - 0.5) + centre, TPointD(point.x - 1.5, -point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 1.5, -point.y + 0.5) + centre, TPointD(point.x - 0.5, -point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 1.5, -point.x + 1.5) + centre, TPointD(-point.y - 0.5, -point.x + 1.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 1.5) + centre, TPointD(-point.y - 0.5, -point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, point.y + 1.5) + centre, TPointD(-point.x + 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, point.y + 0.5) + centre, TPointD(-point.x - 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if (horizontal) {
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 0.5, point.y + 0.5) + centre, TPointD(point.x + 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 0.5, point.x - 0.5) + centre, TPointD(point.y + 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 0.5, -point.x + 0.5) + centre, TPointD(point.y + 0.5, -point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x + 0.5, -point.y - 0.5) + centre, TPointD(point.x - 0.5, -point.y - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x - 0.5, -point.y - 0.5) + centre, TPointD(-point.x + 0.5, -point.y - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 0.5) + centre, TPointD(-point.y - 0.5, -point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre, TPointD(-point.y - 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, point.y + 0.5) + centre, TPointD(-point.x - 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 0.5, point.y + 1.5) + centre, TPointD(point.x - 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 0.5, point.y + 0.5) + centre, TPointD(point.x + 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 1.5, point.x - 0.5) + centre, TPointD(point.y + 0.5, point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 0.5, point.x - 0.5) + centre, TPointD(point.y + 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 1.5, -point.x + 0.5) + centre, TPointD(point.y + 0.5, -point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.y + 0.5, -point.x + 0.5) + centre, TPointD(point.y + 0.5, -point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 0.5, -point.y - 1.5) + centre, TPointD(point.x - 0.5, -point.y - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(point.x - 0.5, -point.y - 0.5) + centre, TPointD(point.x + 0.5, -point.y - 0.5) + centre);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, -point.y - 1.5) + centre, TPointD(-point.x + 0.5, -point.y - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, -point.y - 0.5) + centre, TPointD(-point.x - 0.5, -point.y - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 1.5, -point.x + 0.5) + centre, TPointD(-point.y - 0.5, -point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, -point.x + 0.5) + centre, TPointD(-point.y - 0.5, -point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 1.5, point.x - 0.5) + centre, TPointD(-point.y - 0.5, point.x - 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.y - 0.5, point.x - 0.5) + centre, TPointD(-point.y - 0.5, point.x + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, point.y + 1.5) + centre, TPointD(-point.x + 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
			tglDrawSegment(TPointD(-point.x + 0.5, point.y + 0.5) + centre, TPointD(-point.x - 0.5, point.y + 0.5) + centre);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void drawEmptyCircle(int thick, const TPointD &mousePos, bool isPencil, bool isLxEven, bool isLyEven)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD pos = mousePos;
Toshihiro Shimizu 890ddd
	if (isLxEven)
Toshihiro Shimizu 890ddd
		pos.x += 0.5;
Toshihiro Shimizu 890ddd
	if (isLyEven)
Toshihiro Shimizu 890ddd
		pos.y += 0.5;
Toshihiro Shimizu 890ddd
	if (!isPencil)
Toshihiro Shimizu 890ddd
		tglDrawCircle(pos, (thick + 1) * 0.5);
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		int x = 0, y = tround((thick * 0.5) - 0.5);
Toshihiro Shimizu 890ddd
		int d = 3 - 2 * (int)(thick * 0.5);
Toshihiro Shimizu 890ddd
		bool horizontal = true, isDecimal = thick % 2 != 0;
Toshihiro Shimizu 890ddd
		drawLine(TPointD(x, y), pos, horizontal, isDecimal);
Toshihiro Shimizu 890ddd
		while (y > x) {
Toshihiro Shimizu 890ddd
			if (d < 0) {
Toshihiro Shimizu 890ddd
				d = d + 4 * x + 6;
Toshihiro Shimizu 890ddd
				horizontal = true;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				d = d + 4 * (x - y) + 10;
Toshihiro Shimizu 890ddd
				horizontal = false;
Toshihiro Shimizu 890ddd
				y--;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			x++;
Toshihiro Shimizu 890ddd
			drawLine(TPointD(x, y), pos, horizontal, isDecimal);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class FingerTool : public TTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Q_DECLARE_TR_FUNCTIONS(FingerTool)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RasterStrokeGenerator *m_rasterTrack;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_firstTime;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double m_pointSize, m_distance2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_selecting;
Toshihiro Shimizu 890ddd
	TTileSaverCM32 *m_tileSaver;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD m_mousePos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TIntProperty m_toolSize;
Toshihiro Shimizu 890ddd
	TBoolProperty m_invert;
Toshihiro Shimizu 890ddd
	TPropertyGroup m_prop;
Toshihiro Shimizu 890ddd
	int m_cursor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*---	作業中のFrameIdをクリック時に保存し、マウスリリース時(Undoの登録時)
Toshihiro Shimizu 890ddd
			に別のフレームに移動している場合があるため ---*/
Toshihiro Shimizu 890ddd
	TFrameId m_workingFrameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*-- 最初のクリックでStyleを切り替える --*/
Toshihiro Shimizu 890ddd
	void pick(const TPointD &pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	FingerTool();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void draw();
Toshihiro Shimizu 890ddd
	void update(TToonzImageP ti, TRectD area);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void updateTranslation();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void leftButtonDown(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonDrag(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void leftButtonUp(const TPointD &pos, const TMouseEvent &);
Toshihiro Shimizu 890ddd
	void mouseMove(const TPointD &pos, const TMouseEvent &e);
Toshihiro Shimizu 890ddd
	void onEnter();
Toshihiro Shimizu 890ddd
	void onLeave();
Toshihiro Shimizu 890ddd
	void onActivate();
Toshihiro Shimizu 890ddd
	void onDeactivate();
Toshihiro Shimizu 890ddd
	bool onPropertyChanged(string propertyName);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPropertyGroup *getProperties(int targetType) { return &m_prop; }
Toshihiro Shimizu 890ddd
	ToolType getToolType() const { return TTool::LevelWriteTool; }
Toshihiro Shimizu 890ddd
	int getCursorId() const { return m_cursor; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getColorClass() const { return 2; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*-- ドラッグ中にツールが切り替わった場合に備え、onDeactivateにもMouseReleaseと同じ処理を行う --*/
Toshihiro Shimizu 890ddd
	void finishBrush();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FingerTool fingerTool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//  InkPaintTool implemention
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FingerTool::FingerTool()
Toshihiro Shimizu 890ddd
	: TTool("T_Finger"), m_rasterTrack(0), m_pointSize(-1), m_selecting(false), m_tileSaver(0), m_cursor(ToolCursor::EraserCursor), m_toolSize("Size:", 1, 100, 10, false), m_invert("Invert", false), m_firstTime(true), m_workingFrameId(TFrameId())
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	bind(TTool::ToonzImage);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_prop.bind(m_toolSize);
Toshihiro Shimizu 890ddd
	m_prop.bind(m_invert);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_invert.setId("Invert");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::updateTranslation()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_toolSize.setQStringName(tr("Size:"));
Toshihiro Shimizu 890ddd
	m_invert.setQStringName(tr("Invert", NULL));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::draw()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pointSize == -1) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TToonzImageP ti = (TToonzImageP)getImage(false);
Toshihiro Shimizu 890ddd
	if (!ti)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TRasterP ras = ti->getRaster();
Toshihiro Shimizu 890ddd
	int lx = ras->getLx();
Toshihiro Shimizu 890ddd
	int ly = ras->getLy();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((ToonzCheck::instance()->getChecks() & ToonzCheck::eInk) || (ToonzCheck::instance()->getChecks() & ToonzCheck::ePaint))
Toshihiro Shimizu 890ddd
		glColor3d(0.5, 0.8, 0.8);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		glColor3d(1.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	drawEmptyCircle(m_toolSize.getValue(), m_mousePos, true, lx % 2 == 0, ly % 2 == 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const UINT pointCount = 20;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool FingerTool::onPropertyChanged(string propertyName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*-- サイズ --*/
Toshihiro Shimizu 890ddd
	if (propertyName == m_toolSize.getName()) {
Toshihiro Shimizu 890ddd
		FingerSize = m_toolSize.getValue();
Toshihiro Shimizu 890ddd
		double x = m_toolSize.getValue();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double minRange = 1;
Toshihiro Shimizu 890ddd
		double maxRange = 100;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double minSize = 0.01;
Toshihiro Shimizu 890ddd
		double maxSize = 100;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_pointSize = (x - minRange) / (maxRange - minRange) * (maxSize - minSize) + minSize;
Toshihiro Shimizu 890ddd
		invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Invert
Toshihiro Shimizu 890ddd
	else if (propertyName == m_invert.getName()) {
Toshihiro Shimizu 890ddd
		FingerInvert = (int)(m_invert.getValue());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	pick(pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_selecting = true;
Toshihiro Shimizu 890ddd
	TImageP image(getImage(true));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (TToonzImageP ti = image) {
Toshihiro Shimizu 890ddd
		TRasterCM32P ras = ti->getRaster();
Toshihiro Shimizu 890ddd
		if (ras) {
Toshihiro Shimizu 890ddd
			int thickness = m_toolSize.getValue();
Toshihiro Shimizu 890ddd
			int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
Toshihiro Shimizu 890ddd
			TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
Toshihiro Shimizu 890ddd
			m_tileSaver = new TTileSaverCM32(ras, tileSet);
Toshihiro Shimizu 890ddd
			m_rasterTrack = new RasterStrokeGenerator(ras,
Toshihiro Shimizu 890ddd
													  FINGER,
Toshihiro Shimizu 890ddd
													  INK,
Toshihiro Shimizu 890ddd
													  styleId,
Toshihiro Shimizu 890ddd
													  TThickPoint(pos + convert(ras->getCenter()), thickness),
Toshihiro Shimizu 890ddd
													  m_invert.getValue(),
Toshihiro Shimizu 890ddd
													  0,
Toshihiro Shimizu 890ddd
													  false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*-- 作業中Fidを現在のFIDにする --*/
Toshihiro Shimizu 890ddd
			m_workingFrameId = getFrameId();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_tileSaver->save(m_rasterTrack->getLastRect());
Toshihiro Shimizu 890ddd
			TRect modifiedBbox = m_rasterTrack->generateLastPieceOfStroke(true);
Toshihiro Shimizu 890ddd
			invalidate();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_selecting)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_mousePos = pos;
Toshihiro Shimizu 890ddd
	if (TToonzImageP ri = TImageP(getImage(true))) {
Toshihiro Shimizu 890ddd
		/*---	マウスを動かしながらショートカットで切り替わった場合、
Toshihiro Shimizu 890ddd
				いきなりleftButtonDragから呼ばれることがあり、
Toshihiro Shimizu 890ddd
				m_rasterTrackが無くて落ちることがある。 ---*/
Toshihiro Shimizu 890ddd
		if (m_rasterTrack) {
Toshihiro Shimizu 890ddd
			int thickness = m_toolSize.getValue();
Toshihiro Shimizu 890ddd
			bool isAdded = m_rasterTrack->add(TThickPoint(pos + convert(ri->getRaster()->getCenter()), thickness));
Toshihiro Shimizu 890ddd
			if (isAdded) {
Toshihiro Shimizu 890ddd
				m_tileSaver->save(m_rasterTrack->getLastRect());
Toshihiro Shimizu 890ddd
				TRect modifiedBbox = m_rasterTrack->generateLastPieceOfStroke(true);
Toshihiro Shimizu 890ddd
				invalidate();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::leftButtonUp(const TPointD &pos, const TMouseEvent &)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_selecting)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_mousePos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	finishBrush();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::mouseMove(const TPointD &pos, const TMouseEvent &e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_mousePos = pos;
Toshihiro Shimizu 890ddd
	TPointD pp(tround(pos.x), tround(pos.y));
Toshihiro Shimizu 890ddd
	m_mousePos = pp;
Toshihiro Shimizu 890ddd
	invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::onEnter()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_firstTime) {
Toshihiro Shimizu 890ddd
		m_invert.setValue(FingerInvert ? 1 : 0);
Toshihiro Shimizu 890ddd
		m_toolSize.setValue(FingerSize);
Toshihiro Shimizu 890ddd
		m_firstTime = false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	double x = m_toolSize.getValue();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double minRange = 1;
Toshihiro Shimizu 890ddd
	double maxRange = 100;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double minSize = 0.01;
Toshihiro Shimizu 890ddd
	double maxSize = 100;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_pointSize = (x - minRange) / (maxRange - minRange) * (maxSize - minSize) + minSize;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((TToonzImageP)getImage(false))
Toshihiro Shimizu 890ddd
		m_cursor = ToolCursor::PenCursor;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_cursor = ToolCursor::CURSOR_NO;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::onLeave()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_pointSize = -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::onActivate()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	onEnter();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::onDeactivate()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*--- マウスドラッグ中(m_selecting=true)にツールが切り替わったときに線を終わらせる ---*/
Toshihiro Shimizu 890ddd
	if (m_selecting)
Toshihiro Shimizu 890ddd
		finishBrush();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! ドラッグ中にツールが切り替わった場合に備え、onDeactivateにもMouseReleaseと同じ処理を行う
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
void FingerTool::finishBrush()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TToonzImageP ti = (TToonzImageP)getImage(true)) {
Toshihiro Shimizu 890ddd
		if (m_rasterTrack) {
Toshihiro Shimizu 890ddd
			int thickness = m_toolSize.getValue();
Toshihiro Shimizu 890ddd
			bool isAdded = m_rasterTrack->add(TThickPoint(m_mousePos + convert(ti->getRaster()->getCenter()), thickness));
Toshihiro Shimizu 890ddd
			if (isAdded) {
Toshihiro Shimizu 890ddd
				m_tileSaver->save(m_rasterTrack->getLastRect());
Toshihiro Shimizu 890ddd
				TRect modifiedBbox = m_rasterTrack->generateLastPieceOfStroke(true, true);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
			TXshLevel *level = app->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
			TXshSimpleLevelP simLevel = level->getSimpleLevel();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TFrameId frameId = m_workingFrameId.isEmptyFrame() ? getCurrentFid() : m_workingFrameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TUndoManager::manager()->add(new FingerUndo(m_tileSaver->getTileSet(),
Toshihiro Shimizu 890ddd
														m_rasterTrack->getPointsSequence(),
Toshihiro Shimizu 890ddd
														m_rasterTrack->getStyleId(),
Toshihiro Shimizu 890ddd
														m_rasterTrack->isSelective(),
Toshihiro Shimizu 890ddd
														simLevel.getPointer(),
Toshihiro Shimizu 890ddd
														frameId));
Toshihiro Shimizu 890ddd
			ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*! FIdを指定して、作業中にフレームが動いても、
Toshihiro Shimizu 890ddd
				クリック時のFidのサムネイルが更新されるようにする。
Toshihiro Shimizu 890ddd
			*/
Toshihiro Shimizu 890ddd
			notifyImageChanged(frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			invalidate();
Toshihiro Shimizu 890ddd
			delete m_rasterTrack;
Toshihiro Shimizu 890ddd
			m_rasterTrack = 0;
Toshihiro Shimizu 890ddd
			delete m_tileSaver;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*-- 作業中fIdをリセット --*/
Toshihiro Shimizu 890ddd
			m_workingFrameId = TFrameId();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_selecting = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FingerTool::pick(const TPointD &pos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int modeValue = 2; //LINES
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageP image = getImage(false);
Toshihiro Shimizu 890ddd
	TToonzImageP ti = image;
Toshihiro Shimizu 890ddd
	TVectorImageP vi = image;
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *level = getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!ti || !level)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*--- 画面外をpickしても拾えないようにする ---*/
Toshihiro Shimizu 890ddd
	if (!m_viewer->getGeometry().contains(pos))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int subsampling = level->getImageSubsampling(getCurrentFid());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StylePicker picker(image);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int styleId = picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
Toshihiro Shimizu 890ddd
									 getPixelSize() * getPixelSize(),
Toshihiro Shimizu 890ddd
									 modeValue);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (styleId < 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (modeValue == 2) //LINES
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		/*--- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。 ---*/
Toshihiro Shimizu 890ddd
		if (styleId == 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*--- pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない ---*/
Toshihiro Shimizu 890ddd
		if (ti && picker.pickTone(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5)) == 255)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*--- Styleを選択している場合は選択を解除する ---*/
Toshihiro Shimizu 890ddd
	TSelection *selection = TTool::getApplication()->getCurrentSelection()->getSelection();
Toshihiro Shimizu 890ddd
	if (selection) {
Toshihiro Shimizu 890ddd
		TStyleSelection *styleSelection = dynamic_cast<tstyleselection *="">(selection);</tstyleselection>
Toshihiro Shimizu 890ddd
		if (styleSelection)
Toshihiro Shimizu 890ddd
			styleSelection->selectNone();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	getApplication()->setCurrentLevelStyleIndex(styleId);
Toshihiro Shimizu 890ddd
}