improved nodeparamview Y setting

Still not perfect, mostly due to Qt's terrible QMainWindowLayout, but ah well
This commit is contained in:
itsmattkc
2021-01-30 10:27:52 +11:00
parent 060714cec6
commit d53885fe3d
11 changed files with 215 additions and 138 deletions
+1 -1
View File
@@ -285,7 +285,7 @@ public:
void SetIsKeyframing(bool keyframing, int element)
{
if (IsKeyframable()) {
if (!IsKeyframable()) {
qDebug() << "Ignored set keyframing because this input is not keyframable";
return;
}
+8 -8
View File
@@ -30,6 +30,8 @@
namespace olive {
#define super KeyframeViewBase
CurveView::CurveView(QWidget *parent) :
KeyframeViewBase(parent)
{
@@ -71,9 +73,7 @@ void CurveView::ConnectInput(NodeInput *input, int element, int track)
}
// Add keyframes from track
foreach (NodeKeyframe* key, input->GetKeyframeTracks(element).at(track)) {
this->AddKeyframe(key);
}
AddKeyframesOfTrack(input, element, track);
// Append to the list
connected_inputs_.append(ref);
@@ -89,9 +89,7 @@ void CurveView::DisconnectInput(NodeInput *input, int element, int track)
}
// Remove keyframes belonging to this element and track
foreach (NodeKeyframe* key, input->GetKeyframeTracks(element).at(track)) {
RemoveKeyframe(key);
}
RemoveKeyframesOfTrack(input, element, track);
// Remove from the list
connected_inputs_.removeOne(ref);
@@ -478,14 +476,16 @@ void CurveView::ResetZoom()
SetYScale(1.0);
}
void CurveView::AddKeyframe(NodeKeyframe* key)
KeyframeViewItem* CurveView::AddKeyframe(NodeKeyframe* key)
{
KeyframeViewItem* item = AddKeyframeInternal(key);
KeyframeViewItem* item = super::AddKeyframe(key);
SetItemYFromKeyframeValue(key, item);
item->SetOverrideBrush(keyframe_colors_.value({key->parent(), key->element(), key->track()}));
connect(key, &NodeKeyframe::ValueChanged, this, &CurveView::KeyframeValueChanged);
connect(key, &NodeKeyframe::TypeChanged, this, &CurveView::KeyframeTypeChanged);
return item;
}
}
+1 -1
View File
@@ -49,7 +49,7 @@ public:
void SetKeyframeTrackColor(const NodeInput::KeyframeTrackReference& ref, const QColor& color);
public slots:
void AddKeyframe(NodeKeyframe* key);
virtual KeyframeViewItem* AddKeyframe(NodeKeyframe* key) override;
void ZoomToFit();
+19 -7
View File
@@ -22,6 +22,8 @@
namespace olive {
#define super KeyframeViewBase
KeyframeView::KeyframeView(QWidget *parent) :
KeyframeViewBase(parent),
max_scroll_(0)
@@ -29,6 +31,19 @@ KeyframeView::KeyframeView(QWidget *parent) :
setAlignment(Qt::AlignLeft | Qt::AlignTop);
}
void KeyframeView::SetElementY(const NodeConnectable::InputConnection &c, int y)
{
qreal scene_y = mapToScene(mapFromGlobal(QPoint(0, y))).y();
element_y_.insert(c, scene_y);
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
if (it.key()->parent() == c.input && it.key()->element() == c.element) {
it.value()->SetOverrideY(scene_y);
}
}
}
void KeyframeView::wheelEvent(QWheelEvent *event)
{
if (!HandleZoomFromScroll(event)) {
@@ -42,14 +57,11 @@ void KeyframeView::SceneRectUpdateEvent(QRectF &rect)
rect.setHeight(max_scroll_);
}
void KeyframeView::AddKeyframe(NodeKeyframe* key, int y)
KeyframeViewItem* KeyframeView::AddKeyframe(NodeKeyframe* key)
{
QPoint global_pt(0, y);
QPoint local_pt = mapFromGlobal(global_pt);
QPointF scene_pt = mapToScene(local_pt);
KeyframeViewItem* item = AddKeyframeInternal(key);
item->SetOverrideY(scene_pt.y());
KeyframeViewItem* item = super::AddKeyframe(key);
item->SetOverrideY(element_y_.value({key->parent(), key->element()}));
return item;
}
}
+5 -1
View File
@@ -36,15 +36,19 @@ public:
max_scroll_ = i;
}
void SetElementY(const Node::InputConnection& c, int y);
protected:
virtual void wheelEvent(QWheelEvent* event) override;
virtual void SceneRectUpdateEvent(QRectF& rect) override;
public slots:
void AddKeyframe(NodeKeyframe* key, int y);
virtual KeyframeViewItem* AddKeyframe(NodeKeyframe* key) override;
private:
QHash<Node::InputConnection, qreal> element_y_;
int max_scroll_;
};
+62 -6
View File
@@ -72,6 +72,43 @@ void KeyframeViewBase::DeleteSelected()
Core::instance()->undo_stack()->pushIfHasChildren(command);
}
void KeyframeViewBase::AddKeyframesOfNode(Node *n)
{
foreach (NodeInput* i, n->inputs()) {
AddKeyframesOfInput(i);
}
}
void KeyframeViewBase::AddKeyframesOfInput(NodeInput *input)
{
if (!input->IsKeyframable()) {
return;
}
for (int i=-1; i<input->ArraySize(); i++) {
AddKeyframesOfElement(input, i);
}
}
void KeyframeViewBase::AddKeyframesOfElement(NodeInput *input, int element)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
for (int i=0; i<tracks.size(); i++) {
AddKeyframesOfTrack(input, element, i);
}
}
void KeyframeViewBase::AddKeyframesOfTrack(NodeInput *input, int element, int track)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
const NodeKeyframeTrack& t = tracks.at(track);
foreach (NodeKeyframe* key, t) {
AddKeyframe(key);
}
}
void KeyframeViewBase::RemoveKeyframesOfNode(Node *n)
{
foreach (NodeInput* i, n->inputs()) {
@@ -81,12 +118,31 @@ void KeyframeViewBase::RemoveKeyframesOfNode(Node *n)
void KeyframeViewBase::RemoveKeyframesOfInput(NodeInput *input)
{
if (!input->IsKeyframable()) {
return;
}
for (int i=-1; i<input->ArraySize(); i++) {
foreach (const NodeKeyframeTrack& track, input->GetKeyframeTracks(i)) {
foreach (NodeKeyframe* key, track) {
RemoveKeyframe(key);
}
}
RemoveKeyframesOfElement(input, i);
}
}
void KeyframeViewBase::RemoveKeyframesOfElement(NodeInput *input, int element)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
for (int i=0; i<tracks.size(); i++) {
RemoveKeyframesOfTrack(input, element, i);
}
}
void KeyframeViewBase::RemoveKeyframesOfTrack(NodeInput *input, int element, int track)
{
const QVector<NodeKeyframeTrack>& tracks = input->GetKeyframeTracks(element);
const NodeKeyframeTrack& t = tracks.at(track);
foreach (NodeKeyframe* key, t) {
RemoveKeyframe(key);
}
}
@@ -111,7 +167,7 @@ void KeyframeViewBase::RemoveKeyframe(NodeKeyframe* key)
delete item_map_.take(key);
}
KeyframeViewItem *KeyframeViewBase::AddKeyframeInternal(NodeKeyframe* key)
KeyframeViewItem *KeyframeViewBase::AddKeyframe(NodeKeyframe* key)
{
KeyframeViewItem* item = item_map_.value(key);
+14 -2
View File
@@ -40,10 +40,22 @@ public:
void DeleteSelected();
void AddKeyframesOfNode(Node* n);
void AddKeyframesOfInput(NodeInput* input);
void AddKeyframesOfElement(NodeInput* input, int element);
void AddKeyframesOfTrack(NodeInput* input, int element, int track);
void RemoveKeyframesOfNode(Node* n);
void RemoveKeyframesOfInput(NodeInput* input);
void RemoveKeyframesOfElement(NodeInput* input, int element);
void RemoveKeyframesOfTrack(NodeInput* input, int element, int track);
void SelectAll();
void DeselectAll();
@@ -52,11 +64,11 @@ signals:
void Dragged(int current_x, int current_y);
public slots:
virtual KeyframeViewItem* AddKeyframe(NodeKeyframe* key);
void RemoveKeyframe(NodeKeyframe* key);
protected:
virtual KeyframeViewItem* AddKeyframeInternal(NodeKeyframe* key);
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
+61 -34
View File
@@ -143,34 +143,9 @@ void NodeParamView::SelectNodes(const QVector<Node *> &nodes)
foreach (Node* n, nodes) {
if (!pinned_nodes_.contains(n)) {
NodeParamViewItem* item = new NodeParamViewItem(n, param_widget_area_);
item->setAllowedAreas(Qt::LeftDockWidgetArea);
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
item->SetExpanded(node_expanded_state_.value(n, true));
connect(item, &NodeParamViewItem::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
connect(item, &NodeParamViewItem::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged);
connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::RequestSelectNode);
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::QueueKeyframePositionUpdate);
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::SignalNodeOrder);
connect(item, &NodeParamViewItem::PinToggled, this, &NodeParamView::PinNode);
// Set time target
item->SetTimeTarget(GetTimeTarget());
items_.insert(n, item);
param_widget_area_->addDockWidget(Qt::LeftDockWidgetArea, item);
AddNode(n);
changes_made = true;
if (!focused_node_ && n->HasGizmos()) {
// We'll focus this node now
item->SetHighlighted(true);
focused_node_ = n;
emit FocusedNodeChanged(focused_node_);
}
}
}
@@ -276,7 +251,7 @@ void NodeParamView::UpdateItemTime(const int64_t &timestamp)
void NodeParamView::QueueKeyframePositionUpdate()
{
QMetaObject::invokeMethod(this, "PlaceKeyframesOnView", Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "UpdateElementY", Qt::QueuedConnection);
}
void NodeParamView::SignalNodeOrder()
@@ -308,10 +283,56 @@ void NodeParamView::SignalNodeOrder()
emit NodeOrderChanged(nodes);
}
void NodeParamView::AddNode(Node *n)
{
NodeParamViewItem* item = new NodeParamViewItem(n, param_widget_area_);
item->setAllowedAreas(Qt::LeftDockWidgetArea);
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
item->SetExpanded(node_expanded_state_.value(n, true));
foreach (NodeInput* input, n->inputs()) {
if (input->IsKeyframable()) {
connect(input, &NodeInput::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
connect(input, &NodeInput::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
}
}
connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged);
connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::RequestSelectNode);
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::QueueKeyframePositionUpdate);
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::SignalNodeOrder);
connect(item, &NodeParamViewItem::PinToggled, this, &NodeParamView::PinNode);
connect(item, &NodeParamViewItem::ExpandedChanged, this, &NodeParamView::UpdateElementY);
connect(item, &NodeParamViewItem::ArrayExpandedChanged, this, &NodeParamView::UpdateElementY);
// Set time target
item->SetTimeTarget(GetTimeTarget());
items_.insert(n, item);
param_widget_area_->addDockWidget(Qt::LeftDockWidgetArea, item);
if (!focused_node_ && n->HasGizmos()) {
// We'll focus this node now
item->SetHighlighted(true);
focused_node_ = n;
emit FocusedNodeChanged(focused_node_);
}
keyframe_view_->AddKeyframesOfNode(n);
}
void NodeParamView::RemoveNode(Node *n)
{
keyframe_view_->RemoveKeyframesOfNode(n);
foreach (NodeInput* input, n->inputs()) {
if (input->IsKeyframable()) {
disconnect(input, &NodeInput::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
disconnect(input, &NodeInput::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
}
}
delete items_.take(n);
if (focused_node_ == n) {
@@ -333,13 +354,6 @@ void NodeParamView::UpdateGlobalScrollBar()
vertical_scrollbar_->setRange(0, height_offscreen - keyframe_view_->height());
}
void NodeParamView::PlaceKeyframesOnView()
{
foreach (NodeParamViewItem* item, items_) {
QMetaObject::invokeMethod(item, "SignalAllKeyframes", Qt::QueuedConnection);
}
}
void NodeParamView::PinNode(bool pin)
{
NodeParamViewItem* item = static_cast<NodeParamViewItem*>(sender());
@@ -397,4 +411,17 @@ void NodeParamView::KeyframeViewDragged(int x, int y)
Q_ARG(int, x));
}
void NodeParamView::UpdateElementY()
{
for (auto it=items_.cbegin(); it!=items_.cend(); it++) {
foreach (NodeInput* input, it.key()->inputs()) {
for (int i=-1; i<input->ArraySize(); i++) {
Node::InputConnection ic = {input, i};
int y = it.value()->GetElementY(ic);
keyframe_view_->SetElementY(ic, y);
}
}
}
}
}
+4 -2
View File
@@ -105,6 +105,8 @@ private:
void SignalNodeOrder();
void AddNode(Node* n);
void RemoveNode(Node* n);
KeyframeView* keyframe_view_;
@@ -134,14 +136,14 @@ private slots:
void UpdateGlobalScrollBar();
void PlaceKeyframesOnView();
void PinNode(bool pin);
void FocusChanged(QWidget *old, QWidget *now);
void KeyframeViewDragged(int x, int y);
void UpdateElementY();
};
}
+31 -59
View File
@@ -51,8 +51,7 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
body_ = new NodeParamViewItemBody(node_);
connect(body_, &NodeParamViewItemBody::RequestSelectNode, this, &NodeParamViewItem::RequestSelectNode);
connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime);
connect(body_, &NodeParamViewItemBody::KeyframeAdded, this, &NodeParamViewItem::KeyframeAdded);
connect(body_, &NodeParamViewItemBody::KeyframeRemoved, this, &NodeParamViewItem::KeyframeRemoved);
connect(body_, &NodeParamViewItemBody::ArrayExpandedChanged, this, &NodeParamViewItem::ArrayExpandedChanged);
connect(title_bar_, &NodeParamViewItemTitleBar::ExpandedStateChanged, this, &NodeParamViewItem::SetExpanded);
connect(title_bar_, &NodeParamViewItemTitleBar::PinToggled, this, &NodeParamViewItem::PinToggled);
@@ -87,11 +86,6 @@ Node *NodeParamViewItem::GetNode() const
return node_;
}
void NodeParamViewItem::SignalAllKeyframes()
{
body_->SignalAllKeyframes();
}
void NodeParamViewItem::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
@@ -131,6 +125,8 @@ void NodeParamViewItem::SetExpanded(bool e)
{
body_->setVisible(e);
title_bar_->SetExpanded(e);
emit ExpandedChanged(e);
}
bool NodeParamViewItem::IsExpanded() const
@@ -138,6 +134,16 @@ bool NodeParamViewItem::IsExpanded() const
return body_->isVisible();
}
int NodeParamViewItem::GetElementY(const NodeConnectable::InputConnection &c) const
{
if (IsExpanded()) {
return body_->GetElementY(c);
} else {
// Not expanded, put keyframes at the titlebar Y
return mapToGlobal(title_bar_->rect().center()).y();
}
}
void NodeParamViewItem::ToggleExpanded()
{
SetExpanded(!IsExpanded());
@@ -313,10 +319,6 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, NodeInput *input,
ui_objects.key_control->SetInput(input, element);
layout->addWidget(ui_objects.key_control, row, kKeyControlColumn);
connect(ui_objects.key_control, &NodeParamViewKeyframeControl::RequestSetTime, this, &NodeParamViewItemBody::RequestSetTime);
connect(input, &NodeInput::KeyframeEnableChanged, this, &NodeParamViewItemBody::InputKeyframeEnableChanged);
connect(input, &NodeInput::KeyframeAdded, this, &NodeParamViewItemBody::InputAddedKeyframe);
connect(input, &NodeInput::KeyframeRemoved, this, &NodeParamViewItemBody::KeyframeRemoved);
}
input_ui_map_.insert(Node::InputConnection(input, element), ui_objects);
@@ -365,17 +367,24 @@ void NodeParamViewItemBody::Retranslate()
}
}
void NodeParamViewItemBody::SignalAllKeyframes()
int NodeParamViewItemBody::GetElementY(NodeConnectable::InputConnection c) const
{
for (auto i=input_ui_map_.begin(); i!=input_ui_map_.end(); i++) {
NodeInput* input = i.key().input;
foreach (const NodeKeyframeTrack& track, input->GetKeyframeTracks(i.key().element)) {
foreach (NodeKeyframe* key, track) {
InputAddedKeyframeInternal(input, i.key().element, key);
}
}
if (c.input->IsArray() && !array_ui_.value(c.input).widget->isVisible()) {
// Array is collapsed, so we'll return the Y of its root
c.element = -1;
}
// Find its row in the parameters
QLabel* lbl = input_ui_map_.value(c).main_label;
// Find label's Y position
QPoint lbl_center = lbl->rect().center();
// Find global position
lbl_center = lbl->mapToGlobal(lbl_center);
// Return Y
return lbl_center.y();
}
void NodeParamViewItemBody::EdgeChanged(Node* src, int element)
@@ -398,50 +407,13 @@ void NodeParamViewItemBody::UpdateUIForEdgeConnection(NodeInput *input, int elem
ui_objects.connected_label->setVisible(input->IsConnected(element));
}
void NodeParamViewItemBody::InputKeyframeEnableChanged(bool e, int element)
{
NodeInput* input = static_cast<NodeInput*>(sender());
foreach (const NodeKeyframeTrack& track, input->GetKeyframeTracks(element)) {
foreach (NodeKeyframe* key, track) {
if (e) {
// Add a keyframe item for each keyframe
InputAddedKeyframeInternal(input, element, key);
} else {
// Remove each keyframe item
emit KeyframeRemoved(key);
}
}
}
}
void NodeParamViewItemBody::InputAddedKeyframe(NodeKeyframe* key)
{
// Get NodeInput that emitted this signal
NodeInput* input = static_cast<NodeInput*>(sender());
InputAddedKeyframeInternal(input, key->element(), key);
}
void NodeParamViewItemBody::InputAddedKeyframeInternal(NodeInput *input, int element, NodeKeyframe* keyframe)
{
// Find its row in the parameters
QLabel* lbl = input_ui_map_.value({input, element}).main_label;
// Find label's Y position
QPoint lbl_center = lbl->rect().center();
// Find global position
lbl_center = lbl->mapToGlobal(lbl_center);
emit KeyframeAdded(keyframe, lbl_center.y());
}
void NodeParamViewItemBody::ArrayCollapseBtnPressed(bool checked)
{
NodeInput* input = array_collapse_buttons_.key(static_cast<CollapseButton*>(sender()));
array_ui_.value(input).widget->setVisible(checked);
emit ArrayExpandedChanged(checked);
}
void NodeParamViewItemBody::InputArraySizeChanged(int size)
+9 -17
View File
@@ -81,24 +81,20 @@ public:
void Retranslate();
void SignalAllKeyframes();
int GetElementY(NodeConnectable::InputConnection c) const;
signals:
void KeyframeAdded(NodeKeyframe* key, int y);
void KeyframeRemoved(NodeKeyframe* key);
void RequestSetTime(const rational& time);
void RequestSelectNode(const QVector<Node*>& node);
void ArrayExpandedChanged(bool e);
private:
void CreateWidgets(QGridLayout *layout, NodeInput* input, int element, int row_index);
void UpdateUIForEdgeConnection(NodeInput* input, int element);
void InputAddedKeyframeInternal(NodeInput* input, int element, NodeKeyframe* keyframe);
struct InputUI {
InputUI();
@@ -137,10 +133,6 @@ private:
private slots:
void EdgeChanged(Node *src, int element);
void InputKeyframeEnableChanged(bool e, int element);
void InputAddedKeyframe(NodeKeyframe* key);
void ArrayCollapseBtnPressed(bool checked);
void InputArraySizeChanged(int size);
@@ -176,24 +168,24 @@ public:
update();
}
public slots:
void SignalAllKeyframes();
int GetElementY(const Node::InputConnection& c) const;
public slots:
void SetExpanded(bool e);
void ToggleExpanded();
signals:
void KeyframeAdded(NodeKeyframe* key, int y);
void KeyframeRemoved(NodeKeyframe* key);
void RequestSetTime(const rational& time);
void RequestSelectNode(const QVector<Node*>& node);
void PinToggled(bool e);
void ExpandedChanged(bool e);
void ArrayExpandedChanged(bool e);
protected:
virtual void changeEvent(QEvent *e) override;