work towards timeline/nodeview interactivity

This commit is contained in:
itsmattkc
2021-05-17 11:14:56 +10:00
parent 8e9859b2b3
commit f2d64728f9
15 changed files with 204 additions and 132 deletions
+30 -6
View File
@@ -126,6 +126,17 @@ void NodeView::SetGraph(NodeGraph *graph, const QVector<void*> &nodes)
item->SetNodePosition(it.value());
}
}
for (auto it=scene_.item_map().cbegin(); it!=scene_.item_map().cend(); it++) {
Node *node = it.key();
for (auto jt=node->input_connections().cbegin(); jt!=node->input_connections().cend(); jt++) {
const NodeOutput &output = jt->second;
if (scene_.item_map().contains(output.node())) {
// Create edge since both input and output exist
scene_.AddEdge(output, jt->first);
}
}
}
}
}
@@ -913,23 +924,26 @@ void NodeView::AddNode(Node *node)
void NodeView::RemoveNode(Node *node)
{
if (filter_mode_ == kFilterShowAll) {
scene_.RemoveNode(node);
}
scene_.RemoveNode(node);
}
void NodeView::AddEdge(const NodeOutput &output, const NodeInput &input)
{
if (filter_mode_ == kFilterShowAll) {
scene_.AddEdge(output, input);
} else if (filter_mode_ == kFilterShowSelective) {
Node *output_node = output.node();
Node *input_node = input.node();
if (scene_.item_map().contains(output_node) && scene_.item_map().contains(input_node)) {
scene_.AddEdge(output, input);
}
}
}
void NodeView::RemoveEdge(const NodeOutput &output, const NodeInput &input)
{
if (filter_mode_ == kFilterShowAll) {
scene_.RemoveEdge(output, input);
}
scene_.RemoveEdge(output, input);
}
void NodeView::AddNodePosition(Node *node, void *relative, const QPointF &pos)
@@ -940,6 +954,16 @@ void NodeView::AddNodePosition(Node *node, void *relative, const QPointF &pos)
if (!item) {
item = scene_.AddNode(node);
// Add input edges
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
AddEdge(it->second, it->first);
}
// Add output edges
for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) {
AddEdge(it->first, it->second);
}
}
item->SetNodePosition(pos);
+76 -63
View File
@@ -80,6 +80,82 @@ void NodeViewEdge::SetHighlighted(bool e)
void NodeViewEdge::SetPoints(const QPointF &start, const QPointF &end, bool input_is_expanded)
{
cached_start_ = start;
cached_end_ = end;
cached_input_is_expanded_ = input_is_expanded;
UpdateCurve();
}
void NodeViewEdge::SetFlowDirection(NodeViewCommon::FlowDirection dir)
{
flow_dir_ = dir;
if (from_item_ && to_item_) {
Adjust();
}
}
void NodeViewEdge::SetCurved(bool e)
{
curved_ = e;
UpdateCurve();
}
void NodeViewEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
QPalette::ColorGroup group;
QPalette::ColorRole role;
if (connected_) {
group = QPalette::Active;
} else {
group = QPalette::Disabled;
}
if (highlighted_ != bool(option->state & QStyle::State_Selected)) {
role = QPalette::Highlight;
} else {
role = QPalette::Text;
}
// Draw main path
QColor edge_color = qApp->palette().color(group, role);
painter->setPen(QPen(edge_color, edge_width_));
painter->setBrush(Qt::NoBrush);
painter->drawPath(path());
// Draw arrow
painter->setPen(Qt::NoPen);
painter->setBrush(edge_color);
painter->drawPolygon(arrow_);
}
void NodeViewEdge::Init()
{
connected_ = false;
highlighted_ = false;
flow_dir_ = NodeViewCommon::kLeftToRight;
curved_ = true;
setFlag(QGraphicsItem::ItemIsSelectable);
// Ensures this UI object is drawn behind other objects
setZValue(-1);
// Use font metrics to set edge width for basic high DPI support
edge_width_ = QFontMetrics(QFont()).height() / 12;
arrow_size_ = QFontMetrics(QFont()).height() / 2;
}
void NodeViewEdge::UpdateCurve()
{
const QPointF &start = cached_start_;
const QPointF &end = cached_end_;
const bool input_is_expanded = cached_input_is_expanded_;
QPainterPath path;
path.moveTo(start);
@@ -156,67 +232,4 @@ void NodeViewEdge::SetPoints(const QPointF &start, const QPointF &end, bool inpu
arrow_bounding_rect_.adjust(-arrow_size_, -arrow_size_, arrow_size_, arrow_size_);
}
void NodeViewEdge::SetFlowDirection(NodeViewCommon::FlowDirection dir)
{
flow_dir_ = dir;
if (from_item_ && to_item_) {
Adjust();
}
}
void NodeViewEdge::SetCurved(bool e)
{
curved_ = e;
update();
}
void NodeViewEdge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
QPalette::ColorGroup group;
QPalette::ColorRole role;
if (connected_) {
group = QPalette::Active;
} else {
group = QPalette::Disabled;
}
if (highlighted_ != bool(option->state & QStyle::State_Selected)) {
role = QPalette::Highlight;
} else {
role = QPalette::Text;
}
// Draw main path
QColor edge_color = qApp->palette().color(group, role);
painter->setPen(QPen(edge_color, edge_width_));
painter->setBrush(Qt::NoBrush);
painter->drawPath(path());
// Draw arrow
painter->setPen(Qt::NoPen);
painter->setBrush(edge_color);
painter->drawPolygon(arrow_);
}
void NodeViewEdge::Init()
{
connected_ = false;
highlighted_ = false;
flow_dir_ = NodeViewCommon::kLeftToRight;
curved_ = true;
setFlag(QGraphicsItem::ItemIsSelectable);
// Ensures this UI object is drawn behind other objects
setZValue(-1);
// Use font metrics to set edge width for basic high DPI support
edge_width_ = QFontMetrics(QFont()).height() / 12;
arrow_size_ = QFontMetrics(QFont()).height() / 2;
}
}
+6
View File
@@ -122,6 +122,8 @@ protected:
private:
void Init();
void UpdateCurve();
NodeOutput output_;
NodeInput input_;
@@ -148,6 +150,10 @@ private:
QRectF arrow_bounding_rect_;
QPointF cached_start_;
QPointF cached_end_;
bool cached_input_is_expanded_;
};
}
+29 -18
View File
@@ -97,24 +97,9 @@ QPointF NodeViewItem::GetNodePosition() const
void NodeViewItem::SetNodePosition(const QPointF &pos)
{
switch (flow_dir_) {
case NodeViewCommon::kLeftToRight:
setPos(pos.x() * DefaultItemHorizontalPadding(),
pos.y() * DefaultItemVerticalPadding());
break;
case NodeViewCommon::kRightToLeft:
setPos(-pos.x() * DefaultItemHorizontalPadding(),
pos.y() * DefaultItemVerticalPadding());
break;
case NodeViewCommon::kTopToBottom:
setPos(pos.y() * DefaultItemHorizontalPadding(),
pos.x() * DefaultItemVerticalPadding());
break;
case NodeViewCommon::kBottomToTop:
setPos(pos.y() * DefaultItemHorizontalPadding(),
-pos.x() * DefaultItemVerticalPadding());
break;
}
cached_node_pos_ = pos;
UpdateNodePosition();
}
int NodeViewItem::DefaultTextPadding()
@@ -466,6 +451,8 @@ QPointF NodeViewItem::GetOutputPoint(const QString& output) const
void NodeViewItem::SetFlowDirection(NodeViewCommon::FlowDirection dir)
{
flow_dir_ = dir;
UpdateNodePosition();
}
QPointF NodeViewItem::GetInputPointInternal(int index, const QPointF& source_pos) const
@@ -490,4 +477,28 @@ QPointF NodeViewItem::GetInputPointInternal(int index, const QPointF& source_pos
}
}
void NodeViewItem::UpdateNodePosition()
{
const QPointF &pos = cached_node_pos_;
switch (flow_dir_) {
case NodeViewCommon::kLeftToRight:
setPos(pos.x() * DefaultItemHorizontalPadding(),
pos.y() * DefaultItemVerticalPadding());
break;
case NodeViewCommon::kRightToLeft:
setPos(-pos.x() * DefaultItemHorizontalPadding(),
pos.y() * DefaultItemVerticalPadding());
break;
case NodeViewCommon::kTopToBottom:
setPos(pos.y() * DefaultItemHorizontalPadding(),
pos.x() * DefaultItemVerticalPadding());
break;
case NodeViewCommon::kBottomToTop:
setPos(pos.y() * DefaultItemHorizontalPadding(),
-pos.x() * DefaultItemVerticalPadding());
break;
}
}
}
+7
View File
@@ -136,6 +136,11 @@ private:
*/
QPointF GetInputPointInternal(int index, const QPointF &source_pos) const;
/**
* @brief Internal update function when logical position changes
*/
void UpdateNodePosition();
/**
* @brief Reference to attached Node
*/
@@ -167,6 +172,8 @@ private:
QVector<NodeViewEdge*> edges_;
QPointF cached_node_pos_;
};
}
+6 -4
View File
@@ -179,10 +179,12 @@ void NodeViewScene::AddEdge(const NodeOutput &output, const NodeInput &input)
void NodeViewScene::RemoveEdge(const NodeOutput &output, const NodeInput &input)
{
NodeViewEdge* edge = EdgeToUIObject(output, input);
edge->from_item()->RemoveEdge(edge);
edge->to_item()->RemoveEdge(edge);
edges_.removeOne(edge);
delete edge;
if (edge) {
edge->from_item()->RemoveEdge(edge);
edge->to_item()->RemoveEdge(edge);
edges_.removeOne(edge);
delete edge;
}
}
int NodeViewScene::DetermineWeight(Node *n)
+9 -4
View File
@@ -871,7 +871,7 @@ void TimelineWidget::RemoveBlock(Block *block)
selected_blocks_.removeAt(select_index);
RemoveSelection(block);
emit BlocksDeselected({block});
SignalBlockSelectionChange();
}
}
@@ -1087,6 +1087,11 @@ void TimelineWidget::SetScrollZoomsByDefaultOnAllViews(bool e)
}
}
void TimelineWidget::SignalBlockSelectionChange()
{
emit BlockSelectionChanged(selected_blocks_);
}
void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost)
{
ghost_items_.append(ghost);
@@ -1168,7 +1173,7 @@ void TimelineWidget::SignalSelectedBlocks(QVector<Block *> input, bool filter)
selected_blocks_.append(input);
emit BlocksSelected(input);
emit SignalBlockSelectionChange();
}
void TimelineWidget::SignalDeselectedBlocks(const QVector<Block *> &deselected_blocks)
@@ -1181,14 +1186,14 @@ void TimelineWidget::SignalDeselectedBlocks(const QVector<Block *> &deselected_b
selected_blocks_.removeOne(b);
}
emit BlocksDeselected(deselected_blocks);
emit SignalBlockSelectionChange();
}
void TimelineWidget::SignalDeselectedAllBlocks()
{
if (!selected_blocks_.isEmpty()) {
emit BlocksDeselected(selected_blocks_);
selected_blocks_.clear();
SignalBlockSelectionChange();
}
}
+3 -3
View File
@@ -234,9 +234,7 @@ public:
};
signals:
void BlocksSelected(const QVector<Block*>& selected_blocks);
void BlocksDeselected(const QVector<Block*>& deselected_blocks);
void BlockSelectionChanged(const QVector<Block*>& selected_blocks);
protected:
virtual void resizeEvent(QResizeEvent *event) override;
@@ -355,6 +353,8 @@ private slots:
void SetScrollZoomsByDefaultOnAllViews(bool e);
void SignalBlockSelectionChange();
};
}
+5 -1
View File
@@ -387,8 +387,12 @@ void ImportTool::DropGhosts(bool insert)
clip->set_length_and_media_out(ghost->GetLength());
clip->SetLabel(footage_stream.footage->GetLabel());
command->add_child(new NodeAddCommand(dst_graph, clip));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(clip, footage_stream.footage, clip, QPointF(2, 0)));
command->add_child(new NodeSetPositionToOffsetOfAnotherNodeCommand(clip, footage_stream.footage, nullptr, QPointF(2, 0)));
// Position clip in its own context
command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0), false));
// Position footage in its context
command->add_child(new NodeSetPositionCommand(footage_stream.footage, clip, QPointF(-2, 0), false));
switch (Track::Reference::TypeFromString(footage_stream.output)) {