implement keyframe track separation in curve view
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user