nodeview: started core node filtering work
This commit is contained in:
@@ -88,6 +88,11 @@ void NodePanel::SelectWithDependencies(const QList<Node *> &nodes)
|
||||
node_view_->SelectWithDependencies(nodes);
|
||||
}
|
||||
|
||||
void NodePanel::SelectBlocks(const QList<Block *> &nodes)
|
||||
{
|
||||
node_view_->SelectBlocks(nodes);
|
||||
}
|
||||
|
||||
void NodePanel::Retranslate()
|
||||
{
|
||||
SetTitle(tr("Node Editor"));
|
||||
|
||||
@@ -53,6 +53,8 @@ public slots:
|
||||
void Select(const QList<Node*>& nodes);
|
||||
void SelectWithDependencies(const QList<Node*>& nodes);
|
||||
|
||||
void SelectBlocks(const QList<Block*>& nodes);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Wrapper for NodeView::SelectionChanged()
|
||||
|
||||
@@ -87,7 +87,7 @@ protected:
|
||||
virtual void Retranslate() override;
|
||||
|
||||
signals:
|
||||
void SelectionChanged(const QList<Node*>& selected_blocks);
|
||||
void SelectionChanged(const QList<Block*>& selected_blocks);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ OLIVE_NAMESPACE_ENTER
|
||||
NodeView::NodeView(QWidget *parent) :
|
||||
HandMovableView(parent),
|
||||
graph_(nullptr),
|
||||
drop_edge_(nullptr)
|
||||
drop_edge_(nullptr),
|
||||
filter_mode_(kFilterShowSelectedBlocks)
|
||||
{
|
||||
setScene(&scene_);
|
||||
SetDefaultDragMode(RubberBandDrag);
|
||||
@@ -65,9 +66,9 @@ void NodeView::SetGraph(NodeGraph *graph)
|
||||
}
|
||||
|
||||
if (graph_ != nullptr) {
|
||||
disconnect(graph_, &NodeGraph::NodeAdded, &scene_, &NodeViewScene::AddNode);
|
||||
disconnect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
|
||||
disconnect(graph_, &NodeGraph::NodeRemoved, &scene_, &NodeViewScene::RemoveNode);
|
||||
disconnect(graph_, &NodeGraph::EdgeAdded, &scene_, &NodeViewScene::AddEdge);
|
||||
disconnect(graph_, &NodeGraph::EdgeAdded, this, &NodeView::AddEdge);
|
||||
disconnect(graph_, &NodeGraph::EdgeRemoved, &scene_, &NodeViewScene::RemoveEdge);
|
||||
}
|
||||
|
||||
@@ -80,16 +81,12 @@ void NodeView::SetGraph(NodeGraph *graph)
|
||||
|
||||
// If the graph is valid, add UI objects for each of its Nodes
|
||||
if (graph_ != nullptr) {
|
||||
connect(graph_, &NodeGraph::NodeAdded, &scene_, &NodeViewScene::AddNode);
|
||||
connect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
|
||||
connect(graph_, &NodeGraph::NodeRemoved, &scene_, &NodeViewScene::RemoveNode);
|
||||
connect(graph_, &NodeGraph::EdgeAdded, &scene_, &NodeViewScene::AddEdge);
|
||||
connect(graph_, &NodeGraph::EdgeAdded, this, &NodeView::AddEdge);
|
||||
connect(graph_, &NodeGraph::EdgeRemoved, &scene_, &NodeViewScene::RemoveEdge);
|
||||
|
||||
QList<Node*> graph_nodes = graph_->nodes();
|
||||
|
||||
foreach (Node* node, graph_nodes) {
|
||||
scene_.AddNode(node);
|
||||
}
|
||||
AddNodes(graph_->nodes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +182,25 @@ void NodeView::SelectWithDependencies(QList<Node *> nodes)
|
||||
Select(nodes);
|
||||
}
|
||||
|
||||
void NodeView::SelectBlocks(const QList<Block *> &blocks)
|
||||
{
|
||||
selected_blocks_ = blocks;
|
||||
|
||||
if (filter_mode_ == kFilterShowSelectedBlocks) {
|
||||
UpdateBlockFilter();
|
||||
}
|
||||
|
||||
QList<Node*> nodes;
|
||||
nodes.reserve(blocks.size());
|
||||
|
||||
foreach (Block* b, blocks) {
|
||||
nodes.append(b);
|
||||
nodes.append(b->GetDependencies());
|
||||
}
|
||||
|
||||
SelectWithDependencies(nodes);
|
||||
}
|
||||
|
||||
void NodeView::CopySelected(bool cut)
|
||||
{
|
||||
if (!graph_) {
|
||||
@@ -460,11 +476,19 @@ void NodeView::ShowContextMenu(const QPoint &pos)
|
||||
m.addSeparator();
|
||||
|
||||
Menu* filter_menu = new Menu(tr("Filter"), &m);
|
||||
m.addMenu(filter_menu);
|
||||
|
||||
filter_menu->AddActionWithData(tr("Show All"),
|
||||
kFilterShowAll,
|
||||
filter_mode_);
|
||||
|
||||
filter_menu->AddActionWithData(tr("Show Selected Blocks Only"),
|
||||
kFilterShowSelectedBlocks,
|
||||
filter_mode_);
|
||||
|
||||
connect(filter_menu, &Menu::triggered, this, &NodeView::ContextMenuFilterChanged);
|
||||
|
||||
filter_menu->addAction(tr("Show All"))->setData(NodeViewScene::kFilterShowAll);
|
||||
filter_menu->addAction(tr("Show Selected Blocks Only"))->setData(NodeViewScene::kFilterShowSelectedBlocks);
|
||||
|
||||
m.addSeparator();
|
||||
|
||||
Menu* direction_menu = new Menu(tr("Direction"), &m);
|
||||
m.addMenu(direction_menu);
|
||||
@@ -555,6 +579,28 @@ void NodeView::ContextMenuShowFiltersDialog()
|
||||
fd.exec();
|
||||
}
|
||||
|
||||
void NodeView::ContextMenuFilterChanged(QAction *action)
|
||||
{
|
||||
FilterMode filter = static_cast<FilterMode>(action->data().toInt());
|
||||
|
||||
if (filter_mode_ != filter) {
|
||||
filter_mode_ = filter;
|
||||
|
||||
if (filter == kFilterShowAll) {
|
||||
// Un-hide all blocks
|
||||
foreach (NodeViewItem* item, scene_.item_map()) {
|
||||
item->setVisible(true);
|
||||
}
|
||||
|
||||
foreach (NodeViewEdge* edge, scene_.edge_map()) {
|
||||
edge->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
ValidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::PlaceNode(NodeViewItem *n, const QPointF &pos)
|
||||
{
|
||||
QRectF destination_rect = n->rect();
|
||||
@@ -751,4 +797,101 @@ void NodeView::DisconnectSelectionChangedSignal()
|
||||
disconnect(&scene_, &QGraphicsScene::selectionChanged, this, &NodeView::SceneSelectionChangedSlot);
|
||||
}
|
||||
|
||||
void NodeView::UpdateBlockFilter()
|
||||
{
|
||||
// Hide all nodes
|
||||
foreach (NodeViewItem* item, scene_.item_map()) {
|
||||
item->setVisible(false);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
QRectF last_rect;
|
||||
|
||||
QList<Node*> all_nodes;
|
||||
|
||||
foreach (Block* b, selected_blocks_) {
|
||||
scene_.ReorganizeFrom(b);
|
||||
|
||||
QPointF node_pos = b->GetPosition();
|
||||
QRectF anchor(node_pos, node_pos);
|
||||
|
||||
all_nodes.append(b);
|
||||
|
||||
QList<Node*> deps = b->GetDependencies();
|
||||
all_nodes.append(deps);
|
||||
|
||||
// Show nodes that are block dependencies
|
||||
scene_.NodeToUIObject(b)->setVisible(true);
|
||||
|
||||
foreach (Node* d, deps) {
|
||||
QPointF dep_pos = d->GetPosition();
|
||||
|
||||
anchor.setLeft(qMin(anchor.left(), dep_pos.x()));
|
||||
anchor.setRight(qMax(anchor.right(), dep_pos.x()));
|
||||
anchor.setTop(qMin(anchor.top(), dep_pos.y()));
|
||||
anchor.setBottom(qMax(anchor.bottom(), dep_pos.y()));
|
||||
|
||||
scene_.NodeToUIObject(d)->setVisible(true);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
QPointF desired_anchor_pos = last_rect.bottomRight() + QPointF(0, 2);
|
||||
|
||||
QPointF necessary_movement = anchor.topRight() - desired_anchor_pos;
|
||||
|
||||
b->SetPosition(b->GetPosition() - necessary_movement);
|
||||
foreach (Node* d, deps) {
|
||||
d->SetPosition(d->GetPosition() - necessary_movement);
|
||||
}
|
||||
}
|
||||
|
||||
last_rect = anchor;
|
||||
}
|
||||
|
||||
// Show only edges between those dependencies
|
||||
foreach (NodeViewEdge* edge, scene_.edge_map()) {
|
||||
edge->setVisible((all_nodes.contains(edge->edge()->input()->parentNode())
|
||||
&& all_nodes.contains(edge->edge()->output()->parentNode())));
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::AddNodes(const QList<Node *> node)
|
||||
{
|
||||
foreach (Node* n, node) {
|
||||
scene_.AddNode(n);
|
||||
}
|
||||
|
||||
ValidateFilter();
|
||||
}
|
||||
|
||||
void NodeView::AddNode(Node *node)
|
||||
{
|
||||
scene_.AddNode(node);
|
||||
|
||||
ValidateFilter();
|
||||
}
|
||||
|
||||
void NodeView::AddEdge(NodeEdgePtr edge)
|
||||
{
|
||||
scene_.AddEdge(edge);
|
||||
|
||||
ValidateFilter();
|
||||
}
|
||||
|
||||
void NodeView::ValidateFilter()
|
||||
{
|
||||
// Force auto-positioning
|
||||
switch (filter_mode_) {
|
||||
case kFilterShowAll:
|
||||
// NOTE: Assumes Sequence
|
||||
scene_.ReorganizeFrom(static_cast<Sequence*>(graph_)->viewer_output());
|
||||
break;
|
||||
case kFilterShowSelectedBlocks:
|
||||
UpdateBlockFilter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -61,6 +61,8 @@ public:
|
||||
void Select(const QList<Node*>& nodes);
|
||||
void SelectWithDependencies(QList<Node *> nodes);
|
||||
|
||||
void SelectBlocks(const QList<Block*>& blocks);
|
||||
|
||||
void CopySelected(bool cut);
|
||||
void Paste();
|
||||
|
||||
@@ -98,6 +100,8 @@ private:
|
||||
void ReconnectSelectionChangedSignal();
|
||||
void DisconnectSelectionChangedSignal();
|
||||
|
||||
void UpdateBlockFilter();
|
||||
|
||||
NodeGraph* graph_;
|
||||
|
||||
struct AttachedItem {
|
||||
@@ -112,7 +116,22 @@ private:
|
||||
|
||||
NodeViewScene scene_;
|
||||
|
||||
QList<Block*> selected_blocks_;
|
||||
|
||||
enum FilterMode {
|
||||
kFilterShowAll,
|
||||
kFilterShowSelectedBlocks
|
||||
};
|
||||
|
||||
FilterMode filter_mode_;
|
||||
|
||||
private slots:
|
||||
void AddNodes(const QList<Node*> node);
|
||||
void AddNode(Node* node);
|
||||
void AddEdge(NodeEdgePtr edge);
|
||||
|
||||
void ValidateFilter();
|
||||
|
||||
/**
|
||||
* @brief Internal function triggered when any change is signalled from the QGraphicsScene
|
||||
*
|
||||
@@ -155,6 +174,11 @@ private slots:
|
||||
*/
|
||||
void ContextMenuShowFiltersDialog();
|
||||
|
||||
/**
|
||||
* @brief Receiver for the user changing the filter
|
||||
*/
|
||||
void ContextMenuFilterChanged(QAction* action);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -219,17 +219,11 @@ void NodeViewScene::AddEdge(NodeEdgePtr edge)
|
||||
|
||||
addItem(edge_ui);
|
||||
edge_map_.insert(edge.get(), edge_ui);
|
||||
|
||||
// FIXME: Not optimal, fairly brute force/shotgun approach to positioning
|
||||
ReorganizeFrom(static_cast<Sequence*>(graph_)->viewer_output());
|
||||
}
|
||||
|
||||
void NodeViewScene::RemoveEdge(NodeEdgePtr edge)
|
||||
{
|
||||
delete edge_map_.take(edge.get());
|
||||
|
||||
// FIXME: Not optimal, fairly brute force/shotgun approach to positioning
|
||||
ReorganizeFrom(static_cast<Sequence*>(graph_)->viewer_output());
|
||||
}
|
||||
|
||||
int NodeViewScene::DetermineWeight(Node *n)
|
||||
@@ -290,11 +284,6 @@ void NodeViewScene::ReorganizeFrom(Node* n)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewScene::SetFilterMode(const NodeViewScene::FilterMode &f)
|
||||
{
|
||||
filter_mode_ = f;
|
||||
}
|
||||
|
||||
bool NodeViewScene::GetEdgesAreCurved() const
|
||||
{
|
||||
return curved_edges_;
|
||||
|
||||
@@ -80,13 +80,6 @@ public:
|
||||
*/
|
||||
void ReorganizeFrom(Node* n);
|
||||
|
||||
enum FilterMode {
|
||||
kFilterShowAll,
|
||||
kFilterShowSelectedBlocks
|
||||
};
|
||||
|
||||
void SetFilterMode(const FilterMode& f);
|
||||
|
||||
bool GetEdgesAreCurved() const;
|
||||
|
||||
public slots:
|
||||
@@ -138,8 +131,6 @@ private:
|
||||
|
||||
NodeViewCommon::FlowDirection direction_;
|
||||
|
||||
FilterMode filter_mode_;
|
||||
|
||||
bool curved_edges_;
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -124,7 +124,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
connect(view, &TimelineView::DragMoved, this, &TimelineWidget::ViewDragMoved);
|
||||
connect(view, &TimelineView::DragLeft, this, &TimelineWidget::ViewDragLeft);
|
||||
connect(view, &TimelineView::DragDropped, this, &TimelineWidget::ViewDragDropped);
|
||||
connect(view, &TimelineView::SelectionChanged, this, &TimelineWidget::ViewSelectionChanged);
|
||||
ConnectViewSelectionSignal(view);
|
||||
|
||||
connect(tview->splitter(), &QSplitter::splitterMoved, this, &TimelineWidget::UpdateHorizontalSplitters);
|
||||
|
||||
@@ -156,12 +156,22 @@ TimelineWidget::~TimelineWidget()
|
||||
|
||||
void TimelineWidget::Clear()
|
||||
{
|
||||
foreach (TimelineAndTrackView* tview, views_) {
|
||||
DisconnectViewSelectionSignal(tview->view());
|
||||
}
|
||||
|
||||
QMap<Block*, TimelineViewBlockItem*>::const_iterator iterator;
|
||||
for (iterator=block_items_.begin(); iterator!=block_items_.end(); iterator++) {
|
||||
delete iterator.value();
|
||||
}
|
||||
block_items_.clear();
|
||||
|
||||
foreach (TimelineAndTrackView* tview, views_) {
|
||||
ConnectViewSelectionSignal(tview->view());
|
||||
}
|
||||
|
||||
emit SelectionChanged(QList<Block*>());
|
||||
|
||||
SetTimebase(0);
|
||||
}
|
||||
|
||||
@@ -359,15 +369,23 @@ rational TimelineWidget::GetToolTipTimebase() const
|
||||
void TimelineWidget::SelectAll()
|
||||
{
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
DisconnectViewSelectionSignal(view->view());
|
||||
view->view()->SelectAll();
|
||||
ConnectViewSelectionSignal(view->view());
|
||||
}
|
||||
|
||||
ViewSelectionChanged();
|
||||
}
|
||||
|
||||
void TimelineWidget::DeselectAll()
|
||||
{
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
DisconnectViewSelectionSignal(view->view());
|
||||
view->view()->DeselectAll();
|
||||
ConnectViewSelectionSignal(view->view());
|
||||
}
|
||||
|
||||
emit SelectionChanged(QList<Block*>());
|
||||
}
|
||||
|
||||
void TimelineWidget::RippleToIn()
|
||||
@@ -884,6 +902,16 @@ TrackOutput *TimelineWidget::GetTrackFromReference(const TrackReference &ref)
|
||||
return GetConnectedNode()->track_list(ref.type())->GetTrackAt(ref.index());
|
||||
}
|
||||
|
||||
void TimelineWidget::ConnectViewSelectionSignal(TimelineView *view)
|
||||
{
|
||||
connect(view, &TimelineView::SelectionChanged, this, &TimelineWidget::ViewSelectionChanged);
|
||||
}
|
||||
|
||||
void TimelineWidget::DisconnectViewSelectionSignal(TimelineView *view)
|
||||
{
|
||||
disconnect(view, &TimelineView::SelectionChanged, this, &TimelineWidget::ViewSelectionChanged);
|
||||
}
|
||||
|
||||
int TimelineWidget::GetTrackY(const TrackReference &ref)
|
||||
{
|
||||
return views_.at(ref.type())->view()->GetTrackY(ref.index());
|
||||
@@ -1058,7 +1086,7 @@ void TimelineWidget::ViewSelectionChanged()
|
||||
}
|
||||
|
||||
QList<TimelineViewBlockItem*> selected_items = GetSelectedBlocks();
|
||||
QList<Node*> selected_blocks;
|
||||
QList<Block*> selected_blocks;
|
||||
|
||||
foreach (TimelineViewBlockItem* item, selected_items) {
|
||||
selected_blocks.append(item->block());
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
QList<TimelineViewBlockItem*> GetSelectedBlocks();
|
||||
|
||||
signals:
|
||||
void SelectionChanged(const QList<Node*>& selected_blocks);
|
||||
void SelectionChanged(const QList<Block*>& selected_blocks);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
@@ -453,6 +453,10 @@ private:
|
||||
|
||||
TrackOutput* GetTrackFromReference(const TrackReference& ref);
|
||||
|
||||
void ConnectViewSelectionSignal(TimelineView* view);
|
||||
|
||||
void DisconnectViewSelectionSignal(TimelineView* view);
|
||||
|
||||
QList<TimelineAndTrackView*> views_;
|
||||
|
||||
TimeSlider* timecode_label_;
|
||||
|
||||
@@ -490,7 +490,7 @@ TimelinePanel* MainWindow::AppendTimelinePanel()
|
||||
connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::TimelineCloseRequested);
|
||||
connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp);
|
||||
connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp);
|
||||
connect(panel, &TimelinePanel::SelectionChanged, node_panel_, &NodePanel::SelectWithDependencies);
|
||||
connect(panel, &TimelinePanel::SelectionChanged, node_panel_, &NodePanel::SelectBlocks);
|
||||
connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
|
||||
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
|
||||
connect(sequence_viewer_panel_->video_renderer(), &VideoRenderBackend::CachedTimeReady, panel->ruler(), &TimeRuler::CacheTimeReady);
|
||||
|
||||
Reference in New Issue
Block a user