Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "functionpaneltools.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/functionselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
#include <qmouseevent></qmouseevent>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MoveFrameDragTool::MoveFrameDragTool(FunctionPanel *panel, TFrameHandle *frameHandle)
Toshihiro Shimizu 890ddd
	: m_panel(panel), m_frameHandle(frameHandle)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveFrameDragTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double frame = m_panel->xToFrame(e->pos().x());
Toshihiro Shimizu 890ddd
	m_panel->getSelection()->deselectAllKeyframes();
Toshihiro Shimizu 890ddd
	m_frameHandle->setFrame(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PanDragTool::PanDragTool(FunctionPanel *panel, bool xLocked, bool yLocked)
Toshihiro Shimizu 890ddd
	: m_panel(panel), m_xLocked(xLocked), m_yLocked(yLocked)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PanDragTool::click(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_oldPos = e->pos();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void PanDragTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QPoint delta = e->pos() - m_oldPos;
Toshihiro Shimizu 890ddd
	if (m_xLocked)
Toshihiro Shimizu 890ddd
		delta.setX(0);
Toshihiro Shimizu 890ddd
	if (m_yLocked)
Toshihiro Shimizu 890ddd
		delta.setY(0);
Toshihiro Shimizu 890ddd
	m_panel->pan(delta);
Toshihiro Shimizu 890ddd
	m_oldPos = e->pos();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*--- Ruler部分ドラッグによるズーム ---*/
Toshihiro Shimizu 890ddd
void ZoomDragTool::click(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_startPos = m_oldPos = m_startPos = e->pos();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ZoomDragTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QPoint delta = e->pos() - m_oldPos;
Toshihiro Shimizu 890ddd
	m_oldPos = e->pos();
Toshihiro Shimizu 890ddd
	double sx = 1, sy = 1;
Toshihiro Shimizu 890ddd
	//reflect horizontal drag for frame zoom
Toshihiro Shimizu 890ddd
	double zoomFactor = exp(-0.0075 * ((m_zoomType == FrameZoom) ? -delta.x() : delta.y()));
Toshihiro Shimizu 890ddd
	if (m_zoomType == FrameZoom)
Toshihiro Shimizu 890ddd
		sx = zoomFactor;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		sy = zoomFactor;
Toshihiro Shimizu 890ddd
	m_panel->zoom(sx, sy, m_startPos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ZoomDragTool::release(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if ((e->pos() - m_startPos).manhattanLength() < 2) {
Toshihiro Shimizu 890ddd
		double frame = m_panel->xToFrame(e->pos().x());
Toshihiro Shimizu 890ddd
		if (m_panel->getFrameHandle())
Toshihiro Shimizu 890ddd
			m_panel->getFrameHandle()->setFrame(frame);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectSelectTool::click(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_startPos = e->pos();
Toshihiro Shimizu 890ddd
	m_rect = QRect();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectSelectTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_rect = QRect(m_startPos, e->pos()).normalized();
Toshihiro Shimizu 890ddd
	m_panel->getSelection()->deselectAllKeyframes();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < m_curve->getKeyframeCount(); i++) {
Toshihiro Shimizu 890ddd
		QPointF p = m_panel->getWinPos(m_curve, m_curve->getKeyframe(i));
Toshihiro Shimizu 890ddd
		if (m_rect.contains(tround(p.x()), tround(p.y())))
Toshihiro Shimizu 890ddd
			m_panel->getSelection()->select(m_curve, i);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_panel->update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectSelectTool::release(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_panel->update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RectSelectTool::draw(QPainter &painter)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	painter.setPen(Qt::white);
Toshihiro Shimizu 890ddd
	painter.setBrush(QColor(255, 255, 255, 127));
Toshihiro Shimizu 890ddd
	if (!m_rect.isEmpty())
Toshihiro Shimizu 890ddd
		painter.drawRect(m_rect);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MovePointDragTool::MovePointDragTool(
Toshihiro Shimizu 890ddd
	FunctionPanel *panel,
Toshihiro Shimizu 890ddd
	TDoubleParam *curve)
Toshihiro Shimizu 890ddd
	: m_panel(panel), m_deltaFrame(0), m_speed0Length(0), m_speed0Index(-1), m_speed1Length(0), m_speed1Index(-1), m_groupEnabled(false), m_selection(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->beginBlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (curve) {
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = new KeyframeSetter(curve);
Toshihiro Shimizu 890ddd
		m_setters.push_back(setter);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		m_groupEnabled = true;
Toshihiro Shimizu 890ddd
		FunctionTreeModel *model = panel->getModel();
Toshihiro Shimizu 890ddd
		for (int i = 0; i < model->getActiveChannelCount(); i++) {
Toshihiro Shimizu 890ddd
			FunctionTreeModel::Channel *channel = model->getActiveChannel(i);
Toshihiro Shimizu 890ddd
			if (channel && channel->getParam()) {
Toshihiro Shimizu 890ddd
				TDoubleParam *curve = channel->getParam();
Toshihiro Shimizu 890ddd
				KeyframeSetter *setter = new KeyframeSetter(curve);
Toshihiro Shimizu 890ddd
				m_setters.push_back(setter);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MovePointDragTool::~MovePointDragTool()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++)
Toshihiro Shimizu 890ddd
		delete m_setters[i];
Toshihiro Shimizu 890ddd
	m_setters.clear();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->endBlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MovePointDragTool::addKeyframe2(int kIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(m_setters.size() == 1);
Toshihiro Shimizu 890ddd
	if (m_setters.size() == 1)
Toshihiro Shimizu 890ddd
		m_setters[0]->selectKeyframe(kIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MovePointDragTool::createKeyframe(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++) {
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = m_setters[i];
Toshihiro Shimizu 890ddd
		int kIndex = setter->createKeyframe(tround(frame));
Toshihiro Shimizu 890ddd
		setter->selectKeyframe(kIndex);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MovePointDragTool::selectKeyframes(double frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++) {
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = m_setters[i];
Toshihiro Shimizu 890ddd
		TDoubleParam *curve = setter->getCurve();
Toshihiro Shimizu 890ddd
		setter->setPixelRatio(m_panel->getPixelRatio(curve));
Toshihiro Shimizu 890ddd
		int kIndex = curve->getClosestKeyframe(frame);
Toshihiro Shimizu 890ddd
		if (kIndex >= 0) {
Toshihiro Shimizu 890ddd
			double kf = curve->keyframeIndexToFrame(kIndex);
Toshihiro Shimizu 890ddd
			if (fabs(kf - frame) < 0.01)
Toshihiro Shimizu 890ddd
				setter->selectKeyframe(kIndex);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MovePointDragTool::setSelection(FunctionSelection *selection)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (selection) {
Toshihiro Shimizu 890ddd
		assert(m_setters.size() == 1);
Toshihiro Shimizu 890ddd
		if (m_setters.size() == 1) {
Toshihiro Shimizu 890ddd
			TDoubleParam *curve = m_setters[0]->getCurve();
Toshihiro Shimizu 890ddd
			assert(curve);
Toshihiro Shimizu 890ddd
			if (curve) {
Toshihiro Shimizu 890ddd
				m_selection = selection;
Toshihiro Shimizu 890ddd
				for (int i = 0; i < curve->getKeyframeCount(); i++)
Toshihiro Shimizu 890ddd
					if (selection->isSelected(curve, i))
Toshihiro Shimizu 890ddd
						addKeyframe2(i);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_selection = selection;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MovePointDragTool::click(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_startPos = m_oldPos = e->pos();
Toshihiro Shimizu 890ddd
	m_deltaFrame = 0;
Toshihiro Shimizu 890ddd
	double frame = m_panel->xToFrame(e->pos().x());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++) {
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = m_setters[i];
Toshihiro Shimizu 890ddd
		TDoubleParam *curve = setter->getCurve();
Toshihiro Shimizu 890ddd
		setter->setPixelRatio(m_panel->getPixelRatio(curve));
Toshihiro Shimizu 890ddd
		if (!m_groupEnabled) {
Toshihiro Shimizu 890ddd
			int kIndex = curve->getClosestKeyframe(frame);
Toshihiro Shimizu 890ddd
			if (kIndex >= 0) {
Toshihiro Shimizu 890ddd
				double kf = curve->keyframeIndexToFrame(kIndex);
Toshihiro Shimizu 890ddd
				if (fabs(kf - frame) < 1)
Toshihiro Shimizu 890ddd
					setter->selectKeyframe(kIndex);
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 MovePointDragTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// need ctrl modifier
Toshihiro Shimizu 890ddd
	if (0 == (e->modifiers() & Qt::ControlModifier))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QPoint pos = e->pos();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// if shift is pressed then apply constraints (only horizontal or vertical moves)
Toshihiro Shimizu 890ddd
	if (e->modifiers() & Qt::ShiftModifier) {
Toshihiro Shimizu 890ddd
		QPoint delta = e->pos() - m_startPos;
Toshihiro Shimizu 890ddd
		if (abs(delta.x()) > abs(delta.y()))
Toshihiro Shimizu 890ddd
			pos.setY(m_startPos.y());
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			pos.setX(m_startPos.x());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_groupEnabled)
Toshihiro Shimizu 890ddd
		pos.setY(m_startPos.y());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QPoint oldPos = m_oldPos;
Toshihiro Shimizu 890ddd
	m_oldPos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// compute frame increment. it must be an integer
Toshihiro Shimizu 890ddd
	double totalDFrame = tround(
Toshihiro Shimizu 890ddd
		m_panel->xToFrame(pos.x()) -
Toshihiro Shimizu 890ddd
		m_panel->xToFrame(m_startPos.x()));
Toshihiro Shimizu 890ddd
	double dFrame = totalDFrame - m_deltaFrame;
Toshihiro Shimizu 890ddd
	m_deltaFrame = totalDFrame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++) {
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = m_setters[i];
Toshihiro Shimizu 890ddd
		TDoubleParam *curve = setter->getCurve();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// compute value increment
Toshihiro Shimizu 890ddd
		double dValue =
Toshihiro Shimizu 890ddd
			m_panel->yToValue(curve, pos.y()) -
Toshihiro Shimizu 890ddd
			m_panel->yToValue(curve, oldPos.y());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		setter->moveKeyframes(dFrame, dValue);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_selection != 0 && m_setters.size() == 1) {
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = m_setters[0];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_selection->deselectAllKeyframes();
Toshihiro Shimizu 890ddd
		for (int i = 0; i < setter->getCurve()->getKeyframeCount(); i++)
Toshihiro Shimizu 890ddd
			if (setter->isSelected(i))
Toshihiro Shimizu 890ddd
				m_selection->select(setter->getCurve(), i);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_panel->update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MovePointDragTool::release(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MoveHandleDragTool::MoveHandleDragTool(
Toshihiro Shimizu 890ddd
	FunctionPanel *panel,
Toshihiro Shimizu 890ddd
	TDoubleParam *curve,
Toshihiro Shimizu 890ddd
	int kIndex,
Toshihiro Shimizu 890ddd
	Handle handle)
Toshihiro Shimizu 890ddd
	: m_panel(panel), m_curve(curve), m_kIndex(kIndex), m_handle(handle), m_deltaFrame(0), m_setter(curve, kIndex), m_segmentWidth(0), m_channelGroup(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveHandleDragTool::click(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_startPos = e->pos();
Toshihiro Shimizu 890ddd
	// m_startPos = m_oldPos = e->pos();
Toshihiro Shimizu 890ddd
	m_deltaFrame = 0;
Toshihiro Shimizu 890ddd
	m_keyframe = m_curve->getKeyframe(m_kIndex);
Toshihiro Shimizu 890ddd
	m_keyframe.m_value = m_curve->getValue(m_keyframe.m_frame);
Toshihiro Shimizu 890ddd
	if (m_handle == FunctionPanel::SpeedIn)
Toshihiro Shimizu 890ddd
		m_keyframe.m_value = m_curve->getValue(m_keyframe.m_frame, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_channelGroup) {
Toshihiro Shimizu 890ddd
		for (int i = 0; i < m_channelGroup->getChildCount(); i++) {
Toshihiro Shimizu 890ddd
			TreeModel::Item *child = m_channelGroup->getChild(i);
Toshihiro Shimizu 890ddd
			FunctionTreeModel::Channel *channel = dynamic_cast<functiontreemodel::channel *="">(child);</functiontreemodel::channel>
Toshihiro Shimizu 890ddd
			if (channel && m_curve != channel->getParam()) {
Toshihiro Shimizu 890ddd
				if (channel->getParam()->isKeyframe(m_keyframe.m_frame)) {
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_handle == FunctionPanel::EaseInPercentage && m_kIndex > 0) {
Toshihiro Shimizu 890ddd
		double previousFrame = m_curve->keyframeIndexToFrame(m_kIndex - 1);
Toshihiro Shimizu 890ddd
		m_segmentWidth = m_keyframe.m_frame - previousFrame;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_handle == FunctionPanel::EaseOutPercentage && m_kIndex + 1 < m_curve->getKeyframeCount()) {
Toshihiro Shimizu 890ddd
		double nextFrame = m_curve->keyframeIndexToFrame(m_kIndex + 1);
Toshihiro Shimizu 890ddd
		m_segmentWidth = nextFrame - m_keyframe.m_frame;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TPointD speed;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_keyframe.m_linkedHandles) {
Toshihiro Shimizu 890ddd
		if (m_handle == FunctionPanel::SpeedIn && m_kIndex + 1 < m_curve->getKeyframeCount() && (m_keyframe.m_type != TDoubleKeyframe::SpeedInOut && (m_keyframe.m_type != TDoubleKeyframe::Expression ||
Shinya Kitaoka 3bfa54
																																					  m_keyframe.m_expressionText.find("cycle") == std::string::npos)))
Toshihiro Shimizu 890ddd
			speed = m_curve->getSpeedIn(m_kIndex);
Toshihiro Shimizu 890ddd
		else if (m_handle == FunctionPanel::SpeedOut && m_keyframe.m_prevType != TDoubleKeyframe::SpeedInOut && m_kIndex > 0)
Toshihiro Shimizu 890ddd
			speed = m_curve->getSpeedOut(m_kIndex);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (norm2(speed) > 0.001) {
Toshihiro Shimizu 890ddd
		QPointF a = m_panel->getWinPos(m_curve, speed) - m_panel->getWinPos(m_curve, TPointD());
Toshihiro Shimizu 890ddd
		double aa = 1.0 / sqrt(a.x() * a.x() + a.y() * a.y());
Toshihiro Shimizu 890ddd
		m_nSpeed = QPointF(-a.y() * aa, a.x() * aa);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_nSpeed = QPointF();
Toshihiro Shimizu 890ddd
	m_setter.setPixelRatio(m_panel->getPixelRatio(m_curve));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveHandleDragTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//need ctrl modifier
Toshihiro Shimizu 890ddd
	if (0 == (e->modifiers() & Qt::ControlModifier))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_curve)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QPoint pos = e->pos();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// if shift is pressed then apply constraints (only horizontal or vertical moves)
Toshihiro Shimizu 890ddd
	if (e->modifiers() & Qt::ShiftModifier) {
Toshihiro Shimizu 890ddd
		QPoint delta = e->pos() - m_startPos;
Toshihiro Shimizu 890ddd
		if (abs(delta.x()) > abs(delta.y()))
Toshihiro Shimizu 890ddd
			pos.setY(m_startPos.y());
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			pos.setX(m_startPos.x());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//QPoint oldPos = m_oldPos;
Toshihiro Shimizu 890ddd
	//m_oldPos = pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QPointF p0 = m_panel->getWinPos(m_curve, m_keyframe);
Toshihiro Shimizu 890ddd
	QPointF posF(pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_nSpeed != QPointF(0, 0)) {
Toshihiro Shimizu 890ddd
		QPointF delta = posF - p0;
Toshihiro Shimizu 890ddd
		posF -= m_nSpeed * (delta.x() * m_nSpeed.x() + delta.y() * m_nSpeed.y());
Michał Janiszewski b1cc3c
		if ((m_handle == FunctionPanel::SpeedIn && posF.x() > p0.x()) || (m_handle == FunctionPanel::SpeedOut && posF.x() < p0.x()))
Toshihiro Shimizu 890ddd
			posF = p0;
Toshihiro Shimizu 890ddd
	} else {
Michał Janiszewski b1cc3c
		if ((m_handle == FunctionPanel::SpeedIn && posF.x() > p0.x()) || (m_handle == FunctionPanel::SpeedOut && posF.x() < p0.x()))
Toshihiro Shimizu 890ddd
			posF.setX(p0.x());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double frame = m_panel->xToFrame(posF.x());
Toshihiro Shimizu 890ddd
	double value = m_panel->yToValue(m_curve, posF.y());
Toshihiro Shimizu 890ddd
	TPointD handlePos(frame - m_keyframe.m_frame, value - m_keyframe.m_value);
Toshihiro Shimizu 890ddd
	switch (m_handle) {
Toshihiro Shimizu 890ddd
	case FunctionPanel::SpeedIn:
Toshihiro Shimizu 890ddd
		if (m_keyframe.m_type != TDoubleKeyframe::SpeedInOut) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_setter.setSpeedIn(handlePos);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case FunctionPanel::SpeedOut:
Toshihiro Shimizu 890ddd
		m_setter.setSpeedOut(handlePos);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case FunctionPanel::EaseIn:
Toshihiro Shimizu 890ddd
		m_setter.setEaseIn(handlePos.x);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case FunctionPanel::EaseOut:
Toshihiro Shimizu 890ddd
		m_setter.setEaseOut(handlePos.x);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case FunctionPanel::EaseInPercentage:
Toshihiro Shimizu 890ddd
		if (m_segmentWidth > 0)
Toshihiro Shimizu 890ddd
			m_setter.setEaseIn(100.0 * handlePos.x / m_segmentWidth);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case FunctionPanel::EaseOutPercentage:
Toshihiro Shimizu 890ddd
		if (m_segmentWidth > 0)
Toshihiro Shimizu 890ddd
			m_setter.setEaseOut(100.0 * handlePos.x / m_segmentWidth);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case 100:
Toshihiro Shimizu 890ddd
	case 101:
Toshihiro Shimizu 890ddd
	case 102:
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	default:
Toshihiro Shimizu 890ddd
		assert(0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_panel->update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveHandleDragTool::release(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MoveGroupHandleDragTool::MoveGroupHandleDragTool(
Toshihiro Shimizu 890ddd
	FunctionPanel *panel,
Toshihiro Shimizu 890ddd
	double keyframePosition,
Toshihiro Shimizu 890ddd
	Handle handle)
Toshihiro Shimizu 890ddd
	: m_panel(panel), m_keyframePosition(keyframePosition), m_handle(handle)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->beginBlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MoveGroupHandleDragTool::~MoveGroupHandleDragTool()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++)
Toshihiro Shimizu 890ddd
		delete m_setters[i].second;
Toshihiro Shimizu 890ddd
	m_setters.clear();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->endBlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveGroupHandleDragTool::click(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++)
Toshihiro Shimizu 890ddd
		delete m_setters[i].second;
Toshihiro Shimizu 890ddd
	m_setters.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FunctionTreeModel *model = m_panel->getModel();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < model->getActiveChannelCount(); i++) {
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *channel = model->getActiveChannel(i);
Toshihiro Shimizu 890ddd
		if (channel && channel->getParam()) {
Toshihiro Shimizu 890ddd
			TDoubleParam *curve = channel->getParam();
Toshihiro Shimizu 890ddd
			int kIndex = curve->getClosestKeyframe(m_keyframePosition);
Toshihiro Shimizu 890ddd
			KeyframeSetter *setter = new KeyframeSetter(curve, kIndex);
Toshihiro Shimizu 890ddd
			setter->setPixelRatio(m_panel->getPixelRatio(curve));
Toshihiro Shimizu 890ddd
			TDoubleKeyframe kf = curve->getKeyframe(kIndex);
Toshihiro Shimizu 890ddd
			m_setters.push_back(std::make_pair(kf, setter));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveGroupHandleDragTool::drag(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//  if(!m_curve) return;
Toshihiro Shimizu 890ddd
	QPoint pos = e->pos();
Toshihiro Shimizu 890ddd
	QPointF posF(pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  if(m_nSpeed != QPointF(0,0))
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    QPointF delta = posF-p0;
Toshihiro Shimizu 890ddd
    posF -= m_nSpeed*(delta.x()*m_nSpeed.x()+delta.y()*m_nSpeed.y());
Toshihiro Shimizu 890ddd
    if(  m_handle == FunctionPanel::SpeedIn && posF.x()>p0.x() 
Toshihiro Shimizu 890ddd
      || m_handle == FunctionPanel::SpeedOut && posF.x()
Toshihiro Shimizu 890ddd
      posF = p0;   
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
  else
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    if(  m_handle == FunctionPanel::SpeedIn && posF.x()>p0.x() 
Toshihiro Shimizu 890ddd
      || m_handle == FunctionPanel::SpeedOut && posF.x()
Toshihiro Shimizu 890ddd
      posF.setX(p0.x());   
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double frame = m_panel->xToFrame(posF.x());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++) {
Toshihiro Shimizu 890ddd
		TDoubleKeyframe kf = m_setters[i].first;
Toshihiro Shimizu 890ddd
		KeyframeSetter *setter = m_setters[i].second;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_handle == 101) // why the magic numbers... use enums!
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			kf.m_speedOut.x = frame - kf.m_frame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			switch (kf.m_type) {
Toshihiro Shimizu 890ddd
			case TDoubleKeyframe::SpeedInOut:
Toshihiro Shimizu 890ddd
				setter->setSpeedOut(kf.m_speedOut);
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			case TDoubleKeyframe::EaseInOut:
Shinya Kitaoka d4642c
				setter->setEaseOut(kf.m_speedOut.x);
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			default:
Toshihiro Shimizu 890ddd
				assert(false);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (m_handle == 102) // aagghhrrr
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			kf.m_speedIn.x = frame - kf.m_frame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			switch (kf.m_prevType) {
Toshihiro Shimizu 890ddd
			case TDoubleKeyframe::SpeedInOut:
Toshihiro Shimizu 890ddd
				setter->setSpeedIn(kf.m_speedIn);
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			case TDoubleKeyframe::EaseInOut:
Shinya Kitaoka d4642c
				setter->setEaseIn(kf.m_speedIn.x);
Shinya Kitaoka d4642c
				break;
Shinya Kitaoka d4642c
			default:
Toshihiro Shimizu 890ddd
				assert(false);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  switch(m_handle)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  case FunctionPanel::SpeedIn:
Toshihiro Shimizu 890ddd
    if(m_keyframe.m_type != TDoubleKeyframe::SpeedInOut)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
    m_setter.setSpeedIn(handlePos); 
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
  case FunctionPanel::SpeedOut:m_setter.setSpeedOut(handlePos); break;
Toshihiro Shimizu 890ddd
  case FunctionPanel::EaseIn:m_setter.setEaseIn(handlePos.x); break;
Toshihiro Shimizu 890ddd
  case FunctionPanel::EaseOut:m_setter.setEaseOut(handlePos.x); break;
Toshihiro Shimizu 890ddd
  case FunctionPanel::EaseInPercentage:
Toshihiro Shimizu 890ddd
    if(m_segmentWidth>0) 
Toshihiro Shimizu 890ddd
      m_setter.setEaseIn(100.0*handlePos.x/m_segmentWidth); 
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
  case FunctionPanel::EaseOutPercentage:
Toshihiro Shimizu 890ddd
    if(m_segmentWidth>0) 
Toshihiro Shimizu 890ddd
      m_setter.setEaseOut(100.0*handlePos.x/m_segmentWidth); 
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
  case 100:
Toshihiro Shimizu 890ddd
  case 101:
Toshihiro Shimizu 890ddd
  case 102:
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
  default:assert(0);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
	m_panel->update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void MoveGroupHandleDragTool::release(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)m_setters.size(); i++)
Toshihiro Shimizu 890ddd
		delete m_setters[i].second;
Toshihiro Shimizu 890ddd
	m_setters.clear();
Toshihiro Shimizu 890ddd
}