#ifndef PARAMFIELD_H
#define PARAMFIELD_H
#ifdef _WIN32
#pragma warning(disable : 4251)
#endif
#include "tcommon.h"
#include <QWidget>
#include <QSpinBox>
#include <QSlider>
#include <QCheckBox>
#include <QButtonGroup>
#include <QRadioButton>
#include <QPushButton>
#include "tgeometry.h"
#include "tparam.h"
#include "tnotanimatableparam.h"
#include "tspectrumparam.h"
#include "ttonecurveparam.h"
#include "tdoubleparam.h"
#include "toonz/tfxhandle.h"
#include "historytypes.h"
#undef DVAPI
#undef DVVAR
#ifdef TOONZQT_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
// forward declaration
class QString;
class QComboBox;
class QHBoxLayout;
class TFxHandle;
namespace DVGui
{
class LineEdit;
class IntField;
class DoubleField;
class MeasuredDoubleField;
class MeasuredDoublePairField;
class ColorField;
class SpectrumField;
class ToneCurveField;
class CheckBox;
}
//=============================================================================
/*! \brief ParamField.
Inherits \b QWidget.
*/
class DVAPI ParamField : public QWidget
{
Q_OBJECT
protected:
QHBoxLayout *m_layout;
QString m_paramName;
static TFxHandle *m_fxHandleStat;
QString m_interfaceName;
QString m_description;
public:
ParamField(QWidget *parent, QString paramName, const TParamP ¶m, bool addEmptyLabel = true);
~ParamField();
QString getParamName() const { return m_paramName; }
QString getUIName() const { return m_interfaceName; }
QString getDescription() const { return m_description; }
virtual void setParam(const TParamP ¤t, const TParamP &actual, int frame) = 0;
virtual void update(int frame) = 0;
static ParamField *create(QWidget *parent, QString name, const TParamP ¶m);
virtual void setPointValue(const TPointD &p){};
virtual QSize getPreferedSize() { return QSize(200, 28); }
static void setFxHandle(TFxHandle *fxHandle);
virtual void setPrecision(int precision) {}
signals:
void currentParamChanged();
void actualParamChanged();
void paramKeyToggle();
};
//=============================================================================
// ParamFieldKeyToggle
//-----------------------------------------------------------------------------
class DVAPI ParamFieldKeyToggle : public QWidget
{
Q_OBJECT
public:
enum Status {
NOT_ANIMATED,
NOT_KEYFRAME,
MODIFIED,
KEYFRAME
};
private:
Status m_status;
bool m_highlighted;
public:
ParamFieldKeyToggle(QWidget *parent, std::string name = "ParamFieldKeyToggle");
void setStatus(Status status);
Status getStatus() const;
void setStatus(bool hasKeyframe, bool isKeyframe, bool hasBeenChanged);
protected:
void paintEvent(QPaintEvent *);
void mousePressEvent(QMouseEvent *);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
signals:
void keyToggled();
};
//=============================================================================
// FxSettingsKeyToggleUndo
//=============================================================================
template <class T, class ParamP>
class FxSettingsKeyToggleUndo : public TUndo
{
TFxHandle *m_fxHandle;
QString m_name;
bool m_wasKeyframe;
int m_frame;
ParamP m_param;
T m_currentValue;
public:
FxSettingsKeyToggleUndo(ParamP param, T currentValue, bool wasKeyFrame, QString name, int frame, TFxHandle *fxHandle)
: m_param(param), m_currentValue(currentValue), m_wasKeyframe(wasKeyFrame), m_name(name), m_frame(frame), m_fxHandle(fxHandle)
{
}
//void notify();
void undo() const
{
if (m_wasKeyframe)
m_param->setValue(m_frame, m_currentValue);
else
m_param->deleteKeyframe(m_frame);
if (m_fxHandle)
m_fxHandle->notifyFxChanged();
}
void redo() const
{
if (m_wasKeyframe)
m_param->deleteKeyframe(m_frame);
else
m_param->setValue(m_frame, m_currentValue);
if (m_fxHandle)
m_fxHandle->notifyFxChanged();
}
int getSize() const
{
return sizeof(*this);
}
int getHistoryType()
{
return HistoryType::Fx;
}
QString getHistoryString()
{
QString str = QObject::tr("Modify Fx Param : %1 Key : %2 Frame %3")
.arg((m_wasKeyframe) ? QObject::tr("Delete") : QObject::tr("Set"))
.arg(m_name)
.arg(QString::number(m_frame + 1));
return str;
}
};
//=============================================================================
// AnimatedParamField
//-----------------------------------------------------------------------------
template <class T, class ParamP>
class DVAPI AnimatedParamField : public ParamField
{
protected:
ParamP m_currentParam, m_actualParam;
int m_frame;
ParamFieldKeyToggle *m_keyToggle;
public:
AnimatedParamField(QWidget *parent, QString name, const ParamP ¶m, bool addEmptyLabel = true)
: ParamField(parent, name, param, addEmptyLabel), m_frame(0)
{
m_keyToggle = new ParamFieldKeyToggle(this);
}
virtual void updateField(T value) = 0;
void setParam(const TParamP ¤t, const TParamP &actual, int frame)
{
m_currentParam = current;
m_actualParam = actual;
assert(m_currentParam);
assert(m_actualParam);
update(frame);
}
void update(int frame)
{
m_frame = frame;
if (!m_actualParam || !m_currentParam)
return;
T value = m_actualParam->getValue(m_frame);
if (m_actualParam->isKeyframe(m_frame))
m_currentParam->setValue(m_frame, value);
else if (!m_actualParam.getPointer()->hasKeyframes())
m_currentParam->setDefaultValue(value);
updateField(value);
updateKeyToggle();
}
void updateKeyToggle()
{
T stroke = m_actualParam->getValue(m_frame);
T stroke2 = m_currentParam->getValue(m_frame);
m_keyToggle->setStatus(m_actualParam->hasKeyframes(), m_actualParam->isKeyframe(m_frame),
m_actualParam->getValue(m_frame) != m_currentParam->getValue(m_frame));
}
/*-- エフェクトの位置パラメータをSwatchViewerでドラッグして編集するときに呼ばれる ---*/
void setValue(T value)
{
if (m_currentParam->getValue(m_frame) == value)
return;
m_currentParam->setValue(m_frame, value);
/*-- キーフレーム上で操作した場合 --*/
if (m_actualParam->isKeyframe(m_frame)) {
m_actualParam->setValue(m_frame, value);
emit actualParamChanged();
}
/*-- キーフレーム無い場合 --*/
else if (!m_actualParam.getPointer()->hasKeyframes()) {
m_actualParam->setDefaultValue(value);
emit actualParamChanged();
}
/*-- 他にキーフレームがあって、キーフレーム以外のフレームで操作した場合 --*/
emit currentParamChanged();
updateKeyToggle();
}
void onKeyToggle()
{
T currentVal = m_currentParam->getValue(m_frame);
bool wasKeyFrame;
if (m_keyToggle->getStatus() == ParamFieldKeyToggle::KEYFRAME) {
m_actualParam->deleteKeyframe(m_frame);
update(m_frame);
wasKeyFrame = true;
} else {
m_actualParam->setValue(m_frame, m_currentParam->getValue(m_frame));
updateKeyToggle();
wasKeyFrame = false;
}
emit actualParamChanged();
emit paramKeyToggle();
TUndoManager::manager()->add(
new FxSettingsKeyToggleUndo<T, ParamP>(m_actualParam,
currentVal,
wasKeyFrame,
m_interfaceName,
m_frame,
ParamField::m_fxHandleStat));
}
};
//=============================================================================
// MeasuredDoubleParamField
//-----------------------------------------------------------------------------
class DVAPI MeasuredDoubleParamField : public AnimatedParamField<double, TDoubleParamP>
{
Q_OBJECT
DVGui::MeasuredDoubleField *m_measuredDoubleField;
public:
MeasuredDoubleParamField(QWidget *parent, QString name, const TDoubleParamP ¶m);
void updateField(double value);
QSize getPreferedSize() { return QSize(260, 28); }
protected slots:
void onChange(bool);
void onKeyToggled();
};
//=============================================================================
// RangeParamField
//-----------------------------------------------------------------------------
class DVAPI MeasuredRangeParamField : public AnimatedParamField<DoublePair, TRangeParamP>
{
Q_OBJECT
DVGui::MeasuredDoublePairField *m_valueField;
public:
MeasuredRangeParamField(QWidget *parent, QString name, const TRangeParamP ¶m);
void updateField(DoublePair value);
QSize getPreferedSize() { return QSize(300, 20); }
void setPrecision(int precision);
protected slots:
void onChange(bool);
void onKeyToggled();
};
//=============================================================================
// PointParamField
//-----------------------------------------------------------------------------
class DVAPI PointParamField : public AnimatedParamField<TPointD, TPointParamP>
{
Q_OBJECT
DVGui::MeasuredDoubleField *m_xFld, *m_yFld;
public:
PointParamField(QWidget *parent, QString name, const TPointParamP ¶m);
void setPointValue(const TPointD &p);
void updateField(TPointD value);
QSize getPreferedSize() { return QSize(270, 28); }
protected slots:
void onChange(bool);
void onKeyToggled();
};
//=============================================================================
// PixelParamField
//-----------------------------------------------------------------------------
class DVAPI PixelParamField : public AnimatedParamField<TPixel32, TPixelParamP>
{
Q_OBJECT
DVGui::ColorField *m_colorField;
public:
PixelParamField(QWidget *parent, QString name, const TPixelParamP ¶m);
void updateField(TPixel32 value);
QSize getPreferedSize() { return QSize(360, 40); }
/*-- RgbLinkButtonの実行のため --*/
TPixel32 getColor();
void setColor(TPixel32 value);
protected:
void setParams();
protected slots:
void onChange(const TPixel32 &value, bool isDragging);
void onKeyToggled();
};
//=============================================================================
// RGB Link Button
//-----------------------------------------------------------------------------
class DVAPI RgbLinkButton : public QPushButton
{
Q_OBJECT
PixelParamField *m_field1, *m_field2;
public:
RgbLinkButton(QString str, QWidget *parent, PixelParamField *field1, PixelParamField *field2);
protected slots:
void onButtonClicked();
};
//=============================================================================
// SpectrumParamField
//-----------------------------------------------------------------------------
class DVAPI SpectrumParamField : public AnimatedParamField<TSpectrum, TSpectrumParamP>
{
Q_OBJECT
DVGui::SpectrumField *m_spectrumField;
public:
SpectrumParamField(QWidget *parent, QString name, const TSpectrumParamP ¶m);
void updateField(TSpectrum value);
void setParams();
QSize getPreferedSize() { return QSize(390, 60); }
protected slots:
void onKeyToggled();
void onChange(bool isDragging);
void onKeyAdded(int keyIndex);
void onKeyRemoved(int keyIndex);
};
//=============================================================================
// EnumParamField
//-----------------------------------------------------------------------------
class EnumParamField : public ParamField
{
Q_OBJECT
TIntEnumParamP m_currentParam, m_actualParam;
QComboBox *m_om;
public:
EnumParamField(QWidget *parent, QString name, const TIntEnumParamP ¶m);
void setParam(const TParamP ¤t, const TParamP &actual, int frame);
void update(int frame);
QSize getPreferedSize() { return QSize(150, 20); }
protected slots:
void onChange(const QString &str);
};
//=============================================================================
// BoolParamField
//-----------------------------------------------------------------------------
class DVAPI BoolParamField : public ParamField
{
Q_OBJECT
TBoolParamP m_currentParam, m_actualParam;
DVGui::CheckBox *m_checkBox;
public:
BoolParamField(QWidget *parent, QString name, const TBoolParamP ¶m);
void setParam(const TParamP ¤t, const TParamP &actual, int frame);
void update(int frame);
QSize getPreferedSize() { return QSize(20, 10); }
protected slots:
void onToggled(bool checked);
/*-- visibleToggle UIで使用する --*/
signals:
void toggled(bool);
};
//=============================================================================
// IntParamField
//-----------------------------------------------------------------------------
class DVAPI IntParamField : public ParamField
{
Q_OBJECT
TIntParamP m_currentParam, m_actualParam;
DVGui::IntField *m_intField;
typedef IntParamField This;
public:
IntParamField(QWidget *parent = 0, QString name = 0, const TIntParamP ¶m = 0);
void setParam(const TParamP ¤t, const TParamP &actual, int frame);
void update(int frame);
QSize getPreferedSize() { return QSize(50, 28); }
protected slots:
void onChange(bool isDragging = false);
};
//=============================================================================
// StringParamField
//-----------------------------------------------------------------------------
class DVAPI StringParamField : public ParamField
{
Q_OBJECT
TStringParamP m_currentParam, m_actualParam;
DVGui::LineEdit *m_textFld;
public:
StringParamField(QWidget *parent, QString name, const TStringParamP ¶m);
void setParam(const TParamP ¤t, const TParamP &actual, int frame);
void update(int frame);
QSize getPreferedSize() { return QSize(100, 20); }
protected slots:
void onChange();
};
//=============================================================================
// ToneCurveParamField
//-----------------------------------------------------------------------------
class DVAPI ToneCurveParamField : public AnimatedParamField<const QList<TPointD>, TToneCurveParamP>
{
Q_OBJECT
DVGui::ToneCurveField *m_toneCurveField;
public:
ToneCurveParamField(QWidget *parent, QString name, const TToneCurveParamP ¶m);
void updateField(const QList<TPointD> value);
void setParams();
QSize getPreferedSize() { return QSize(400, 380); }
protected slots:
void onChannelChanged(int);
void onChange(bool isDragging);
void onPointAdded(int index);
void onPointRemoved(int index);
void onIsLinearChanged(bool);
void onKeyToggled();
};
namespace component
{
class DVAPI LineEdit_double : public ParamField
{
Q_OBJECT; // could not use templates for Q_OBJECT
int frame_;
TDoubleParamP current_;
TDoubleParamP actual_;
QLineEdit *value_;
public:
LineEdit_double(QWidget *parent, QString name, TDoubleParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(QString const &text); // could not use MACROs for slots
};
class DVAPI Slider_double : public ParamField
{
Q_OBJECT;
int frame_;
TDoubleParamP current_;
TDoubleParamP actual_;
QSlider *value_;
public:
Slider_double(QWidget *parent, QString name, TDoubleParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(int);
};
class DVAPI SpinBox_double : public ParamField
{
Q_OBJECT;
int frame_;
TDoubleParamP current_;
TDoubleParamP actual_;
QDoubleSpinBox *value_;
public:
SpinBox_double(QWidget *parent, QString name, TDoubleParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(double);
};
}
namespace component
{
class DVAPI LineEdit_int : public ParamField
{
Q_OBJECT;
int frame_;
TIntParamP current_;
TIntParamP actual_;
QLineEdit *value_;
public:
LineEdit_int(QWidget *parent, QString name, TIntParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(QString const &text);
};
class DVAPI Slider_int : public ParamField
{
Q_OBJECT;
int frame_;
TIntParamP current_;
TIntParamP actual_;
QSlider *value_;
public:
Slider_int(QWidget *parent, QString name, TIntParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(int);
};
class DVAPI SpinBox_int : public ParamField
{
Q_OBJECT;
int frame_;
TIntParamP current_;
TIntParamP actual_;
QSpinBox *value_;
public:
SpinBox_int(QWidget *parent, QString name, TIntParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(int);
};
} // end of namespace component
namespace component
{
class DVAPI CheckBox_bool : public ParamField
{
Q_OBJECT;
int frame_;
TBoolParamP current_;
TBoolParamP actual_;
QCheckBox *value_;
public:
CheckBox_bool(QWidget *parent, QString name, TBoolParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(int);
};
} // end of namespace component
namespace component
{
class DVAPI RadioButton_enum : public ParamField
{
Q_OBJECT;
int frame_;
TIntEnumParamP current_;
TIntEnumParamP actual_;
QButtonGroup *value_;
public:
RadioButton_enum(QWidget *parent, QString name, TIntEnumParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(int);
};
class DVAPI ComboBox_enum : public ParamField
{
Q_OBJECT;
int frame_;
TIntEnumParamP current_;
TIntEnumParamP actual_;
QComboBox *value_;
public:
ComboBox_enum(QWidget *parent, QString name, TIntEnumParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(int);
};
} // end of namespace component
namespace component
{
class DVAPI LineEdit_string : public ParamField
{
Q_OBJECT;
int frame_;
TStringParamP current_;
TStringParamP actual_;
QLineEdit *value_;
public:
LineEdit_string(QWidget *parent, QString name, TStringParamP const ¶m);
void setParam(TParamP const ¤t, TParamP const &actual, int frame);
void update(int frame);
protected slots:
void update_value(QString const &);
};
} // end of namespace component
#ifdef __cplusplus
extern "C" {
#endif
#define TOONZ_DECLARE_MAKE_WIDGET(NAME) \
ParamField *NAME(QWidget *parent, QString name, TParamP const ¶m)
TOONZ_DECLARE_MAKE_WIDGET(make_lineedit);
TOONZ_DECLARE_MAKE_WIDGET(make_slider);
TOONZ_DECLARE_MAKE_WIDGET(make_spinbox);
TOONZ_DECLARE_MAKE_WIDGET(make_checkbox);
TOONZ_DECLARE_MAKE_WIDGET(make_radiobutton);
TOONZ_DECLARE_MAKE_WIDGET(make_combobox);
#ifdef __cplusplus
}
#endif
#endif // PARAMFIELD_H