keyframeview: implemented transforming keyframe times to and from sequence time

Since the node graph can have transform cross nodes, input keyframes may occur
at a different times requiring transforming between sequence time and media
time. This commit implements such a mechanism in all UI classes that need it.
This commit is contained in:
itsmattkc
2020-03-26 19:17:46 +11:00
parent 592171cc31
commit 3399227b3a
27 changed files with 389 additions and 144 deletions
+13
View File
@@ -107,6 +107,8 @@ void CurveWidget::SetInput(NodeInput *input)
if (input_) {
bridge_ = new NodeParamViewWidgetBridge(input_, this);
bridge_->SetTimeTarget(GetTimeTarget());
for (int i=0;i<bridge_->widgets().size();i++) {
// Insert between two stretches to center the widget
widget_bridge_layout_->insertWidget(2 + i, bridge_->widgets().at(i));
@@ -165,6 +167,17 @@ void CurveWidget::ScaleChangedEvent(const double &scale)
view_->SetScale(scale);
}
void CurveWidget::TimeTargetChangedEvent(Node *target)
{
key_control_->SetTimeTarget(target);
view_->SetTimeTarget(target);
if (bridge_) {
bridge_->SetTimeTarget(target);
}
}
void CurveWidget::UpdateInputLabel()
{
if (input_) {
+3 -1
View File
@@ -11,7 +11,7 @@
#include "widget/nodeparamview/nodeparamviewwidgetbridge.h"
#include "widget/timebased/timebased.h"
class CurveWidget : public TimeBasedWidget
class CurveWidget : public TimeBasedWidget, public TimeTargetObject
{
Q_OBJECT
public:
@@ -31,6 +31,8 @@ protected:
virtual void TimebaseChangedEvent(const rational &) override;
virtual void ScaleChangedEvent(const double &) override;
virtual void TimeTargetChangedEvent(Node* target) override;
private:
void UpdateInputLabel();
+2
View File
@@ -24,5 +24,7 @@ set(OLIVE_SOURCES
widget/keyframeview/keyframeviewitem.cpp
widget/keyframeview/keyframeviewundo.h
widget/keyframeview/keyframeviewundo.cpp
widget/keyframeview/timetargetobject.h
widget/keyframeview/timetargetobject.cpp
PARENT_SCOPE
)
+29 -4
View File
@@ -59,6 +59,7 @@ void KeyframeViewBase::RemoveKeyframe(NodeKeyframePtr key)
KeyframeViewItem *KeyframeViewBase::AddKeyframeInternal(NodeKeyframePtr key)
{
KeyframeViewItem* item = new KeyframeViewItem(key);
item->SetTimeTarget(GetTimeTarget());
item->SetScale(GetScale());
item_map_.insert(key.get(), item);
scene()->addItem(item);
@@ -87,9 +88,12 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event)
dragging_bezier_point_ = dynamic_cast<BezierControlPointItem*>(item_under_cursor);
if (dragging_bezier_point_) {
dragging_bezier_point_start_ = dragging_bezier_point_->GetCorrespondingKeyframeHandle();
dragging_bezier_point_opposing_start_ = dragging_bezier_point_->key()->bezier_control(NodeKeyframe::get_opposing_bezier_type(dragging_bezier_point_->mode()));
} else {
QList<QGraphicsItem*> selected_items = scene()->selectedItems();
selected_keys_.resize(selected_items.size());
@@ -97,8 +101,12 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event)
for (int i=0;i<selected_items.size();i++) {
KeyframeViewItem* key = static_cast<KeyframeViewItem*>(selected_items.at(i));
selected_keys_.replace(i, {key, key->x(), key->key()->time(), key->key()->value().toDouble()});
selected_keys_.replace(i, {key,
key->x(),
GetAdjustedTime(key->key()->parent()->parentNode(), GetTimeTarget(), key->key()->time(), NodeParam::kOutput),
key->key()->value().toDouble()});
}
}
}
}
@@ -128,7 +136,12 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event)
input_parent->blockSignals(true);
keypair.key->key()->set_time(CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()));
rational node_time = GetAdjustedTime(GetTimeTarget(),
keypair.key->key()->parent()->parentNode(),
CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()),
NodeParam::kInput);
keypair.key->key()->set_time(node_time);
if (y_axis_enabled_) {
keypair.key->key()->set_value(keypair.value - mouse_diff_scaled.y());
@@ -174,7 +187,10 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event)
keypair.key->key()->parent()->blockSignals(true);
// Calculate the new time for this keyframe
rational new_time = CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x());
rational node_time = GetAdjustedTime(GetTimeTarget(),
keypair.key->key()->parent()->parentNode(),
CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()),
NodeParam::kInput);
@@ -185,7 +201,7 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event)
// the signalling once the undo command is pushed.
item->key()->set_time(keypair.time);
new NodeParamSetKeyframeTimeCommand(item->key(),
new_time,
node_time,
keypair.time,
command);
@@ -234,6 +250,15 @@ void KeyframeViewBase::KeyframeAboutToBeRemoved(NodeKeyframe *)
{
}
void KeyframeViewBase::TimeTargetChangedEvent(Node *target)
{
QMap<NodeKeyframe*, KeyframeViewItem*>::const_iterator i;
for (i=item_map_.begin();i!=item_map_.end();i++) {
i.value()->SetTimeTarget(target);
}
}
void KeyframeViewBase::SetYAxisEnabled(bool e)
{
y_axis_enabled_ = e;
+4 -1
View File
@@ -3,10 +3,11 @@
#include "keyframeviewitem.h"
#include "node/keyframe.h"
#include "timetargetobject.h"
#include "widget/curvewidget/beziercontrolpointitem.h"
#include "widget/timelinewidget/view/timelineviewbase.h"
class KeyframeViewBase : public TimelineViewBase
class KeyframeViewBase : public TimelineViewBase, public TimeTargetObject
{
Q_OBJECT
public:
@@ -35,6 +36,8 @@ protected:
virtual void KeyframeAboutToBeRemoved(NodeKeyframe* key);
virtual void TimeTargetChangedEvent(Node*) override;
void SetYAxisEnabled(bool e);
private:
+8 -2
View File
@@ -6,6 +6,7 @@
#include <QWidget>
#include "common/qtutils.h"
#include "node/input.h"
KeyframeViewItem::KeyframeViewItem(NodeKeyframePtr key, QGraphicsItem *parent) :
QGraphicsRectItem(parent),
@@ -76,11 +77,16 @@ void KeyframeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
}
}
void KeyframeViewItem::TimeTargetChangedEvent(Node *)
{
UpdatePos();
}
void KeyframeViewItem::UpdatePos()
{
double x_center = key_->time().toDouble() * scale_;
rational adjusted = GetAdjustedTime(key_->parent()->parentNode(), GetTimeTarget(), key_->time(), NodeParam::kOutput);
setPos(x_center, vert_center_);
setPos(adjusted.toDouble() * scale_, vert_center_);
}
void KeyframeViewItem::Redraw()
+4 -1
View File
@@ -4,8 +4,9 @@
#include <QGraphicsRectItem>
#include "node/keyframe.h"
#include "timetargetobject.h"
class KeyframeViewItem : public QObject, public QGraphicsRectItem
class KeyframeViewItem : public QObject, public QGraphicsRectItem, public TimeTargetObject
{
Q_OBJECT
public:
@@ -20,6 +21,8 @@ public:
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
virtual void TimeTargetChangedEvent(Node* ) override;
private:
NodeKeyframePtr key_;
@@ -0,0 +1,59 @@
#include "timetargetobject.h"
TimeTargetObject::TimeTargetObject() :
time_target_(nullptr),
path_index_(0)
{
}
Node *TimeTargetObject::GetTimeTarget() const
{
return time_target_;
}
void TimeTargetObject::SetTimeTarget(Node *target)
{
time_target_ = target;
TimeTargetChangedEvent(time_target_);
}
void TimeTargetObject::SetPathIndex(int index)
{
path_index_ = index;
}
rational TimeTargetObject::GetAdjustedTime(Node* from, Node* to, const rational &r, NodeParam::Type direction) const
{
if (!from || !to) {
return r;
}
return GetAdjustedTime(from, to, TimeRange(r, r), direction).in();
}
TimeRange TimeTargetObject::GetAdjustedTime(Node* from, Node* to, const TimeRange &r, NodeParam::Type direction) const
{
if (!from || !to) {
return r;
}
QList<TimeRange> adjusted = from->TransformTimeTo(r, to, direction);
if (adjusted.isEmpty()) {
return r;
}
return adjusted.at(path_index_);
}
/*int TimeTargetObject::GetNumberOfPathAdjustments(Node* from, NodeParam::Type direction) const
{
if (!time_target_) {
return 0;
}
QList<TimeRange> adjusted = from->TransformTimeTo(TimeRange(), time_target_, direction);
return adjusted.size();
}*/
@@ -0,0 +1,31 @@
#ifndef TIMETARGETOBJECT_H
#define TIMETARGETOBJECT_H
#include "node/node.h"
class TimeTargetObject
{
public:
TimeTargetObject();
Node* GetTimeTarget() const;
void SetTimeTarget(Node* target);
void SetPathIndex(int index);
rational GetAdjustedTime(Node* from, Node* to, const rational& r, NodeParam::Type direction) const;
TimeRange GetAdjustedTime(Node* from, Node* to, const TimeRange& r, NodeParam::Type direction) const;
//int GetNumberOfPathAdjustments(Node* from, NodeParam::Type direction) const;
protected:
virtual void TimeTargetChangedEvent(Node* ){}
private:
Node* time_target_;
int path_index_;
};
#endif // TIMETARGETOBJECT_H
+11 -8
View File
@@ -123,6 +123,7 @@ void NodeParamView::SetNodes(QList<Node *> nodes)
delete item;
}
items_.clear();
emit TimeTargetChanged(nullptr);
// Reset keyframe view
SetTimebase(rational());
@@ -149,21 +150,23 @@ void NodeParamView::SetNodes(QList<Node *> nodes)
}
if (!nodes_.isEmpty()) {
const ViewerOutput* viewer = nodes_.first()->FindOutputNode<ViewerOutput>();
ViewerOutput* viewer = nodes_.first()->FindOutputNode<ViewerOutput>();
if (viewer) {
SetTimebase(viewer->video_params().time_base());
// Set viewer as a time target
keyframe_view_->SetTimeTarget(viewer);
foreach (NodeParamViewItem* item, items_) {
item->SetTimeTarget(viewer);
}
emit TimeTargetChanged(viewer);
}
}
SetTime(0);
// FIXME: Test code only!
if (nodes_.isEmpty()) {
emit SelectedInputChanged(nullptr);
} else {
emit SelectedInputChanged(static_cast<NodeInput*>(nodes_.first()->parameters().first()));
}
}
void NodeParamView::resizeEvent(QResizeEvent *event)
+2
View File
@@ -41,6 +41,8 @@ public:
signals:
void SelectedInputChanged(NodeInput* input);
void TimeTargetChanged(Node* target);
protected:
virtual void resizeEvent(QResizeEvent *event) override;
@@ -73,6 +73,17 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
SetupUI();
}
void NodeParamViewItem::SetTimeTarget(Node *target)
{
foreach (NodeParamViewKeyframeControl* control, key_control_list_) {
control->SetTimeTarget(target);
}
foreach (NodeParamViewWidgetBridge* bridge, bridges_) {
bridge->SetTimeTarget(target);
}
}
void NodeParamViewItem::SetTime(const rational &time)
{
time_ = time;
@@ -46,6 +46,8 @@ class NodeParamViewItem : public QWidget
public:
NodeParamViewItem(Node* node, QWidget* parent = nullptr);
void SetTimeTarget(Node* target);
void SetTime(const rational& time);
public slots:
@@ -102,6 +102,16 @@ void NodeParamViewKeyframeControl::SetButtonsEnabled(bool e)
enable_key_btn_->setEnabled(e);
}
rational NodeParamViewKeyframeControl::GetCurrentTimeAsNodeTime() const
{
return GetAdjustedTime(GetTimeTarget(), input_->parentNode(), time_, NodeParam::kInput);
}
rational NodeParamViewKeyframeControl::ConvertToViewerTime(const rational &r) const
{
return GetAdjustedTime(input_->parentNode(), GetTimeTarget(), r, NodeParam::kOutput);
}
void NodeParamViewKeyframeControl::ShowButtonsFromKeyframeEnable(bool e)
{
prev_key_btn_->setVisible(e);
@@ -111,16 +121,18 @@ void NodeParamViewKeyframeControl::ShowButtonsFromKeyframeEnable(bool e)
void NodeParamViewKeyframeControl::ToggleKeyframe(bool e)
{
QList<NodeKeyframePtr> keys = input_->get_keyframe_at_time(time_);
rational node_time = GetCurrentTimeAsNodeTime();
QList<NodeKeyframePtr> keys = input_->get_keyframe_at_time(node_time);
QUndoCommand* command = new QUndoCommand();
if (e && keys.isEmpty()) {
// Add a keyframe here (one for each track)
for (int i=0;i<input_->get_number_of_keyframe_tracks();i++) {
NodeKeyframePtr key = NodeKeyframe::Create(time_,
input_->get_value_at_time_for_track(time_, i),
input_->get_best_keyframe_type_for_time(time_, i),
NodeKeyframePtr key = NodeKeyframe::Create(node_time,
input_->get_value_at_time_for_track(node_time, i),
input_->get_best_keyframe_type_for_time(node_time, i),
i);
new NodeParamInsertKeyframeCommand(input_, key, command);
@@ -134,7 +146,7 @@ void NodeParamViewKeyframeControl::ToggleKeyframe(bool e)
// If this was the last keyframe on this track, set the standard value to the value at this time too
new NodeParamSetStandardValueCommand(input_,
key->track(),
input_->get_value_at_time_for_track(time_, key->track()),
input_->get_value_at_time_for_track(node_time, key->track()),
command);
}
}
@@ -152,26 +164,36 @@ void NodeParamViewKeyframeControl::UpdateState()
NodeKeyframePtr earliest_key = input_->get_earliest_keyframe();
NodeKeyframePtr latest_key = input_->get_latest_keyframe();
prev_key_btn_->setEnabled(earliest_key && time_ > earliest_key->time());
next_key_btn_->setEnabled(latest_key && time_ < latest_key->time());
toggle_key_btn_->setChecked(input_->has_keyframe_at_time(time_));
rational node_time = GetCurrentTimeAsNodeTime();
prev_key_btn_->setEnabled(earliest_key && node_time > earliest_key->time());
next_key_btn_->setEnabled(latest_key && node_time < latest_key->time());
toggle_key_btn_->setChecked(input_->has_keyframe_at_time(node_time));
}
void NodeParamViewKeyframeControl::GoToPreviousKey()
{
NodeKeyframePtr previous_key = input_->get_closest_keyframe_before_time(time_);
rational node_time = GetCurrentTimeAsNodeTime();
NodeKeyframePtr previous_key = input_->get_closest_keyframe_before_time(node_time);
if (previous_key) {
emit RequestSetTime(previous_key->time());
rational key_time = ConvertToViewerTime(previous_key->time());
emit RequestSetTime(key_time);
}
}
void NodeParamViewKeyframeControl::GoToNextKey()
{
NodeKeyframePtr next_key = input_->get_closest_keyframe_after_time(time_);
rational node_time = GetCurrentTimeAsNodeTime();
NodeKeyframePtr next_key = input_->get_closest_keyframe_after_time(node_time);
if (next_key) {
emit RequestSetTime(next_key->time());
rational key_time = ConvertToViewerTime(next_key->time());
emit RequestSetTime(key_time);
}
}
@@ -192,7 +214,7 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
QVector<QVariant> key_vals = input_->get_split_standard_value();
for (int i=0;i<key_vals.size();i++) {
NodeKeyframePtr key = NodeKeyframe::Create(time_,
NodeKeyframePtr key = NodeKeyframe::Create(GetCurrentTimeAsNodeTime(),
key_vals.at(i),
NodeKeyframe::kDefaultType,
i);
@@ -207,7 +229,7 @@ void NodeParamViewKeyframeControl::KeyframeEnableChanged(bool e)
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
// Store value at this time, we'll set this as the persistent value later
QVector<QVariant> stored_vals = input_->get_split_values_at_time(time_);
QVector<QVariant> stored_vals = input_->get_split_values_at_time(GetCurrentTimeAsNodeTime());
// Delete all keyframes
foreach (const NodeInput::KeyframeTrack& track, input_->keyframe_tracks()) {
@@ -5,8 +5,9 @@
#include <QWidget>
#include "node/input.h"
#include "widget/keyframeview/timetargetobject.h"
class NodeParamViewKeyframeControl : public QWidget
class NodeParamViewKeyframeControl : public QWidget, public TimeTargetObject
{
Q_OBJECT
public:
@@ -26,6 +27,10 @@ private:
void SetButtonsEnabled(bool e);
rational GetCurrentTimeAsNodeTime() const;
rational ConvertToViewerTime(const rational& r) const;
QPushButton* prev_key_btn_;
QPushButton* toggle_key_btn_;
QPushButton* next_key_btn_;
@@ -36,80 +36,10 @@ void NodeParamViewWidgetBridge::SetTime(const rational &time)
return;
}
// We assume the first data type is the "primary" type
switch (input_->data_type()) {
// None of these inputs have applicable UI widgets
case NodeParam::kNone:
case NodeParam::kAny:
case NodeParam::kTexture:
case NodeParam::kMatrix:
case NodeParam::kRational:
case NodeParam::kSamples:
case NodeParam::kDecimal:
case NodeParam::kNumber:
case NodeParam::kString:
case NodeParam::kBuffer:
case NodeParam::kVector:
break;
case NodeParam::kInt:
static_cast<IntegerSlider*>(widgets_.first())->SetValue(input_->get_value_at_time(time).toLongLong());
break;
case NodeParam::kFloat:
static_cast<FloatSlider*>(widgets_.first())->SetValue(input_->get_value_at_time(time).toDouble());
break;
case NodeParam::kVec2:
{
QVector2D vec2 = input_->get_value_at_time(time).value<QVector2D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec2.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec2.y()));
break;
}
case NodeParam::kVec3:
{
QVector3D vec3 = input_->get_value_at_time(time).value<QVector3D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec3.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec3.y()));
static_cast<FloatSlider*>(widgets_.at(2))->SetValue(static_cast<double>(vec3.z()));
break;
}
case NodeParam::kVec4:
{
QVector4D vec4 = input_->get_value_at_time(time).value<QVector4D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec4.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec4.y()));
static_cast<FloatSlider*>(widgets_.at(2))->SetValue(static_cast<double>(vec4.z()));
static_cast<FloatSlider*>(widgets_.at(3))->SetValue(static_cast<double>(vec4.w()));
break;
}
case NodeParam::kFile:
// FIXME: File selector
break;
case NodeParam::kColor:
// FIXME: Color selector
break;
case NodeParam::kText:
{
static_cast<QLineEdit*>(widgets_.first())->setText(input_->get_value_at_time(time).toString());
break;
}
case NodeParam::kBoolean:
static_cast<QCheckBox*>(widgets_.first())->setChecked(input_->get_value_at_time(time).toBool());
break;
case NodeParam::kFont:
{
// FIXME: Implement this
break;
}
case NodeParam::kFootage:
static_cast<FootageComboBox*>(widgets_.first())->SetFootage(input_->get_value_at_time(time).value<StreamPtr>());
break;
}
UpdateWidgetValues();
}
const QList<QWidget *> &NodeParamViewWidgetBridge::widgets()
const QList<QWidget *> &NodeParamViewWidgetBridge::widgets() const
{
return widgets_;
}
@@ -207,18 +137,20 @@ void NodeParamViewWidgetBridge::CreateWidgets()
void NodeParamViewWidgetBridge::SetInputValue(const QVariant &value, int track)
{
rational node_time = GetCurrentTimeAsNodeTime();
QUndoCommand* command = new QUndoCommand();
if (input_->is_keyframing()) {
NodeKeyframePtr existing_key = input_->get_keyframe_at_time_on_track(time_, track);
NodeKeyframePtr existing_key = input_->get_keyframe_at_time_on_track(node_time, track);
if (existing_key) {
new NodeParamSetKeyframeValueCommand(existing_key, value, command);
} else {
// No existing key, create a new one
NodeKeyframePtr new_key = NodeKeyframe::Create(time_,
NodeKeyframePtr new_key = NodeKeyframe::Create(node_time,
value,
input_->get_best_keyframe_type_for_time(time_, track),
input_->get_best_keyframe_type_for_time(node_time, track),
track);
new NodeParamInsertKeyframeCommand(input_, new_key, command);
@@ -232,6 +164,8 @@ void NodeParamViewWidgetBridge::SetInputValue(const QVariant &value, int track)
void NodeParamViewWidgetBridge::ProcessSlider(SliderBase *slider, const QVariant &value)
{
rational node_time = GetCurrentTimeAsNodeTime();
int slider_track = widgets_.indexOf(slider);
if (slider->IsDragging()) {
@@ -244,17 +178,17 @@ void NodeParamViewWidgetBridge::ProcessSlider(SliderBase *slider, const QVariant
dragging_ = true;
// Cache current value
drag_old_value_ = input_->get_value_at_time_for_track(time_, slider_track);
drag_old_value_ = input_->get_value_at_time_for_track(node_time, slider_track);
// Determine whether we are creating a keyframe or not
if (input_->is_keyframing()) {
dragging_keyframe_ = input_->get_keyframe_at_time_on_track(time_, slider_track);
dragging_keyframe_ = input_->get_keyframe_at_time_on_track(node_time, slider_track);
drag_created_keyframe_ = !dragging_keyframe_;
if (drag_created_keyframe_) {
dragging_keyframe_ = NodeKeyframe::Create(time_,
dragging_keyframe_ = NodeKeyframe::Create(node_time,
value,
input_->get_best_keyframe_type_for_time(time_, slider_track),
input_->get_best_keyframe_type_for_time(node_time, slider_track),
slider_track);
input_->insert_keyframe(dragging_keyframe_);
@@ -406,11 +340,93 @@ void NodeParamViewWidgetBridge::CreateSliders(int count)
}
}
void NodeParamViewWidgetBridge::UpdateWidgetValues()
{
rational node_time = GetCurrentTimeAsNodeTime();
// We assume the first data type is the "primary" type
switch (input_->data_type()) {
// None of these inputs have applicable UI widgets
case NodeParam::kNone:
case NodeParam::kAny:
case NodeParam::kTexture:
case NodeParam::kMatrix:
case NodeParam::kRational:
case NodeParam::kSamples:
case NodeParam::kDecimal:
case NodeParam::kNumber:
case NodeParam::kString:
case NodeParam::kBuffer:
case NodeParam::kVector:
break;
case NodeParam::kInt:
static_cast<IntegerSlider*>(widgets_.first())->SetValue(input_->get_value_at_time(node_time).toLongLong());
break;
case NodeParam::kFloat:
static_cast<FloatSlider*>(widgets_.first())->SetValue(input_->get_value_at_time(node_time).toDouble());
break;
case NodeParam::kVec2:
{
QVector2D vec2 = input_->get_value_at_time(node_time).value<QVector2D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec2.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec2.y()));
break;
}
case NodeParam::kVec3:
{
QVector3D vec3 = input_->get_value_at_time(node_time).value<QVector3D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec3.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec3.y()));
static_cast<FloatSlider*>(widgets_.at(2))->SetValue(static_cast<double>(vec3.z()));
break;
}
case NodeParam::kVec4:
{
QVector4D vec4 = input_->get_value_at_time(node_time).value<QVector4D>();
static_cast<FloatSlider*>(widgets_.at(0))->SetValue(static_cast<double>(vec4.x()));
static_cast<FloatSlider*>(widgets_.at(1))->SetValue(static_cast<double>(vec4.y()));
static_cast<FloatSlider*>(widgets_.at(2))->SetValue(static_cast<double>(vec4.z()));
static_cast<FloatSlider*>(widgets_.at(3))->SetValue(static_cast<double>(vec4.w()));
break;
}
case NodeParam::kFile:
// FIXME: File selector
break;
case NodeParam::kColor:
// FIXME: Color selector
break;
case NodeParam::kText:
{
static_cast<QLineEdit*>(widgets_.first())->setText(input_->get_value_at_time(node_time).toString());
break;
}
case NodeParam::kBoolean:
static_cast<QCheckBox*>(widgets_.first())->setChecked(input_->get_value_at_time(node_time).toBool());
break;
case NodeParam::kFont:
{
// FIXME: Implement this
break;
}
case NodeParam::kFootage:
static_cast<FootageComboBox*>(widgets_.first())->SetFootage(input_->get_value_at_time(node_time).value<StreamPtr>());
break;
}
}
rational NodeParamViewWidgetBridge::GetCurrentTimeAsNodeTime() const
{
return GetAdjustedTime(GetTimeTarget(), input_->parentNode(), time_, NodeParam::kInput);
}
void NodeParamViewWidgetBridge::InputValueChanged(const rational &start, const rational &end)
{
if (!dragging_ && start <= time_ && end >= time_) {
// We'll need to update the widgets because the values have changed on our current time
SetTime(time_);
UpdateWidgetValues();
}
}
@@ -4,9 +4,10 @@
#include <QObject>
#include "node/input.h"
#include "widget/keyframeview/timetargetobject.h"
#include "widget/slider/sliderbase.h"
class NodeParamViewWidgetBridge : public QObject
class NodeParamViewWidgetBridge : public QObject, public TimeTargetObject
{
Q_OBJECT
public:
@@ -14,7 +15,7 @@ public:
void SetTime(const rational& time);
const QList<QWidget*>& widgets();
const QList<QWidget*>& widgets() const;
private:
void CreateWidgets();
@@ -25,6 +26,10 @@ private:
void CreateSliders(int count);
void UpdateWidgetValues();
rational GetCurrentTimeAsNodeTime() const;
NodeInput* input_;
QList<QWidget*> widgets_;