|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/functionpanel.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzQt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/functionselection.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/functionsegmentviewer.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/imageutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "functionpaneltools.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/gutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzLib includes
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tframehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/doubleparamcmd.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzfolders.h"
|
|
Jeremy Bullock |
807052 |
#include "toonz/preferences.h"
|
|
Toshihiro Shimizu |
890ddd |
// TnzBase includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tdoubleparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tdoublekeyframe.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tunit.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcommon.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainter></qpainter>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmouseevent></qmouseevent>
|
|
Toshihiro Shimizu |
890ddd |
#include <qwheelevent></qwheelevent>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmenu></qmenu>
|
|
Toshihiro Shimizu |
890ddd |
#include <qsettings></qsettings>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
61dd76 |
#include <cmath></cmath>
|
|
Shinya Kitaoka |
61dd76 |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawCircle(QPainter &painter, double x, double y, double r) {
|
|
Shinya Kitaoka |
120a6e |
painter.drawEllipse(x - r, y - r, 2 * r, 2 * r);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
void drawCircle(QPainter &painter, const QPointF &p, double r) {
|
|
Shinya Kitaoka |
120a6e |
painter.drawEllipse(p.x() - r, p.y() - r, 2 * r, 2 * r);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
void drawSquare(QPainter &painter, double x, double y, double r) {
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(x - r, y - r, 2 * r, 2 * r);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
void drawSquare(QPainter &painter, const QPointF &p, double r) {
|
|
Shinya Kitaoka |
120a6e |
drawSquare(painter, p.x(), p.y(), r);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void drawRoundedSquare(QPainter &painter, const QPointF &p, double r) {
|
|
Shinya Kitaoka |
120a6e |
painter.drawRoundRect(p.x() - r, p.y() - r, 2 * r, 2 * r, 99, 99);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double norm2(const QPointF &p) { return p.x() * p.x() + p.y() * p.y(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class FunctionPanelZoomer final : public ImageUtils::ShortcutZoomer {
|
|
Shinya Kitaoka |
120a6e |
FunctionPanel *m_panel;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
FunctionPanelZoomer(FunctionPanel *panel)
|
|
Shinya Kitaoka |
120a6e |
: ShortcutZoomer(panel), m_panel(panel) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
bool zoom(bool zoomin, bool resetZoom) override {
|
|
Shinya Kitaoka |
120a6e |
if (resetZoom)
|
|
Shinya Kitaoka |
120a6e |
m_panel->fitGraphToWindow();
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
double f = 1.25;
|
|
Shinya Kitaoka |
120a6e |
double sc = zoomin ? f : 1.0 / f;
|
|
Shinya Kitaoka |
120a6e |
QPoint center(m_panel->width() / 2, m_panel->height() / 2);
|
|
Shinya Kitaoka |
120a6e |
m_panel->zoom(sc, sc, center);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// Ruler
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class Ruler {
|
|
Shinya Kitaoka |
120a6e |
double m_minValue, m_step;
|
|
Shinya Kitaoka |
120a6e |
int m_labelPeriod, m_labelOffset, m_tickCount;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double m_unit, m_pan, m_vOrigin;
|
|
Shinya Kitaoka |
120a6e |
int m_x0, m_x1;
|
|
Shinya Kitaoka |
120a6e |
int m_minLabelDistance, m_minDistance;
|
|
Shinya Kitaoka |
120a6e |
double m_minStep;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
Ruler();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// unit,pan define the world to viewport transformation: pixel = value * unit
|
|
Shinya Kitaoka |
120a6e |
// + pan
|
|
Shinya Kitaoka |
120a6e |
// note: unit can be <0 (e.g. in the vertical rulers)
|
|
Shinya Kitaoka |
120a6e |
// use vOrigin!=0 when there is a offset between values and labels
|
|
Shinya Kitaoka |
120a6e |
// (e.g. frame=0 is visualized as 1)
|
|
Shinya Kitaoka |
120a6e |
void setTransform(double unit, double pan, double vOrigin = 0) {
|
|
Shinya Kitaoka |
120a6e |
m_unit = unit;
|
|
Shinya Kitaoka |
120a6e |
m_pan = pan;
|
|
Shinya Kitaoka |
120a6e |
m_vOrigin = vOrigin;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void setRange(int x0, int x1) {
|
|
Shinya Kitaoka |
120a6e |
m_x0 = x0;
|
|
Shinya Kitaoka |
120a6e |
m_x1 = x1;
|
|
Shinya Kitaoka |
120a6e |
} // [x0,x1] is the pixel range
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// set minimum distance (pixel) between two consecutive labels
|
|
Shinya Kitaoka |
120a6e |
void setMinLabelDistance(int distance) { m_minLabelDistance = distance; }
|
|
Shinya Kitaoka |
120a6e |
// set minimum distance (pixel) between two consecutive ticks
|
|
Shinya Kitaoka |
120a6e |
void setMinDistance(int distance) { m_minDistance = distance; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// use setMinStep to define a minimum tick (e.g. for integer rulers as 'frame'
|
|
Shinya Kitaoka |
120a6e |
// call setMinStep(1);)
|
|
Shinya Kitaoka |
120a6e |
void setMinStep(double step) { m_minStep = step; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void compute(); // call compute() once, before calling the following methods
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int getTickCount() const { return m_tickCount; }
|
|
Shinya Kitaoka |
120a6e |
double getTick(int index) const { return m_minValue + index * m_step; }
|
|
Shinya Kitaoka |
120a6e |
bool isLabel(int index) const {
|
|
Shinya Kitaoka |
120a6e |
return ((m_labelOffset + index) % m_labelPeriod) == 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Ruler::Ruler()
|
|
Shinya Kitaoka |
120a6e |
: m_minValue(0)
|
|
Shinya Kitaoka |
120a6e |
, m_step(1)
|
|
Shinya Kitaoka |
120a6e |
, m_labelPeriod(2)
|
|
Shinya Kitaoka |
120a6e |
, m_labelOffset(0)
|
|
Shinya Kitaoka |
120a6e |
, m_tickCount(0)
|
|
Shinya Kitaoka |
120a6e |
, m_unit(1)
|
|
Shinya Kitaoka |
120a6e |
, m_pan(0)
|
|
Shinya Kitaoka |
120a6e |
, m_x0(0)
|
|
Shinya Kitaoka |
120a6e |
, m_x1(100)
|
|
Shinya Kitaoka |
120a6e |
, m_minLabelDistance(20)
|
|
Shinya Kitaoka |
120a6e |
, m_minDistance(5)
|
|
Shinya Kitaoka |
120a6e |
, m_minStep(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Ruler::compute() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_x0 < m_x1);
|
|
Shinya Kitaoka |
120a6e |
assert(m_unit != 0.0);
|
|
Shinya Kitaoka |
120a6e |
assert(m_minLabelDistance > 0);
|
|
Shinya Kitaoka |
120a6e |
assert(m_minDistance >= 0);
|
|
Shinya Kitaoka |
120a6e |
// compute m_step (world distance between two adjacent ticks)
|
|
Shinya Kitaoka |
120a6e |
// and m_labelPeriod (number of ticks between two adjacent labels)
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// the distance (world units) between two labels must be >=
|
|
Shinya Kitaoka |
120a6e |
// minLabelWorldDistance
|
|
Shinya Kitaoka |
120a6e |
const double absUnit = std::abs(m_unit);
|
|
Shinya Kitaoka |
120a6e |
const double minLabelWorldDistance = m_minLabelDistance / absUnit;
|
|
Shinya Kitaoka |
120a6e |
const double minWorldDistance = m_minDistance / absUnit;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// we want the minimum step with:
|
|
Shinya Kitaoka |
120a6e |
// step*labelPeriod (i.e. label distance) >= minLabelWorldDistance
|
|
Shinya Kitaoka |
120a6e |
// step (i.e. tick distance) >= minWorldDistance
|
|
Shinya Kitaoka |
120a6e |
// Note: labelPeriod alternates between 5 and 2 => labelPeriod' =
|
|
Shinya Kitaoka |
120a6e |
// 7-labelPeriod
|
|
Shinya Kitaoka |
120a6e |
m_step = 1;
|
|
Shinya Kitaoka |
120a6e |
m_labelPeriod = 5;
|
|
Shinya Kitaoka |
120a6e |
if (m_step * m_labelPeriod >= minLabelWorldDistance &&
|
|
Shinya Kitaoka |
120a6e |
m_step >= minWorldDistance) {
|
|
Shinya Kitaoka |
120a6e |
while (m_step >= minLabelWorldDistance &&
|
|
Shinya Kitaoka |
120a6e |
m_step / (7 - m_labelPeriod) >= minWorldDistance) {
|
|
Shinya Kitaoka |
120a6e |
m_labelPeriod = 7 - m_labelPeriod;
|
|
Shinya Kitaoka |
120a6e |
m_step /= m_labelPeriod;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
m_step *= m_labelPeriod;
|
|
Shinya Kitaoka |
120a6e |
m_labelPeriod =
|
|
Shinya Kitaoka |
120a6e |
7 - m_labelPeriod; // m_labelPeriod alternates between 5 and 2
|
|
Shinya Kitaoka |
120a6e |
} while (m_step * m_labelPeriod < minLabelWorldDistance ||
|
|
Shinya Kitaoka |
120a6e |
m_step < minWorldDistance);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_step >= minLabelWorldDistance) {
|
|
Shinya Kitaoka |
120a6e |
m_labelPeriod = 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_step * m_labelPeriod < m_minStep) {
|
|
Shinya Kitaoka |
120a6e |
m_step = m_minStep;
|
|
Shinya Kitaoka |
120a6e |
m_labelPeriod = 1;
|
|
Shinya Kitaoka |
120a6e |
} else if (m_step < m_minStep) {
|
|
Shinya Kitaoka |
120a6e |
m_step *= m_labelPeriod;
|
|
Shinya Kitaoka |
120a6e |
m_labelPeriod = 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// compute range
|
|
Shinya Kitaoka |
120a6e |
double v0 = (m_x0 - m_pan) / m_unit; // left margin (world units)
|
|
Shinya Kitaoka |
120a6e |
double v1 = (m_x1 - m_pan) / m_unit; // right margin (world units)
|
|
Shinya Kitaoka |
120a6e |
if (m_unit < 0) tswap(v0, v1);
|
|
Shinya Kitaoka |
120a6e |
int i0 =
|
|
Shinya Kitaoka |
120a6e |
tfloor((v0 - m_vOrigin) / m_step); // largest tick <=v0 is i0 * m_step
|
|
Shinya Kitaoka |
120a6e |
int i1 =
|
|
Shinya Kitaoka |
120a6e |
tceil((v1 - m_vOrigin) / m_step); // smallest tick >=v1 is i1 * m_step
|
|
Shinya Kitaoka |
120a6e |
m_minValue = i0 * m_step + m_vOrigin;
|
|
Shinya Kitaoka |
120a6e |
m_tickCount = i1 - i0 + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_labelOffset = i0 >= 0 ? (i0 % m_labelPeriod)
|
|
Shinya Kitaoka |
120a6e |
: (m_labelPeriod - ((-i0) % m_labelPeriod));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// FunctionPanel::Gadget
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FunctionPanel::Gadget::Gadget(FunctionPanel::Handle handle, int kIndex,
|
|
Shinya Kitaoka |
120a6e |
const QPointF &p, int rx, int ry,
|
|
Shinya Kitaoka |
120a6e |
const QPointF &pointPos)
|
|
Shinya Kitaoka |
120a6e |
: m_handle(handle)
|
|
Shinya Kitaoka |
120a6e |
, m_kIndex(kIndex)
|
|
Shinya Kitaoka |
120a6e |
, m_hitRegion(QRect((int)p.x() - rx, (int)p.y() - ry, 2 * rx, 2 * ry))
|
|
Shinya Kitaoka |
120a6e |
, m_pos(p)
|
|
Shinya Kitaoka |
120a6e |
, m_pointPos(pointPos)
|
|
Shinya Kitaoka |
120a6e |
, m_channel(0)
|
|
Shinya Kitaoka |
120a6e |
, m_keyframePosition(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// FunctionPanel
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
4ce953 |
FunctionPanel::FunctionPanel(QWidget *parent, bool isFloating)
|
|
Shinya Kitaoka |
120a6e |
: QDialog(parent)
|
|
Shinya Kitaoka |
120a6e |
, m_functionTreeModel(0)
|
|
Shinya Kitaoka |
120a6e |
, m_viewTransform()
|
|
Shinya Kitaoka |
120a6e |
, m_valueAxisX(50)
|
|
Shinya Kitaoka |
120a6e |
, m_frameAxisY(50)
|
|
Shinya Kitaoka |
120a6e |
, m_graphViewportY(50)
|
|
Shinya Kitaoka |
120a6e |
, m_frameHandle(0)
|
|
Shinya Kitaoka |
120a6e |
, m_dragTool(0)
|
|
Shinya Kitaoka |
120a6e |
, m_currentFrameStatus(0)
|
|
Shinya Kitaoka |
120a6e |
, m_selection(0)
|
|
Jeremy Bullock |
4ce953 |
, m_curveShape(SMOOTH)
|
|
Jeremy Bullock |
4ce953 |
, m_isFloating(isFloating) {
|
|
Shinya Kitaoka |
120a6e |
setWindowTitle(tr("Function Curves"));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform.translate(50, 200);
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform.scale(5, -1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
setFocusPolicy(Qt::ClickFocus);
|
|
Shinya Kitaoka |
120a6e |
setMouseTracking(true);
|
|
Shinya Kitaoka |
120a6e |
m_highlighted.handle = None;
|
|
Shinya Kitaoka |
120a6e |
m_highlighted.gIndex = -1;
|
|
Shinya Kitaoka |
120a6e |
m_cursor.visible = false;
|
|
Shinya Kitaoka |
120a6e |
m_cursor.frame = m_cursor.value = 0;
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.text = "";
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.curve = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
4ce953 |
if (m_isFloating) {
|
|
Jeremy Bullock |
4ce953 |
// load the dialog size
|
|
Jeremy Bullock |
4ce953 |
TFilePath fp(ToonzFolder::getMyModuleDir() + TFilePath(mySettingsFileName));
|
|
Jeremy Bullock |
4ce953 |
QSettings mySettings(toQString(fp), QSettings::IniFormat);
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
4ce953 |
mySettings.beginGroup("Dialogs");
|
|
Jeremy Bullock |
4ce953 |
setGeometry(
|
|
Jeremy Bullock |
4ce953 |
mySettings.value("FunctionCurves", QRect(500, 500, 400, 300)).toRect());
|
|
Jeremy Bullock |
4ce953 |
mySettings.endGroup();
|
|
Jeremy Bullock |
4ce953 |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FunctionPanel::~FunctionPanel() {
|
|
Jeremy Bullock |
4ce953 |
if (m_isFloating) {
|
|
Jeremy Bullock |
4ce953 |
// save the dialog size
|
|
Jeremy Bullock |
4ce953 |
TFilePath fp(ToonzFolder::getMyModuleDir() + TFilePath(mySettingsFileName));
|
|
Jeremy Bullock |
4ce953 |
QSettings mySettings(toQString(fp), QSettings::IniFormat);
|
|
Jeremy Bullock |
4ce953 |
|
|
Jeremy Bullock |
4ce953 |
mySettings.beginGroup("Dialogs");
|
|
Jeremy Bullock |
4ce953 |
mySettings.setValue("FunctionCurves", geometry());
|
|
Jeremy Bullock |
4ce953 |
mySettings.endGroup();
|
|
Jeremy Bullock |
4ce953 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete m_dragTool;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double FunctionPanel::getPixelRatio(TDoubleParam *curve) const {
|
|
Shinya Kitaoka |
120a6e |
double framePixelSize = xToFrame(1) - xToFrame(0);
|
|
Shinya Kitaoka |
120a6e |
assert(framePixelSize > 0);
|
|
Shinya Kitaoka |
120a6e |
double valuePixelSize = fabs(yToValue(curve, 1) - yToValue(curve, 0));
|
|
Shinya Kitaoka |
120a6e |
assert(valuePixelSize > 0);
|
|
Shinya Kitaoka |
120a6e |
return framePixelSize / valuePixelSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double FunctionPanel::frameToX(double f) const {
|
|
Shinya Kitaoka |
120a6e |
return m_viewTransform.m11() * f + m_viewTransform.dx();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double FunctionPanel::xToFrame(double x) const {
|
|
Shinya Kitaoka |
120a6e |
return (x - m_viewTransform.dx()) / m_viewTransform.m11();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double FunctionPanel::valueToY(TDoubleParam *curve, double v) const {
|
|
Shinya Kitaoka |
120a6e |
const double bigNumber = 1.0e9;
|
|
Shinya Kitaoka |
120a6e |
TMeasure *m = curve->getMeasure();
|
|
Shinya Kitaoka |
120a6e |
if (m) {
|
|
Shinya Kitaoka |
120a6e |
const TUnit *unit = m->getCurrentUnit();
|
|
Shinya Kitaoka |
120a6e |
v = unit->convertTo(v);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return tcrop(m_viewTransform.m22() * v + m_viewTransform.dy(), -bigNumber,
|
|
Shinya Kitaoka |
120a6e |
bigNumber);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double FunctionPanel::yToValue(TDoubleParam *curve, double y) const {
|
|
Shinya Kitaoka |
120a6e |
double v = (y - m_viewTransform.dy()) / m_viewTransform.m22();
|
|
Shinya Kitaoka |
120a6e |
TMeasure *m = curve->getMeasure();
|
|
Shinya Kitaoka |
120a6e |
if (m) {
|
|
Shinya Kitaoka |
120a6e |
const TUnit *unit = m->getCurrentUnit();
|
|
Shinya Kitaoka |
120a6e |
v = unit->convertFrom(v);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return v;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::pan(int dx, int dy) {
|
|
Shinya Kitaoka |
120a6e |
QTransform m;
|
|
Shinya Kitaoka |
120a6e |
m.translate(dx, dy);
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform *= m;
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::zoom(double sx, double sy, const QPoint ¢er) {
|
|
Shinya Kitaoka |
120a6e |
QTransform m;
|
|
Shinya Kitaoka |
120a6e |
m.translate(center.x(), center.y());
|
|
Shinya Kitaoka |
120a6e |
m.scale(sx, sy);
|
|
Shinya Kitaoka |
120a6e |
m.translate(-center.x(), -center.y());
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform *= m;
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QPointF FunctionPanel::getWinPos(TDoubleParam *curve, double frame,
|
|
Shinya Kitaoka |
120a6e |
double value) const {
|
|
Shinya Kitaoka |
120a6e |
return QPointF(frameToX(frame), valueToY(curve, value));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QPointF FunctionPanel::getWinPos(TDoubleParam *curve, double frame) const {
|
|
Shinya Kitaoka |
120a6e |
return getWinPos(curve, frame, curve->getValue(frame));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QPointF FunctionPanel::getWinPos(TDoubleParam *curve,
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &kf) const {
|
|
Shinya Kitaoka |
120a6e |
return getWinPos(curve, kf.m_frame, kf.m_value);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int FunctionPanel::getCurveDistance(TDoubleParam *curve, const QPoint &winPos) {
|
|
Shinya Kitaoka |
120a6e |
double frame = xToFrame(winPos.x());
|
|
Shinya Kitaoka |
120a6e |
double value = curve->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
double curveY = valueToY(curve, value);
|
|
Shinya Kitaoka |
120a6e |
return std::abs(curveY - winPos.y());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *FunctionPanel::findClosestChannel(
|
|
Shinya Kitaoka |
120a6e |
const QPoint &winPos, int maxWinDistance) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *closestChannel = 0;
|
|
Shinya Kitaoka |
120a6e |
int minDistance = maxWinDistance;
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_functionTreeModel->getActiveChannelCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel->getActiveChannel(i);
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = channel->getParam();
|
|
Shinya Kitaoka |
120a6e |
int distance = getCurveDistance(curve, winPos);
|
|
Shinya Kitaoka |
120a6e |
if (distance < minDistance) {
|
|
Shinya Kitaoka |
120a6e |
closestChannel = channel;
|
|
Shinya Kitaoka |
120a6e |
minDistance = distance;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return closestChannel;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *FunctionPanel::findClosestCurve(const QPoint &winPos,
|
|
Shinya Kitaoka |
120a6e |
int maxWinDistance) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *closestChannel =
|
|
Shinya Kitaoka |
120a6e |
findClosestChannel(winPos, maxWinDistance);
|
|
Shinya Kitaoka |
120a6e |
return closestChannel ? closestChannel->getParam() : 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// return the gadget index (-1 if no gadget is close enough)
|
|
Shinya Kitaoka |
120a6e |
int FunctionPanel::findClosestGadget(const QPoint &winPos, Handle &handle,
|
|
Shinya Kitaoka |
120a6e |
int maxDistance) {
|
|
Shinya Kitaoka |
120a6e |
// search only handles close enough (i.e. distance
|
|
Shinya Kitaoka |
120a6e |
int minDistance = maxDistance;
|
|
Shinya Kitaoka |
120a6e |
int k = -1;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_gadgets.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_gadgets[i].m_hitRegion.contains(winPos)) {
|
|
Shinya Kitaoka |
120a6e |
QPoint p;
|
|
Shinya Kitaoka |
120a6e |
double d = (m_gadgets[i].m_hitRegion.center() - winPos).manhattanLength();
|
|
Shinya Kitaoka |
120a6e |
if (d < minDistance) {
|
|
Shinya Kitaoka |
120a6e |
k = i;
|
|
Shinya Kitaoka |
120a6e |
minDistance = d;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (k >= 0) {
|
|
Shinya Kitaoka |
120a6e |
handle = m_gadgets[k].m_handle;
|
|
Shinya Kitaoka |
120a6e |
return k; // m_gadgets[k].m_kIndex;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
handle = None;
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *FunctionPanel::getCurrentCurve() const {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *currentChannel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel ? m_functionTreeModel->getCurrentChannel() : 0;
|
|
Shinya Kitaoka |
120a6e |
if (!currentChannel)
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return currentChannel->getParam();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QPainterPath FunctionPanel::getSegmentPainterPath(TDoubleParam *curve,
|
|
Shinya Kitaoka |
120a6e |
int segmentIndex, int x0,
|
|
Shinya Kitaoka |
120a6e |
int x1) {
|
|
Shinya Kitaoka |
120a6e |
double frame0 = xToFrame(x0), frame1 = xToFrame(x1);
|
|
Shinya Kitaoka |
120a6e |
int kCount = curve->getKeyframeCount();
|
|
Shinya Kitaoka |
120a6e |
int step = 1;
|
|
Shinya Kitaoka |
120a6e |
if (kCount > 0) {
|
|
Shinya Kitaoka |
120a6e |
if (segmentIndex < 0)
|
|
Shinya Kitaoka |
120a6e |
frame1 = std::min(
|
|
Shinya Kitaoka |
120a6e |
frame1, curve->keyframeIndexToFrame(0)); // before first keyframe
|
|
Shinya Kitaoka |
120a6e |
else if (segmentIndex >= kCount - 1)
|
|
Shinya Kitaoka |
120a6e |
frame0 = std::max(frame0, curve->keyframeIndexToFrame(
|
|
Shinya Kitaoka |
120a6e |
kCount - 1)); // after last keyframe
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
// between keyframes
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf = curve->getKeyframe(segmentIndex);
|
|
Shinya Kitaoka |
120a6e |
frame0 = std::max(frame0, kf.m_frame);
|
|
Shinya Kitaoka |
120a6e |
double f = curve->keyframeIndexToFrame(segmentIndex + 1);
|
|
Shinya Kitaoka |
120a6e |
frame1 = std::min(frame1, f);
|
|
Shinya Kitaoka |
120a6e |
step = kf.m_step;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (frame0 >= frame1) return QPainterPath();
|
|
Shinya Kitaoka |
120a6e |
double frame;
|
|
Shinya Kitaoka |
120a6e |
double df = xToFrame(3) - xToFrame(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_curveShape == SMOOTH) {
|
|
Shinya Kitaoka |
120a6e |
frame = frame0;
|
|
Shinya Kitaoka |
120a6e |
} else // FRAME_BASED
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
frame = (double)tfloor(frame0);
|
|
Shinya Kitaoka |
120a6e |
df = std::max(df, 1.0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QPainterPath path;
|
|
Shinya Kitaoka |
120a6e |
if (0 <= segmentIndex && segmentIndex < kCount && step > 1) {
|
|
Shinya Kitaoka |
120a6e |
// step>1
|
|
Shinya Kitaoka |
120a6e |
path.moveTo(getWinPos(curve, frame));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int f0 = curve->keyframeIndexToFrame(segmentIndex);
|
|
Shinya Kitaoka |
120a6e |
int vFrame = f0 + tfloor(tfloor(frame - f0), step);
|
|
Shinya Kitaoka |
120a6e |
double vValue = curve->getValue(vFrame);
|
|
Shinya Kitaoka |
120a6e |
assert(vFrame <= frame);
|
|
Shinya Kitaoka |
120a6e |
assert(vFrame + step > frame);
|
|
Shinya Kitaoka |
120a6e |
while (vFrame + step < frame1) {
|
|
Shinya Kitaoka |
120a6e |
vValue = curve->getValue(vFrame);
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, vFrame, vValue));
|
|
Shinya Kitaoka |
120a6e |
vFrame += step;
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, vFrame, vValue));
|
|
Shinya Kitaoka |
120a6e |
vValue = curve->getValue(vFrame);
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, vFrame, vValue));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, frame1, vValue));
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, frame1, curve->getValue(frame1, true)));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// step = 1
|
|
Shinya Kitaoka |
120a6e |
path.moveTo(getWinPos(curve, frame));
|
|
Shinya Kitaoka |
120a6e |
while (frame + df < frame1) {
|
|
Shinya Kitaoka |
120a6e |
frame += df;
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, frame));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
path.lineTo(getWinPos(curve, frame1, curve->getValue(frame1, true)));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return path;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::drawCurrentFrame(QPainter &painter) {
|
|
Shinya Kitaoka |
120a6e |
int currentframe = 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_frameHandle) currentframe = m_frameHandle->getFrame();
|
|
Shinya Kitaoka |
120a6e |
int x = frameToX(currentframe);
|
|
Shinya Kitaoka |
120a6e |
if (m_currentFrameStatus == 0)
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(Qt::magenta);
|
|
Shinya Kitaoka |
120a6e |
else if (m_currentFrameStatus == 1)
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(Qt::white);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_selectedColor);
|
|
Shinya Kitaoka |
120a6e |
int y = m_graphViewportY + 1;
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x - 1, y, x - 1, height());
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x + 1, y, x + 1, height());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::drawFrameGrid(QPainter &painter) {
|
|
Shinya Kitaoka |
120a6e |
QFontMetrics fm(painter.font());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ruler background
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(Qt::NoPen);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(getRulerBackground());
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(0, 0, width(), m_frameAxisY);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw ticks and labels
|
|
Shinya Kitaoka |
120a6e |
Ruler ruler;
|
|
Shinya Kitaoka |
120a6e |
ruler.setTransform(m_viewTransform.m11(), m_viewTransform.dx(), -1);
|
|
Shinya Kitaoka |
120a6e |
ruler.setRange(m_valueAxisX, width());
|
|
Shinya Kitaoka |
120a6e |
ruler.setMinLabelDistance(fm.width("-8888") + 2);
|
|
Shinya Kitaoka |
120a6e |
ruler.setMinDistance(5);
|
|
Shinya Kitaoka |
120a6e |
ruler.setMinStep(1);
|
|
Shinya Kitaoka |
120a6e |
ruler.compute();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < ruler.getTickCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
double f = ruler.getTick(i);
|
|
Shinya Kitaoka |
120a6e |
bool isLabel = ruler.isLabel(i);
|
|
Shinya Kitaoka |
120a6e |
int x = frameToX(f);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
int y = m_frameAxisY;
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x, y - (isLabel ? 4 : 2), x, y);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(getFrameLineColor());
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x, m_graphViewportY, x, height());
|
|
Shinya Kitaoka |
120a6e |
if (isLabel) {
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
QString labelText = QString::number(f + 1);
|
|
Shinya Kitaoka |
120a6e |
painter.drawText(x - fm.width(labelText) / 2, y - 6, labelText);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::drawValueGrid(QPainter &painter) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = getCurrentCurve();
|
|
Shinya Kitaoka |
120a6e |
if (!curve) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QFontMetrics fm(painter.font());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ruler background
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(Qt::NoPen);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(getRulerBackground());
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(0, 0, m_valueAxisX, height());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Ruler ruler;
|
|
Shinya Kitaoka |
120a6e |
ruler.setTransform(m_viewTransform.m22(), m_viewTransform.dy());
|
|
Shinya Kitaoka |
120a6e |
ruler.setRange(m_graphViewportY, height());
|
|
Shinya Kitaoka |
120a6e |
ruler.setMinLabelDistance(fm.height() + 2);
|
|
Shinya Kitaoka |
120a6e |
ruler.setMinDistance(5);
|
|
Shinya Kitaoka |
120a6e |
ruler.compute();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < ruler.getTickCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
double v = ruler.getTick(i);
|
|
Shinya Kitaoka |
120a6e |
bool isLabel = ruler.isLabel(i);
|
|
Shinya Kitaoka |
120a6e |
int y = tround(m_viewTransform.m22() * v +
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform.dy()); // valueToY(curve, v);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
int x = m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x - (isLabel ? 5 : 2), y, x, y);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(getValueLineColor());
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x, y, width(), y);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isLabel) {
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
QString labelText = QString::number(v);
|
|
Shinya Kitaoka |
120a6e |
painter.drawText(std::max(0, x - 5 - fm.width(labelText)),
|
|
Shinya Kitaoka |
120a6e |
y + fm.height() / 2, labelText);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (false && ruler.getTickCount() > 10) {
|
|
Shinya Kitaoka |
120a6e |
double value = ruler.getTick(9);
|
|
Shinya Kitaoka |
120a6e |
double dv = fabs(ruler.getTick(10));
|
|
Shinya Kitaoka |
120a6e |
double frame = 10;
|
|
Shinya Kitaoka |
120a6e |
double df = dv * getPixelRatio(curve);
|
|
Shinya Kitaoka |
120a6e |
QPointF p0 = getWinPos(curve, frame, value);
|
|
Shinya Kitaoka |
120a6e |
QPointF p1 = getWinPos(curve, frame + df, value + dv);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(Qt::magenta);
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(p0.x(), p0.y(), (p1 - p0).x(), (p1 - p0).y());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::drawOtherCurves(QPainter &painter) {
|
|
Shinya Kitaoka |
120a6e |
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
int x0 = m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
int x1 = width();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QPen solidPen;
|
|
Shinya Kitaoka |
120a6e |
QPen dashedPen;
|
|
Shinya Kitaoka |
120a6e |
QVector<qreal> dashes;</qreal>
|
|
Shinya Kitaoka |
120a6e |
dashes << 4 << 4;
|
|
Shinya Kitaoka |
120a6e |
dashedPen.setDashPattern(dashes);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_functionTreeModel->getActiveChannelCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel->getActiveChannel(i);
|
|
Shinya Kitaoka |
120a6e |
if (channel->isCurrent()) continue;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = channel->getParam();
|
|
Shinya Kitaoka |
120a6e |
QColor color =
|
|
Shinya Kitaoka |
120a6e |
curve == m_curveLabel.curve ? m_selectedColor : getOtherCurvesColor();
|
|
Shinya Kitaoka |
120a6e |
solidPen.setColor(color);
|
|
Shinya Kitaoka |
120a6e |
dashedPen.setColor(color);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int kCount = curve->getKeyframeCount();
|
|
Shinya Kitaoka |
120a6e |
if (kCount == 0) {
|
|
Shinya Kitaoka |
120a6e |
// no control points
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(dashedPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawPath(getSegmentPainterPath(curve, 0, x0, x1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// draw control points and handles
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
for (int k = -1; k < kCount; k++) {
|
|
Shinya Kitaoka |
120a6e |
painter.setPen((k < 0 || k >= kCount - 1) ? dashedPen : solidPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawPath(getSegmentPainterPath(curve, k, x0, x1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(m_subColor);
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < kCount; k++) {
|
|
Shinya Kitaoka |
120a6e |
double frame = curve->keyframeIndexToFrame(k);
|
|
Shinya Kitaoka |
120a6e |
QPointF p = getWinPos(curve, frame, curve->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(p.x() - 1, p.y() - 1, 3, 3);
|
|
Shinya Kitaoka |
120a6e |
QPointF p2 = getWinPos(curve, frame, curve->getValue(frame, true));
|
|
Shinya Kitaoka |
120a6e |
if (p2.y() != p.y()) {
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(p2.x() - 1, p2.y() - 1, 3, 3);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(solidPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(p, p2);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::updateGadgets(TDoubleParam *curve) {
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe oldKf;
|
|
Shinya Kitaoka |
120a6e |
oldKf.m_type = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int keyframeCount = curve->getKeyframeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i != keyframeCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
const int pointHitRadius = 10, handleHitRadius = 6;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf = curve->getKeyframe(i);
|
|
Shinya Kitaoka |
120a6e |
kf.m_value = curve->getValue(
|
|
Shinya Kitaoka |
120a6e |
kf.m_frame); // Some keyframe values do NOT correspond to the
|
|
Shinya Kitaoka |
120a6e |
// actual displayed curve value (eg with expressions)
|
|
Shinya Kitaoka |
120a6e |
// Build keyframe positions
|
|
Shinya Kitaoka |
120a6e |
QPointF p = getWinPos(curve, kf.m_frame);
|
|
Shinya Kitaoka |
120a6e |
QPointF pLeft = p;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (i == keyframeCount - 1 &&
|
|
Shinya Kitaoka |
120a6e |
curve
|
|
Shinya Kitaoka |
120a6e |
->isCycleEnabled()) // This is probably OBSOLETE. I don't think the
|
|
Shinya Kitaoka |
120a6e |
p = getWinPos(curve, kf.m_frame,
|
|
Shinya Kitaoka |
120a6e |
curve->getValue(
|
|
Shinya Kitaoka |
120a6e |
kf.m_frame,
|
|
Shinya Kitaoka |
120a6e |
true)); // GUI allows cycling single curves nowadays...
|
|
Shinya Kitaoka |
120a6e |
// However, is the assignment correct?
|
|
Shinya Kitaoka |
120a6e |
// Add keyframe gadget(s)
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(Gadget(Point, i, p, pointHitRadius, pointHitRadius));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD currentPointRight(kf.m_frame, kf.m_value);
|
|
Shinya Kitaoka |
120a6e |
TPointD currentPointLeft(currentPointRight);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If the previous segment or the current segment are not keyframe based,
|
|
Shinya Kitaoka |
120a6e |
// the curve can have two different values in kf.m_frame
|
|
Shinya Kitaoka |
120a6e |
if (i > 0 &&
|
|
Shinya Kitaoka |
120a6e |
(!TDoubleKeyframe::isKeyframeBased(
|
|
Shinya Kitaoka |
120a6e |
kf.m_type) || // Keyframe-based are the above mentioned curves
|
|
Shinya Kitaoka |
120a6e |
!TDoubleKeyframe::isKeyframeBased(
|
|
Shinya Kitaoka |
120a6e |
curve->getKeyframe(i - 1)
|
|
Shinya Kitaoka |
120a6e |
.m_type))) // where values stored in keyframes are not used
|
|
Shinya Kitaoka |
120a6e |
{ // to calculate the actual curve values.
|
|
Shinya Kitaoka |
120a6e |
currentPointLeft.y = curve->getValue(kf.m_frame, true);
|
|
Shinya Kitaoka |
120a6e |
pLeft = getWinPos(curve, currentPointLeft);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(
|
|
Shinya Kitaoka |
120a6e |
Gadget(Point, i, pLeft, pointHitRadius, pointHitRadius));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add handle gadgets (eg the speed or ease handles)
|
|
Shinya Kitaoka |
120a6e |
if (getSelection()->isSelected(curve, i)) {
|
|
Shinya Kitaoka |
120a6e |
// Left handle
|
|
Shinya Kitaoka |
120a6e |
switch (oldKf.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::SpeedInOut: {
|
|
Shinya Kitaoka |
120a6e |
TPointD speedIn = curve->getSpeedIn(i);
|
|
Shinya Kitaoka |
120a6e |
if (norm2(speedIn) > 0) {
|
|
Shinya Kitaoka |
120a6e |
QPointF q = getWinPos(curve, currentPointLeft + speedIn);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(
|
|
Shinya Kitaoka |
120a6e |
Gadget(SpeedIn, i, q, handleHitRadius, handleHitRadius, pLeft));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOut: {
|
|
Shinya Kitaoka |
120a6e |
QPointF q = getWinPos(curve, kf.m_frame + kf.m_speedIn.x);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(Gadget(EaseIn, i, q, 6, 15));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOutPercentage: {
|
|
Shinya Kitaoka |
120a6e |
double easeIn = kf.m_speedIn.x * (kf.m_frame - oldKf.m_frame) * 0.01;
|
|
Shinya Kitaoka |
120a6e |
QPointF q = getWinPos(curve, kf.m_frame + easeIn);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(Gadget(EaseInPercentage, i, q, 6, 15));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Right handle
|
|
Shinya Kitaoka |
120a6e |
if (i != keyframeCount - 1) {
|
|
Shinya Kitaoka |
120a6e |
switch (kf.m_type) {
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::SpeedInOut: {
|
|
Shinya Kitaoka |
120a6e |
TPointD speedOut = curve->getSpeedOut(i);
|
|
Shinya Kitaoka |
120a6e |
if (norm2(speedOut) > 0) {
|
|
Shinya Kitaoka |
120a6e |
QPointF q = getWinPos(curve, currentPointRight + speedOut);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(
|
|
Shinya Kitaoka |
120a6e |
Gadget(SpeedOut, i, q, handleHitRadius, handleHitRadius, p));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOut: {
|
|
Shinya Kitaoka |
120a6e |
QPointF q = getWinPos(curve, kf.m_frame + kf.m_speedOut.x);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(Gadget(EaseOut, i, q, 6, 15));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case TDoubleKeyframe::EaseInOutPercentage: {
|
|
Shinya Kitaoka |
120a6e |
double segmentWidth = curve->keyframeIndexToFrame(i + 1) - kf.m_frame;
|
|
Shinya Kitaoka |
120a6e |
double easeOut = segmentWidth * kf.m_speedOut.x * 0.01;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QPointF q = getWinPos(curve, kf.m_frame + easeOut);
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(Gadget(EaseOutPercentage, i, q, 6, 15));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
oldKf = kf;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Add group gadgets (ie those that can be added when multiple channels share
|
|
Shinya Kitaoka |
120a6e |
// the same keyframe data)
|
|
Shinya Kitaoka |
120a6e |
int channelCount = m_functionTreeModel->getActiveChannelCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Using a map of vectors. Yes, really. The *ideal* way would be that of
|
|
Shinya Kitaoka |
120a6e |
// copying the first keyframes
|
|
Shinya Kitaoka |
120a6e |
// vector, and then comparing it with the others from each channel - keeping
|
|
Shinya Kitaoka |
120a6e |
// the common data only...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typedef std::map<double, std::vector<tdoublekeyframe="">></double,>
|
|
Shinya Kitaoka |
120a6e |
KeyframeTable; // frame -> { keyframes }
|
|
Shinya Kitaoka |
120a6e |
KeyframeTable keyframes;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i != channelCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel->getActiveChannel(i);
|
|
Shinya Kitaoka |
120a6e |
if (!channel) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = channel->getParam();
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j != curve->getKeyframeCount(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf = curve->getKeyframe(
|
|
Shinya Kitaoka |
120a6e |
j); // Well... this stuff gets called upon *painting* o_o'
|
|
Shinya Kitaoka |
120a6e |
keyframes[kf.m_frame].push_back(
|
|
Shinya Kitaoka |
120a6e |
kf); // It's bound to be slow. Do we really need it?
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int groupHandleY = m_graphViewportY - 6;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
KeyframeTable::iterator it, iEnd(keyframes.end()),
|
|
Shinya Kitaoka |
120a6e |
iLast(keyframes.empty() ? iEnd : --iEnd);
|
|
Shinya Kitaoka |
120a6e |
for (KeyframeTable::iterator it = keyframes.begin(); it != keyframes.end();
|
|
Shinya Kitaoka |
120a6e |
++it) {
|
|
Shinya Kitaoka |
120a6e |
assert(!it->second.empty());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double frame = it->first; // redundant, already in the key... oh well
|
|
Shinya Kitaoka |
120a6e |
QPointF p(frameToX(frame), groupHandleY);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Gadget gadget((FunctionPanel::Handle)100, -1, p, 6,
|
|
Shinya Kitaoka |
120a6e |
6); // No idea what the '100' type value mean...
|
|
Shinya Kitaoka |
120a6e |
gadget.m_keyframePosition = frame;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(gadget);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf = it->second[0];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((int)it->second.size() < channelCount) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// All channels had this keyframe - so, add further gadgets about stuff...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 1; i < channelCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
// Find out if keyframes data differs
|
|
Shinya Kitaoka |
120a6e |
const TDoubleKeyframe &kf2 = it->second[i];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type != kf2.m_type || kf.m_speedOut.x != kf2.m_speedOut.x)
|
|
Shinya Kitaoka |
120a6e |
kf.m_type = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_prevType != kf2.m_prevType || kf.m_speedIn.x != kf2.m_speedIn.x)
|
|
Shinya Kitaoka |
120a6e |
kf.m_prevType = TDoubleKeyframe::None;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// NOTE: EaseInOutPercentage are currently NOT SUPPORTED - they would be
|
|
Shinya Kitaoka |
120a6e |
// harder to code and
|
|
Shinya Kitaoka |
120a6e |
// controversial, since the handle position depends on the *segment
|
|
Shinya Kitaoka |
120a6e |
// size* too.
|
|
Shinya Kitaoka |
120a6e |
// So, keyframe data could be shared, but adjacent segment lengths
|
|
Shinya Kitaoka |
120a6e |
// could not...
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (it != iLast && (kf.m_type == TDoubleKeyframe::SpeedInOut ||
|
|
Shinya Kitaoka |
120a6e |
kf.m_type == TDoubleKeyframe::EaseInOut) &&
|
|
Shinya Kitaoka |
120a6e |
kf.m_speedOut.x != 0) {
|
|
Shinya Kitaoka |
120a6e |
QPointF p(frameToX(frame + kf.m_speedOut.x), groupHandleY);
|
|
Shinya Kitaoka |
120a6e |
Gadget gadget((FunctionPanel::Handle)101, -1, p, 6, 15); // type value...
|
|
Shinya Kitaoka |
120a6e |
gadget.m_keyframePosition = frame;
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(gadget);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((kf.m_prevType == TDoubleKeyframe::SpeedInOut ||
|
|
Shinya Kitaoka |
120a6e |
kf.m_prevType == TDoubleKeyframe::EaseInOut) &&
|
|
Shinya Kitaoka |
120a6e |
kf.m_speedIn.x != 0) {
|
|
Shinya Kitaoka |
120a6e |
QPointF p(frameToX(frame + kf.m_speedIn.x), groupHandleY);
|
|
Shinya Kitaoka |
120a6e |
Gadget gadget((FunctionPanel::Handle)102, -1, p, 6, 15); // type value...
|
|
Shinya Kitaoka |
120a6e |
gadget.m_keyframePosition = frame;
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.push_back(gadget);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::drawCurrentCurve(QPainter &painter) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel ? m_functionTreeModel->getCurrentChannel() : 0;
|
|
Shinya Kitaoka |
120a6e |
if (!channel) return;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = channel->getParam();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setRenderHint(QPainter::Antialiasing, true);
|
|
Shinya Kitaoka |
120a6e |
QColor color = Qt::red;
|
|
Shinya Kitaoka |
120a6e |
QPen solidPen(color);
|
|
Shinya Kitaoka |
120a6e |
QPen dashedPen(color);
|
|
Shinya Kitaoka |
120a6e |
QVector<qreal> dashes;</qreal>
|
|
Shinya Kitaoka |
120a6e |
dashes << 4 << 4;
|
|
Shinya Kitaoka |
120a6e |
dashedPen.setDashPattern(dashes);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int x0 = m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
int x1 = width();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw curve
|
|
Shinya Kitaoka |
120a6e |
int kCount = curve->getKeyframeCount();
|
|
Shinya Kitaoka |
120a6e |
if (kCount == 0) {
|
|
Shinya Kitaoka |
120a6e |
// no control points
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(dashedPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawPath(getSegmentPainterPath(curve, 0, x0, x1));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (int k = -1; k < kCount; k++) {
|
|
Shinya Kitaoka |
120a6e |
if (k < 0 || k >= kCount - 1) {
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(dashedPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawPath(getSegmentPainterPath(curve, k, x0, x1));
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::Type segmentType = curve->getKeyframe(k).m_type;
|
|
Shinya Kitaoka |
120a6e |
QColor color = Qt::red;
|
|
Shinya Kitaoka |
120a6e |
if (segmentType == TDoubleKeyframe::Expression ||
|
|
Shinya Kitaoka |
120a6e |
segmentType == TDoubleKeyframe::SimilarShape ||
|
|
Shinya Kitaoka |
120a6e |
segmentType == TDoubleKeyframe::File)
|
|
Shinya Kitaoka |
120a6e |
color = QColor(185, 0, 0);
|
|
Shinya Kitaoka |
120a6e |
if (getSelection()->isSegmentSelected(curve, k))
|
|
Shinya Kitaoka |
120a6e |
solidPen.setWidth(2);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
solidPen.setWidth(0);
|
|
Shinya Kitaoka |
120a6e |
solidPen.setColor(color);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(solidPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawPath(getSegmentPainterPath(curve, k, x0, x1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(QPen(m_textColor, 0));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw control points
|
|
Shinya Kitaoka |
120a6e |
updateGadgets(curve);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)m_gadgets.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
const Gadget &g = m_gadgets[j];
|
|
Shinya Kitaoka |
120a6e |
if (g.m_handle == SpeedIn || g.m_handle == SpeedOut)
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(g.m_pointPos, g.m_pos);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
solidPen.setWidth(0);
|
|
Shinya Kitaoka |
120a6e |
solidPen.setColor(Qt::red);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(solidPen);
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)m_gadgets.size() - 1; j++)
|
|
Shinya Kitaoka |
120a6e |
if (m_gadgets[j].m_handle == Point && m_gadgets[j + 1].m_handle &&
|
|
Shinya Kitaoka |
120a6e |
m_gadgets[j + 1].m_handle != 100 &&
|
|
Shinya Kitaoka |
120a6e |
m_gadgets[j].m_pos.x() == m_gadgets[j + 1].m_pos.x())
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(m_gadgets[j].m_pos, m_gadgets[j + 1].m_pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)m_gadgets.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
const Gadget &g = m_gadgets[j];
|
|
Shinya Kitaoka |
120a6e |
int i = g.m_kIndex;
|
|
Shinya Kitaoka |
120a6e |
int r = 1;
|
|
Shinya Kitaoka |
120a6e |
QPointF p = g.m_pos;
|
|
Shinya Kitaoka |
120a6e |
double easeDx = 0, easeHeight = 15, easeTick = 2;
|
|
Shinya Kitaoka |
120a6e |
bool isSelected = getSelection()->isSelected(curve, i);
|
|
Shinya Kitaoka |
120a6e |
bool isHighlighted =
|
|
Shinya Kitaoka |
120a6e |
m_highlighted.handle == g.m_handle && m_highlighted.gIndex == j;
|
|
Shinya Kitaoka |
120a6e |
switch (g.m_handle) {
|
|
Shinya Kitaoka |
120a6e |
case Point:
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(isSelected ? QColor(255, 126, 0) : m_subColor);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
r = isHighlighted ? 3 : 2;
|
|
Shinya Kitaoka |
120a6e |
drawSquare(painter, p, r);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case SpeedIn:
|
|
Shinya Kitaoka |
120a6e |
case SpeedOut:
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(m_subColor);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
r = isHighlighted ? 3 : 2;
|
|
Shinya Kitaoka |
120a6e |
drawRoundedSquare(painter, p, r);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case EaseIn:
|
|
Shinya Kitaoka |
120a6e |
case EaseOut:
|
|
Shinya Kitaoka |
120a6e |
case EaseInPercentage:
|
|
Shinya Kitaoka |
120a6e |
case EaseOutPercentage:
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(isHighlighted ? QColor(255, 126, 0) : m_textColor);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(p.x(), p.y() - easeHeight, p.x(), p.y() + easeHeight);
|
|
Shinya Kitaoka |
120a6e |
if (g.m_handle == EaseIn || g.m_handle == EaseInPercentage)
|
|
Shinya Kitaoka |
120a6e |
easeDx = easeTick;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
easeDx = -easeTick;
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(p.x(), p.y() - easeHeight, p.x() + easeDx,
|
|
Shinya Kitaoka |
120a6e |
p.y() - easeHeight - easeTick);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(p.x(), p.y() + easeHeight, p.x() + easeDx,
|
|
Shinya Kitaoka |
120a6e |
p.y() + easeHeight + easeTick);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(
|
|
Shinya Kitaoka |
120a6e |
Qt::NoBrush); // isSelected ? QColor(255,126,0) : Qt::white);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(isHighlighted ? QColor(255, 126, 0) : m_selectedColor);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(p.x(), p.y() - 15, p.x(), p.y() + 15);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::drawGroupKeyframes(QPainter &painter) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel ? m_functionTreeModel->getCurrentChannel() : 0;
|
|
Shinya Kitaoka |
120a6e |
if (!channel) return;
|
|
Shinya Kitaoka |
120a6e |
QColor color = Qt::red;
|
|
Shinya Kitaoka |
120a6e |
QPen solidPen(color);
|
|
Shinya Kitaoka |
120a6e |
QPen dashedPen(color);
|
|
Shinya Kitaoka |
120a6e |
QVector<qreal> dashes;</qreal>
|
|
Shinya Kitaoka |
120a6e |
dashes << 4 << 4;
|
|
Shinya Kitaoka |
120a6e |
dashedPen.setDashPattern(dashes);
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int x0 = m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
int x1 = width();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
solidPen.setWidth(0);
|
|
Shinya Kitaoka |
120a6e |
solidPen.setColor(Qt::red);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(solidPen);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> keyframes;</double>
|
|
Shinya Kitaoka |
120a6e |
int y = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)m_gadgets.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
const Gadget &g = m_gadgets[j];
|
|
Shinya Kitaoka |
120a6e |
int i = g.m_kIndex;
|
|
Shinya Kitaoka |
120a6e |
int r = 1;
|
|
Shinya Kitaoka |
120a6e |
QPointF p = g.m_pos;
|
|
Shinya Kitaoka |
120a6e |
double easeDx = 0, easeHeight = 15, easeTick = 2;
|
|
Shinya Kitaoka |
120a6e |
bool isSelected = false; // getSelection()->isSelected(curve, i);
|
|
Shinya Kitaoka |
120a6e |
bool isHighlighted =
|
|
Shinya Kitaoka |
120a6e |
m_highlighted.handle == g.m_handle && m_highlighted.gIndex == j;
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(isSelected ? QColor(255, 126, 0) : m_subColor);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
r = isHighlighted ? 3 : 2;
|
|
Shinya Kitaoka |
120a6e |
QPainterPath pp;
|
|
Shinya Kitaoka |
120a6e |
int d = 2;
|
|
Shinya Kitaoka |
120a6e |
int h = 4;
|
|
Shinya Kitaoka |
120a6e |
switch (g.m_handle) {
|
|
Shinya Kitaoka |
120a6e |
case 100:
|
|
Shinya Kitaoka |
120a6e |
drawSquare(painter, p, r);
|
|
Shinya Kitaoka |
120a6e |
y = p.y();
|
|
Shinya Kitaoka |
120a6e |
keyframes.push_back(p.x());
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 101:
|
|
Shinya Kitaoka |
120a6e |
d = -d;
|
|
Shinya Kitaoka |
120a6e |
// Note: NO break!
|
|
Shinya Kitaoka |
120a6e |
case 102:
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(isHighlighted ? QColor(255, 126, 0) : m_textColor);
|
|
Shinya Kitaoka |
120a6e |
pp.moveTo(p + QPointF(d, -h));
|
|
Shinya Kitaoka |
120a6e |
pp.lineTo(p + QPointF(0, -h));
|
|
Shinya Kitaoka |
120a6e |
pp.lineTo(p + QPointF(0, h));
|
|
Shinya Kitaoka |
120a6e |
pp.lineTo(p + QPointF(d, h));
|
|
Shinya Kitaoka |
120a6e |
painter.drawPath(pp);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i + 1 < (int)keyframes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(keyframes[i] + 3, y, keyframes[i + 1] - 3, y);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::paintEvent(QPaintEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
m_gadgets.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
807052 |
QString fontName = Preferences::instance()->getInterfaceFont();
|
|
Jeremy Bullock |
807052 |
if (fontName == "") {
|
|
Jeremy Bullock |
807052 |
#ifdef _WIN32
|
|
Jeremy Bullock |
807052 |
fontName = "Arial";
|
|
Jeremy Bullock |
807052 |
#else
|
|
Jeremy Bullock |
807052 |
fontName = "Helvetica";
|
|
Jeremy Bullock |
807052 |
#endif
|
|
Jeremy Bullock |
807052 |
}
|
|
Jeremy Bullock |
807052 |
|
|
Shinya Kitaoka |
120a6e |
QPainter painter(this);
|
|
Jeremy Bullock |
807052 |
QFont font(fontName, 8);
|
|
Shinya Kitaoka |
120a6e |
painter.setFont(font);
|
|
Shinya Kitaoka |
120a6e |
QFontMetrics fm(font);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// define ruler sizes
|
|
Shinya Kitaoka |
120a6e |
m_valueAxisX = fm.width("-888.88") + 2;
|
|
Shinya Kitaoka |
120a6e |
m_frameAxisY = fm.height() + 2;
|
|
Shinya Kitaoka |
120a6e |
m_graphViewportY = m_frameAxisY + 12;
|
|
Shinya Kitaoka |
120a6e |
int ox = m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
int oy0 = m_graphViewportY;
|
|
Shinya Kitaoka |
120a6e |
int oy1 = m_frameAxisY;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// QRect bounds(0,0,width(),height());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw functions background
|
|
Shinya Kitaoka |
120a6e |
painter.setBrush(getBGColor());
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(Qt::NoPen);
|
|
Shinya Kitaoka |
120a6e |
painter.drawRect(ox, oy0, width() - ox, height() - oy0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(ox, 0, width() - ox, height());
|
|
Shinya Kitaoka |
120a6e |
drawCurrentFrame(painter);
|
|
Shinya Kitaoka |
120a6e |
drawFrameGrid(painter);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(0, oy0, width(), height() - oy0);
|
|
Shinya Kitaoka |
120a6e |
drawValueGrid(painter);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw axes
|
|
Shinya Kitaoka |
120a6e |
painter.setClipping(false);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_textColor);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(0, oy0, width(), oy0);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(ox, oy1, width(), oy1);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(ox, 0, ox, height());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// draw curves
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(ox + 1, oy0 + 1, width() - ox - 1, height() - oy0 - 1);
|
|
Shinya Kitaoka |
120a6e |
drawOtherCurves(painter);
|
|
Shinya Kitaoka |
120a6e |
drawCurrentCurve(painter);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
painter.setClipping(false);
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(ox + 1, oy1 + 1, width() - ox - 1, oy0 - oy1 - 1);
|
|
Shinya Kitaoka |
120a6e |
drawGroupKeyframes(painter);
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(ox + 1, oy0 + 1, width() - ox - 1, height() - oy0 - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// tool
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) m_dragTool->draw(painter);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// cursor
|
|
Shinya Kitaoka |
120a6e |
if (m_cursor.visible) {
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(ox + 1, oy0 + 1, width() - ox - 1, height() - oy0 - 1);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(getOtherCurvesColor());
|
|
Shinya Kitaoka |
120a6e |
int x = frameToX(m_cursor.frame);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(x, oy0 + 1, x, oy0 + 10);
|
|
Shinya Kitaoka |
120a6e |
QString text = QString::number(tround(m_cursor.frame) + 1);
|
|
Shinya Kitaoka |
120a6e |
painter.drawText(x - fm.width(text) / 2, oy0 + 10 + fm.height(), text);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *currentCurve = getCurrentCurve();
|
|
Shinya Kitaoka |
120a6e |
if (currentCurve) {
|
|
Shinya Kitaoka |
120a6e |
const TUnit *unit = 0;
|
|
Shinya Kitaoka |
120a6e |
if (currentCurve->getMeasure())
|
|
Shinya Kitaoka |
120a6e |
unit = currentCurve->getMeasure()->getCurrentUnit();
|
|
Shinya Kitaoka |
120a6e |
double displayValue = m_cursor.value;
|
|
Shinya Kitaoka |
120a6e |
if (unit) displayValue = unit->convertTo(displayValue);
|
|
Shinya Kitaoka |
120a6e |
// painter.setClipRect(0,oy0,height(),height()-oy0);
|
|
Shinya Kitaoka |
120a6e |
int y = valueToY(currentCurve, m_cursor.value);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(ox, y, ox + 10, y);
|
|
Shinya Kitaoka |
120a6e |
painter.drawText(m_origin.x() + 10, y + 4, QString::number(displayValue));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// curve name
|
|
Shinya Kitaoka |
120a6e |
if (m_curveLabel.text != "") {
|
|
Shinya Kitaoka |
120a6e |
painter.setClipRect(ox, oy0, width() - ox, height() - oy0);
|
|
Shinya Kitaoka |
120a6e |
painter.setPen(m_selectedColor);
|
|
Shinya Kitaoka |
120a6e |
painter.drawLine(m_curveLabel.curvePos, m_curveLabel.labelPos);
|
|
Shinya Kitaoka |
120a6e |
painter.drawText(m_curveLabel.labelPos,
|
|
Shinya Kitaoka |
120a6e |
QString::fromStdString(m_curveLabel.text));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// painter.setPen(Qt::black);
|
|
Shinya Kitaoka |
120a6e |
// painter.drawText(QPointF(70,70),
|
|
Shinya Kitaoka |
120a6e |
// "f0=" + QString::number(xToFrame(ox)) +
|
|
Shinya Kitaoka |
120a6e |
// " f1=" + QString::number(xToFrame(width())));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// painter.setPen(Qt::black);
|
|
Shinya Kitaoka |
120a6e |
// painter.setBrush(Qt::NoBrush);
|
|
Shinya Kitaoka |
120a6e |
// painter.drawRect(ox+10,oy+10,width()-ox-20,height()-oy-20);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::mousePressEvent(QMouseEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
m_cursor.visible = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// m_dragTool should be 0. just in case...
|
|
Shinya Kitaoka |
120a6e |
assert(m_dragTool == 0);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (e->button() == Qt::MidButton) {
|
|
Shinya Kitaoka |
120a6e |
// mid mouse click => panning
|
|
Shinya Kitaoka |
120a6e |
bool xLocked = e->pos().x() <= m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
bool yLocked = e->pos().y() <= m_valueAxisX;
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new PanDragTool(this, xLocked, yLocked);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool->click(e);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
} else if (e->button() == Qt::RightButton) {
|
|
Shinya Kitaoka |
120a6e |
// right mouse click => open context menu
|
|
Shinya Kitaoka |
120a6e |
openContextMenu(e);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QPoint winPos = e->pos();
|
|
Shinya Kitaoka |
120a6e |
Handle handle = None;
|
|
Shinya Kitaoka |
120a6e |
const int maxDistance = 20;
|
|
Shinya Kitaoka |
120a6e |
int closestGadgetId = findClosestGadget(e->pos(), handle, maxDistance);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (e->pos().x() > m_valueAxisX && e->pos().y() < m_frameAxisY &&
|
|
Shinya Kitaoka |
120a6e |
closestGadgetId < 0 && (e->modifiers() & Qt::ControlModifier) == 0) {
|
|
Shinya Kitaoka |
120a6e |
// click on topbar => frame zoom
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new ZoomDragTool(this, ZoomDragTool::FrameZoom);
|
|
Shinya Kitaoka |
120a6e |
} else if (e->pos().x() < m_valueAxisX && e->pos().y() > m_graphViewportY) {
|
|
Shinya Kitaoka |
120a6e |
// click on topbar => value zoom
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new ZoomDragTool(this, ZoomDragTool::ValueZoom);
|
|
Shinya Kitaoka |
120a6e |
} else if (m_currentFrameStatus == 1 && m_frameHandle != 0 &&
|
|
Shinya Kitaoka |
120a6e |
closestGadgetId < 0) {
|
|
Shinya Kitaoka |
120a6e |
// click on current frame => move frame
|
|
Shinya Kitaoka |
120a6e |
m_currentFrameStatus = 2;
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new MoveFrameDragTool(this, m_frameHandle);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (0 <= closestGadgetId && closestGadgetId < (int)m_gadgets.size()) {
|
|
Shinya Kitaoka |
120a6e |
if (handle == 100) // group move gadget
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
MovePointDragTool *dragTool = new MovePointDragTool(this, 0);
|
|
Shinya Kitaoka |
120a6e |
dragTool->selectKeyframes(m_gadgets[closestGadgetId].m_keyframePosition);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = dragTool;
|
|
Shinya Kitaoka |
120a6e |
} else if (handle == 101 || handle == 102) {
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new MoveGroupHandleDragTool(
|
|
Shinya Kitaoka |
120a6e |
this, m_gadgets[closestGadgetId].m_keyframePosition, handle);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) {
|
|
Shinya Kitaoka |
120a6e |
m_dragTool->click(e);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *currentChannel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel ? m_functionTreeModel->getCurrentChannel() : 0;
|
|
Shinya Kitaoka |
120a6e |
if (!currentChannel ||
|
|
Shinya Kitaoka |
120a6e |
getCurveDistance(currentChannel->getParam(), winPos) > maxDistance &&
|
|
Shinya Kitaoka |
120a6e |
closestGadgetId < 0) {
|
|
Shinya Kitaoka |
120a6e |
// if current channel is undefined or its curve is too far from the clicked
|
|
Shinya Kitaoka |
120a6e |
// point
|
|
Shinya Kitaoka |
120a6e |
// the user is possibly trying to select a different curve
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
findClosestChannel(winPos, maxDistance);
|
|
Shinya Kitaoka |
120a6e |
if (channel) {
|
|
Shinya Kitaoka |
120a6e |
channel->setIsCurrent(true);
|
|
Shinya Kitaoka |
120a6e |
// Open folder
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::ChannelGroup *channelGroup =
|
|
Shinya Kitaoka |
120a6e |
channel->getChannelGroup();
|
|
Shinya Kitaoka |
120a6e |
if (!channelGroup->isOpen())
|
|
Shinya Kitaoka |
120a6e |
channelGroup->getModel()->setExpandedItem(channelGroup->createIndex(),
|
|
Shinya Kitaoka |
120a6e |
true);
|
|
Shinya Kitaoka |
120a6e |
currentChannel = channel;
|
|
Shinya Kitaoka |
120a6e |
getSelection()->selectNone();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (currentChannel) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *currentCurve = currentChannel->getParam();
|
|
Shinya Kitaoka |
120a6e |
if (currentCurve) {
|
|
Shinya Kitaoka |
120a6e |
int kIndex =
|
|
Shinya Kitaoka |
120a6e |
closestGadgetId >= 0 ? m_gadgets[closestGadgetId].m_kIndex : -1;
|
|
Shinya Kitaoka |
120a6e |
if (kIndex >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// keyframe clicked
|
|
Shinya Kitaoka |
120a6e |
if (handle == FunctionPanel::Point) {
|
|
Shinya Kitaoka |
120a6e |
// select point (if needed)
|
|
Shinya Kitaoka |
120a6e |
if (!getSelection()->isSelected(currentCurve, kIndex)) {
|
|
Shinya Kitaoka |
120a6e |
// shift-click => add to selection
|
|
Shinya Kitaoka |
120a6e |
if (0 == (e->modifiers() & Qt::ShiftModifier))
|
|
Shinya Kitaoka |
120a6e |
getSelection()->deselectAllKeyframes();
|
|
Shinya Kitaoka |
120a6e |
getSelection()->select(currentCurve, kIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// move selected point(s)
|
|
Shinya Kitaoka |
120a6e |
MovePointDragTool *dragTool =
|
|
Shinya Kitaoka |
120a6e |
new MovePointDragTool(this, currentCurve);
|
|
Shinya Kitaoka |
120a6e |
if (getSelection()->getSelectedSegment().first != 0) {
|
|
Shinya Kitaoka |
120a6e |
// if a segment is selected then move only the clicked point
|
|
Shinya Kitaoka |
120a6e |
dragTool->addKeyframe2(kIndex);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
dragTool->setSelection(getSelection());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = dragTool;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_dragTool =
|
|
Shinya Kitaoka |
120a6e |
new MoveHandleDragTool(this, currentCurve, kIndex, handle);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// no keyframe clicked
|
|
Shinya Kitaoka |
120a6e |
int curveDistance =
|
|
Shinya Kitaoka |
120a6e |
getCurveDistance(currentChannel->getParam(), winPos);
|
|
Shinya Kitaoka |
120a6e |
bool isKeyframeable = true;
|
|
Shinya Kitaoka |
120a6e |
bool isGroup = abs(winPos.y() - (m_graphViewportY - 5)) < 5;
|
|
Shinya Kitaoka |
120a6e |
if (0 != (e->modifiers() & Qt::ControlModifier) &&
|
|
Shinya Kitaoka |
120a6e |
(curveDistance < maxDistance || isGroup) && isKeyframeable) {
|
|
Shinya Kitaoka |
120a6e |
// ctrl-clicked near curve => create a new keyframe
|
|
Shinya Kitaoka |
120a6e |
double frame = tround(xToFrame(winPos.x()));
|
|
Shinya Kitaoka |
120a6e |
MovePointDragTool *dragTool =
|
|
Shinya Kitaoka |
120a6e |
new MovePointDragTool(this, isGroup ? 0 : currentCurve);
|
|
Shinya Kitaoka |
120a6e |
// if(curveDistance>=maxDistance)
|
|
Shinya Kitaoka |
120a6e |
// dragTool->m_channelGroup =
|
|
Shinya Kitaoka |
120a6e |
// currentChannel->getChannelGroup();
|
|
Shinya Kitaoka |
120a6e |
dragTool->createKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
dragTool->selectKeyframes(frame);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = dragTool;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
int kIndex = dragTool->createKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
if(kIndex!=-1)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
getSelection()->deselectAllKeyframes();
|
|
Shinya Kitaoka |
120a6e |
getSelection()->select(currentCurve, kIndex);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = dragTool;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
// assert(0);
|
|
Shinya Kitaoka |
120a6e |
} else if (curveDistance < maxDistance) {
|
|
Shinya Kitaoka |
120a6e |
// clicked near curve (but far from keyframes)
|
|
Shinya Kitaoka |
120a6e |
getSelection()->deselectAllKeyframes();
|
|
Shinya Kitaoka |
120a6e |
double frame = xToFrame(winPos.x());
|
|
Shinya Kitaoka |
120a6e |
int k0 = currentCurve->getPrevKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
int k1 = currentCurve->getNextKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
if (k0 >= 0 && k1 == k0 + 1) {
|
|
Shinya Kitaoka |
120a6e |
// select and move the segment
|
|
Shinya Kitaoka |
120a6e |
getSelection()->selectSegment(currentCurve, k0);
|
|
Shinya Kitaoka |
120a6e |
MovePointDragTool *dragTool =
|
|
Shinya Kitaoka |
120a6e |
new MovePointDragTool(this, currentCurve);
|
|
Shinya Kitaoka |
120a6e |
dragTool->addKeyframe2(k0);
|
|
Shinya Kitaoka |
120a6e |
dragTool->addKeyframe2(k1);
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = dragTool;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// start a rectangular selection
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new RectSelectTool(this, currentCurve);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// nothing clicked: start a rectangular selection
|
|
Shinya Kitaoka |
120a6e |
getSelection()->deselectAllKeyframes();
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = new RectSelectTool(this, currentCurve);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) m_dragTool->click(e);
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::mouseReleaseEvent(QMouseEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) m_dragTool->release(e);
|
|
Shinya Kitaoka |
120a6e |
delete m_dragTool;
|
|
Shinya Kitaoka |
120a6e |
m_dragTool = 0;
|
|
Shinya Kitaoka |
120a6e |
m_cursor.visible = true;
|
|
Shinya Kitaoka |
120a6e |
m_currentFrameStatus = 0;
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::mouseMoveEvent(QMouseEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
if (e->buttons()) {
|
|
Shinya Kitaoka |
120a6e |
if (m_dragTool) m_dragTool->drag(e);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_cursor.frame = xToFrame(e->pos().x());
|
|
Shinya Kitaoka |
120a6e |
m_cursor.value = 0;
|
|
Shinya Kitaoka |
120a6e |
m_cursor.visible = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *currentCurve = getCurrentCurve();
|
|
Shinya Kitaoka |
120a6e |
if (currentCurve) {
|
|
Shinya Kitaoka |
120a6e |
Handle handle = None;
|
|
Shinya Kitaoka |
120a6e |
int gIndex = findClosestGadget(e->pos(), handle, 20);
|
|
Shinya Kitaoka |
120a6e |
if (m_highlighted.handle != handle || m_highlighted.gIndex != gIndex) {
|
|
Shinya Kitaoka |
120a6e |
m_highlighted.handle = handle;
|
|
Shinya Kitaoka |
120a6e |
m_highlighted.gIndex = gIndex;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_cursor.value = yToValue(currentCurve, e->pos().y());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double currentFrame = m_frameHandle ? m_frameHandle->getFrame() : 0;
|
|
Shinya Kitaoka |
120a6e |
if (m_highlighted.handle == None &&
|
|
Shinya Kitaoka |
120a6e |
std::abs(e->pos().x() - frameToX(currentFrame)) < 5)
|
|
Shinya Kitaoka |
120a6e |
m_currentFrameStatus = 1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_currentFrameStatus = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *closestChannel =
|
|
Shinya Kitaoka |
120a6e |
findClosestChannel(e->pos(), 20);
|
|
Shinya Kitaoka |
120a6e |
if (closestChannel && m_highlighted.handle == None) {
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = closestChannel->getParam();
|
|
Shinya Kitaoka |
120a6e |
if (m_functionTreeModel->getActiveChannelCount() <= 1)
|
|
Shinya Kitaoka |
120a6e |
//|| closestChannel == m_functionTreeModel->getCurrentChannel())
|
|
Shinya Kitaoka |
120a6e |
curve = 0;
|
|
Shinya Kitaoka |
120a6e |
if (curve && m_curveLabel.curve != curve) {
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.curve = curve;
|
|
Shinya Kitaoka |
120a6e |
QString channelName = closestChannel->data(Qt::DisplayRole).toString();
|
|
Shinya Kitaoka |
120a6e |
QString parentChannelName =
|
|
Shinya Kitaoka |
120a6e |
closestChannel->getChannelGroup()->data(Qt::DisplayRole).toString();
|
|
Shinya Kitaoka |
120a6e |
QString name = parentChannelName + QString(", ") + channelName;
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.text = name.toStdString();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// in order to avoid run off the right-end of visible area
|
|
Shinya Kitaoka |
120a6e |
int textWidth = fontMetrics().width(name) + 30;
|
|
Shinya Kitaoka |
120a6e |
double frame = xToFrame(width() - textWidth);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.curvePos = getWinPos(curve, frame).toPoint();
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.labelPos = m_curveLabel.curvePos + QPoint(20, -10);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.text = "";
|
|
Shinya Kitaoka |
120a6e |
m_curveLabel.curve = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::keyPressEvent(QKeyEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
FunctionPanelZoomer(this).exec(e);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::enterEvent(QEvent *) {
|
|
Shinya Kitaoka |
120a6e |
m_cursor.visible = true;
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::leaveEvent(QEvent *) {
|
|
Shinya Kitaoka |
120a6e |
m_cursor.visible = false;
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::wheelEvent(QWheelEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
double factor = exp(0.002 * (double)e->delta());
|
|
Shinya Kitaoka |
120a6e |
zoom(factor, factor, e->pos());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::fitGraphToWindow(bool currentCurveOnly) {
|
|
Shinya Kitaoka |
120a6e |
double f0 = 0, f1 = -1;
|
|
Shinya Kitaoka |
120a6e |
double v0 = 0, v1 = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_functionTreeModel->getActiveChannelCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
FunctionTreeModel::Channel *channel =
|
|
Shinya Kitaoka |
120a6e |
m_functionTreeModel->getActiveChannel(i);
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = channel->getParam();
|
|
Shinya Kitaoka |
120a6e |
if (currentCurveOnly && curve != getCurrentCurve()) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TUnit *unit = 0;
|
|
Shinya Kitaoka |
120a6e |
if (curve->getMeasure()) unit = curve->getMeasure()->getCurrentUnit();
|
|
Shinya Kitaoka |
120a6e |
int n = curve->getKeyframeCount();
|
|
Shinya Kitaoka |
120a6e |
if (n == 0) {
|
|
Shinya Kitaoka |
120a6e |
double v = curve->getDefaultValue();
|
|
Shinya Kitaoka |
120a6e |
if (unit) v = unit->convertTo(v);
|
|
Shinya Kitaoka |
120a6e |
if (v0 > v1)
|
|
Shinya Kitaoka |
120a6e |
v0 = v1 = v;
|
|
Shinya Kitaoka |
120a6e |
else if (v > v1)
|
|
Shinya Kitaoka |
120a6e |
v1 = v;
|
|
Shinya Kitaoka |
120a6e |
else if (v < v0)
|
|
Shinya Kitaoka |
120a6e |
v0 = v;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe k = curve->getKeyframe(0);
|
|
Shinya Kitaoka |
120a6e |
double fa = k.m_frame;
|
|
Shinya Kitaoka |
120a6e |
k = curve->getKeyframe(n - 1);
|
|
Shinya Kitaoka |
120a6e |
double fb = k.m_frame;
|
|
Shinya Kitaoka |
120a6e |
if (f0 > f1) {
|
|
Shinya Kitaoka |
120a6e |
f0 = fa;
|
|
Shinya Kitaoka |
120a6e |
f1 = fb;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
f0 = qMin(f0, fa);
|
|
Shinya Kitaoka |
120a6e |
f1 = qMax(f1, fb);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
double v = curve->getValue(fa);
|
|
Shinya Kitaoka |
120a6e |
if (unit) v = unit->convertTo(v);
|
|
Shinya Kitaoka |
120a6e |
if (v0 > v1) v0 = v1 = v;
|
|
Shinya Kitaoka |
120a6e |
int m = 50;
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < m; j++) {
|
|
Shinya Kitaoka |
120a6e |
double t = (double)j / (double)(m - 1);
|
|
Shinya Kitaoka |
120a6e |
double v = curve->getValue((1 - t) * fa + t * fb);
|
|
Shinya Kitaoka |
120a6e |
if (unit) v = unit->convertTo(v);
|
|
Shinya Kitaoka |
120a6e |
v0 = qMin(v0, v);
|
|
Shinya Kitaoka |
120a6e |
v1 = qMax(v1, v);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (f0 >= f1 || v0 >= v1) {
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform = QTransform();
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform.translate(m_valueAxisX, 200);
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform.scale(5, -1);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
double mx = (width() - m_valueAxisX - 20) / (f1 - f0);
|
|
Shinya Kitaoka |
120a6e |
double my = -(height() - m_graphViewportY - 20) / (v1 - v0);
|
|
Shinya Kitaoka |
120a6e |
double dx = m_valueAxisX + 10 - f0 * mx;
|
|
Shinya Kitaoka |
120a6e |
double dy = m_graphViewportY + 10 - v1 * my;
|
|
Shinya Kitaoka |
120a6e |
m_viewTransform = QTransform(mx, 0, 0, my, dx, dy);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::fitSelectedPoints() { fitGraphToWindow(true); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::fitCurve() { fitGraphToWindow(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::fitRegion(double f0, double v0, double f1, double v1) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
ccd505 |
static void setSegmentType(FunctionSelection *selection, TDoubleParam *curve,
|
|
Campbell Barton |
ccd505 |
int segmentIndex, TDoubleKeyframe::Type type) {
|
|
Shinya Kitaoka |
120a6e |
selection->selectSegment(curve, segmentIndex);
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter setter(curve, segmentIndex);
|
|
Shinya Kitaoka |
120a6e |
setter.setType(type);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::openContextMenu(QMouseEvent *e) {
|
|
Shinya Kitaoka |
120a6e |
QAction linkHandlesAction(tr("Link Handles"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction unlinkHandlesAction(tr("Unlink Handles"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction resetHandlesAction(tr("Reset Handles"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction deleteKeyframeAction(tr("Delete"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction insertKeyframeAction(tr("Set Key"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction activateCycleAction(tr("Activate Cycle"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction deactivateCycleAction(tr("Deactivate Cycle"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setLinearAction(tr("Linear Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setSpeedInOutAction(tr("Speed In / Speed Out Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setEaseInOutAction(tr("Ease In / Ease Out Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setEaseInOut2Action(tr("Ease In / Ease Out (%) Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setExponentialAction(tr("Exponential Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setExpressionAction(tr("Expression Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setFileAction(tr("File Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setConstantAction(tr("Constant Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setSimilarShapeAction(tr("Similar Shape Interpolation"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction fitSelectedAction(tr("Fit Selection"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction fitAllAction(tr("Fit"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setStep1Action(tr("Step 1"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setStep2Action(tr("Step 2"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setStep3Action(tr("Step 3"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction setStep4Action(tr("Step 4"), 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDoubleParam *curve = getCurrentCurve();
|
|
Shinya Kitaoka |
120a6e |
int segmentIndex = -1;
|
|
Shinya Kitaoka |
120a6e |
if (!curve) return;
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe kf;
|
|
Shinya Kitaoka |
120a6e |
double frame = xToFrame(e->pos().x());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// build menu
|
|
Shinya Kitaoka |
120a6e |
QMenu menu(0);
|
|
Shinya Kitaoka |
120a6e |
if (m_highlighted.handle == Point && m_highlighted.gIndex >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
m_gadgets[m_highlighted.gIndex].m_handle != 100) {
|
|
Shinya Kitaoka |
120a6e |
kf = curve->getKeyframe(m_gadgets[m_highlighted.gIndex].m_kIndex);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_linkedHandles)
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&unlinkHandlesAction);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&linkHandlesAction);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&resetHandlesAction);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&deleteKeyframeAction);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
int k0 = curve->getPrevKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
int k1 = curve->getNextKeyframe(frame);
|
|
Shinya Kitaoka |
120a6e |
if (k0 == curve->getKeyframeCount() - 1) // after last keyframe
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (curve->isCycleEnabled())
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&deactivateCycleAction);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&activateCycleAction);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&insertKeyframeAction);
|
|
Shinya Kitaoka |
120a6e |
if (k0 >= 0 && k1 >= 0) {
|
|
Shinya Kitaoka |
120a6e |
menu.addSeparator();
|
|
Shinya Kitaoka |
120a6e |
segmentIndex = k0;
|
|
Shinya Kitaoka |
120a6e |
kf = curve->getKeyframe(k0);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setLinearAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::Linear)
|
|
Shinya Kitaoka |
120a6e |
setLinearAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setSpeedInOutAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::SpeedInOut)
|
|
Shinya Kitaoka |
120a6e |
setSpeedInOutAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setEaseInOutAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::EaseInOut)
|
|
Shinya Kitaoka |
120a6e |
setEaseInOutAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setEaseInOut2Action);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::EaseInOutPercentage)
|
|
Shinya Kitaoka |
120a6e |
setEaseInOut2Action.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setExponentialAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::Exponential)
|
|
Shinya Kitaoka |
120a6e |
setExponentialAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setExpressionAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::Expression)
|
|
Shinya Kitaoka |
120a6e |
setExpressionAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setSimilarShapeAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::SimilarShape)
|
|
Shinya Kitaoka |
120a6e |
setSimilarShapeAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setFileAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::File) setFileAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&setConstantAction);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_type == TDoubleKeyframe::Constant)
|
|
Shinya Kitaoka |
120a6e |
setConstantAction.setEnabled(false);
|
|
Shinya Kitaoka |
120a6e |
menu.addSeparator();
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_step != 1) menu.addAction(&setStep1Action);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_step != 2) menu.addAction(&setStep2Action);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_step != 3) menu.addAction(&setStep3Action);
|
|
Shinya Kitaoka |
120a6e |
if (kf.m_step != 4) menu.addAction(&setStep4Action);
|
|
Shinya Kitaoka |
120a6e |
menu.addSeparator();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!getSelection()->isEmpty()) menu.addAction(&fitSelectedAction);
|
|
Shinya Kitaoka |
120a6e |
menu.addAction(&fitAllAction);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// curve shape type
|
|
Shinya Kitaoka |
120a6e |
QAction curveShapeSmoothAction(tr("Smooth"), 0);
|
|
Shinya Kitaoka |
120a6e |
QAction curveShapeFrameBasedAction(tr("Frame Based"), 0);
|
|
Shinya Kitaoka |
120a6e |
QMenu curveShapeSubmenu(tr("Curve Shape"), 0);
|
|
Shinya Kitaoka |
120a6e |
menu.addSeparator();
|
|
Shinya Kitaoka |
120a6e |
curveShapeSubmenu.addAction(&curveShapeSmoothAction);
|
|
Shinya Kitaoka |
120a6e |
curveShapeSubmenu.addAction(&curveShapeFrameBasedAction);
|
|
Shinya Kitaoka |
120a6e |
menu.addMenu(&curveShapeSubmenu);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
curveShapeSmoothAction.setCheckable(true);
|
|
Shinya Kitaoka |
120a6e |
curveShapeSmoothAction.setChecked(m_curveShape == SMOOTH);
|
|
Shinya Kitaoka |
120a6e |
curveShapeFrameBasedAction.setCheckable(true);
|
|
Shinya Kitaoka |
120a6e |
curveShapeFrameBasedAction.setChecked(m_curveShape == FRAME_BASED);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Store m_highlighted due to the following exec()
|
|
Shinya Kitaoka |
120a6e |
Highlighted highlighted(m_highlighted);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// execute menu
|
|
Shinya Kitaoka |
120a6e |
QAction *action = menu.exec(e->globalPos()); // Will process events, possibly
|
|
Shinya Kitaoka |
120a6e |
// altering m_highlighted
|
|
Shinya Kitaoka |
120a6e |
// (MAC-verified)
|
|
Shinya Kitaoka |
120a6e |
if (action == &linkHandlesAction) // Let's just *hope* that doesn't happen to
|
|
Shinya Kitaoka |
120a6e |
// m_gadgets though... :/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (m_gadgets[highlighted.gIndex].m_handle != 100)
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve, m_gadgets[highlighted.gIndex].m_kIndex)
|
|
Shinya Kitaoka |
120a6e |
.linkHandles();
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &unlinkHandlesAction) {
|
|
Shinya Kitaoka |
120a6e |
if (m_gadgets[highlighted.gIndex].m_handle != 100)
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve, m_gadgets[highlighted.gIndex].m_kIndex)
|
|
Shinya Kitaoka |
120a6e |
.unlinkHandles();
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &resetHandlesAction) {
|
|
Shinya Kitaoka |
120a6e |
kf.m_speedIn = TPointD(-5, 0);
|
|
Shinya Kitaoka |
120a6e |
kf.m_speedOut = -kf.m_speedIn;
|
|
Shinya Kitaoka |
120a6e |
curve->setKeyframe(kf);
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &deleteKeyframeAction) {
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter::removeKeyframeAt(curve, kf.m_frame);
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &insertKeyframeAction) {
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve).createKeyframe(tround(frame));
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &activateCycleAction) {
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter::enableCycle(curve, true);
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &deactivateCycleAction) {
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter::enableCycle(curve, false);
|
|
Shinya Kitaoka |
120a6e |
} else if (action == &setLinearAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::Linear);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setSpeedInOutAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::SpeedInOut);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setEaseInOutAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::EaseInOut);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setEaseInOut2Action)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::EaseInOutPercentage);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setExponentialAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::Exponential);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setExpressionAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::Expression);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setSimilarShapeAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::SimilarShape);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setFileAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex, TDoubleKeyframe::File);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setConstantAction)
|
|
Shinya Kitaoka |
120a6e |
setSegmentType(getSelection(), curve, segmentIndex,
|
|
Shinya Kitaoka |
120a6e |
TDoubleKeyframe::Constant);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &fitSelectedAction)
|
|
Shinya Kitaoka |
120a6e |
fitSelectedPoints();
|
|
Shinya Kitaoka |
120a6e |
else if (action == &fitAllAction)
|
|
Shinya Kitaoka |
120a6e |
fitCurve();
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setStep1Action)
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve, segmentIndex).setStep(1);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setStep2Action)
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve, segmentIndex).setStep(2);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setStep3Action)
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve, segmentIndex).setStep(3);
|
|
Shinya Kitaoka |
120a6e |
else if (action == &setStep4Action)
|
|
Shinya Kitaoka |
120a6e |
KeyframeSetter(curve, segmentIndex).setStep(4);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
else if (action == &curveShapeSmoothAction)
|
|
Shinya Kitaoka |
120a6e |
m_curveShape = SMOOTH;
|
|
Shinya Kitaoka |
120a6e |
else if (action == &curveShapeFrameBasedAction)
|
|
Shinya Kitaoka |
120a6e |
m_curveShape = FRAME_BASED;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::setFrameHandle(TFrameHandle *frameHandle) {
|
|
Shinya Kitaoka |
120a6e |
if (m_frameHandle == frameHandle) return;
|
|
Shinya Kitaoka |
120a6e |
if (m_frameHandle) m_frameHandle->disconnect(this);
|
|
Shinya Kitaoka |
120a6e |
m_frameHandle = frameHandle;
|
|
Shinya Kitaoka |
120a6e |
if (isVisible() && m_frameHandle) {
|
|
Shinya Kitaoka |
120a6e |
connect(m_frameHandle, SIGNAL(frameSwitched()), this,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onFrameSwitched()));
|
|
Shinya Kitaoka |
120a6e |
update();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(m_selection);
|
|
Shinya Kitaoka |
120a6e |
m_selection->setFrameHandle(frameHandle);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::showEvent(QShowEvent *) {
|
|
Shinya Kitaoka |
120a6e |
if (m_frameHandle)
|
|
Shinya Kitaoka |
120a6e |
connect(m_frameHandle, SIGNAL(frameSwitched()), this,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onFrameSwitched()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::hideEvent(QHideEvent *) {
|
|
Shinya Kitaoka |
120a6e |
if (m_frameHandle) m_frameHandle->disconnect(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FunctionPanel::onFrameSwitched() { update(); }
|