implement keyframe track separation in curve view

This commit is contained in:
itsmattkc
2021-01-24 12:09:00 +11:00
parent 4dd2b64c6d
commit b68397d687
8 changed files with 291 additions and 166 deletions
+91 -13
View File
@@ -4,9 +4,11 @@ namespace olive {
NodeTreeView::NodeTreeView(QWidget *parent) :
QTreeWidget(parent),
only_show_keyframable_(false)
only_show_keyframable_(false),
show_keyframe_tracks_as_rows_(false)
{
connect(this, &NodeTreeView::itemChanged, this, &NodeTreeView::ItemCheckStateChanged);
connect(this, &NodeTreeView::itemSelectionChanged, this, &NodeTreeView::SelectionChanged);
Retranslate();
}
@@ -16,9 +18,9 @@ bool NodeTreeView::IsNodeEnabled(Node *n) const
return !disabled_nodes_.contains(n);
}
bool NodeTreeView::IsInputEnabled(NodeInput *i) const
bool NodeTreeView::IsInputEnabled(NodeInput *i, int element, int track) const
{
return !disabled_inputs_.contains(i);
return !disabled_inputs_.contains({i, element, track});
}
void NodeTreeView::SetNodes(const QVector<Node *> &nodes)
@@ -34,16 +36,32 @@ void NodeTreeView::SetNodes(const QVector<Node *> &nodes)
node_item->setData(0, kItemType, kItemTypeNode);
node_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(n));
foreach (NodeInput* i, n->inputs()) {
if (only_show_keyframable_ && !i->IsKeyframable()) {
foreach (NodeInput* input, n->inputs()) {
if (only_show_keyframable_ && !input->IsKeyframable()) {
continue;
}
QTreeWidgetItem* input_item = new QTreeWidgetItem(node_item);
input_item->setText(0, i->name());
input_item->setCheckState(0, disabled_inputs_.contains(i) ? Qt::Unchecked : Qt::Checked);
input_item->setData(0, kItemType, kItemTypeInput);
input_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(i));
int type_track_count = NodeValue::get_number_of_keyframe_tracks(input->GetDataType());
bool type_has_multiple_tracks = (type_track_count > 1);
QTreeWidgetItem* input_item = CreateItem(node_item, input, -1, type_has_multiple_tracks ? -1 : 0);
if (input->IsArray()) {
for (int i=0; i<input->ArraySize(); i++) {
QTreeWidgetItem* element_item = CreateItem(input_item, input, i, type_has_multiple_tracks ? -1 : 0);
if (type_has_multiple_tracks && show_keyframe_tracks_as_rows_) {
for (int j=0; j<type_track_count; j++) {
CreateItem(element_item, input, i, j);
}
}
}
} else if (type_has_multiple_tracks && show_keyframe_tracks_as_rows_) {
for (int j=0; j<type_track_count; j++) {
CreateItem(input_item, input, -1, j);
}
}
}
// Add at the end to prevent unnecessary signalling while we're setting these objects up
@@ -69,6 +87,42 @@ void NodeTreeView::Retranslate()
setHeaderLabel(tr("Nodes"));
}
QTreeWidgetItem* NodeTreeView::CreateItem(QTreeWidgetItem *parent, NodeInput *input, int element, int track)
{
QTreeWidgetItem* input_item = new QTreeWidgetItem(parent);
QString item_name;
if (track == -1 || NodeValue::get_number_of_keyframe_tracks(input->GetDataType()) == 1) {
item_name = input->name();
} else {
switch (track) {
case 0:
item_name = tr("X");
break;
case 1:
item_name = tr("Y");
break;
case 2:
item_name = tr("Z");
break;
case 3:
item_name = tr("W");
break;
default:
item_name = QString::number(track);
}
}
input_item->setText(0, item_name);
input_item->setCheckState(0, disabled_inputs_.contains({input, element, track}) ? Qt::Unchecked : Qt::Checked);
input_item->setData(0, kItemType, kItemTypeInput);
input_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(input));
input_item->setData(0, kItemElement, element);
input_item->setData(0, kItemTrack, track);
return input_item;
}
void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
{
Q_UNUSED(column)
@@ -91,20 +145,44 @@ void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
}
case kItemTypeInput:
{
NodeInput* i = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
NodeInput* input = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
int element = item->data(0, kItemElement).toInt();
int track = item->data(0, kItemTrack).toInt();
NodeInput::KeyframeTrackReference i = {input, element, track};
if (item->checkState(0) == Qt::Checked) {
if (disabled_inputs_.contains(i)) {
disabled_inputs_.removeOne(i);
emit InputEnableChanged(i, true);
emit InputEnableChanged(input, element, track, true);
}
} else if (!disabled_inputs_.contains(i)) {
disabled_inputs_.append(i);
emit InputEnableChanged(i, false);
emit InputEnableChanged(input, element, track, false);
}
break;
}
}
}
void NodeTreeView::SelectionChanged()
{
QList<QTreeWidgetItem*> sel = selectedItems();
NodeInput* selected_input = nullptr;
int selected_element = -1;
int selected_track = -1;
if (!sel.isEmpty()) {
QTreeWidgetItem* item = sel.first();
if (item->data(0, kItemType).toInt() == kItemTypeInput) {
selected_input = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
selected_element = item->data(0, kItemElement).toInt();
selected_track = item->data(0, kItemTrack).toInt();
}
}
emit InputSelectionChanged(selected_input, selected_element, selected_track);
}
}