contexts in param view
This commit is contained in:
@@ -66,9 +66,7 @@ NodeGroupDialog::NodeGroupDialog(NodeGroup *group, QWidget *parent) :
|
||||
param_view->SetInputChecked(it.value(), true);
|
||||
}
|
||||
|
||||
connect(node_view, &NodeView::NodesSelected, param_view, &NodeParamView::SelectNodes);
|
||||
connect(node_view, &NodeView::NodesDeselected, param_view, &NodeParamView::DeselectNodes);
|
||||
node_view->SelectAll();
|
||||
param_view->SetContexts({group});
|
||||
|
||||
row++;
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ ViewerOutput::ViewerOutput(bool create_buffer_inputs, bool create_default_stream
|
||||
video_cache_enabled_(true),
|
||||
audio_cache_enabled_(true)
|
||||
{
|
||||
AddInput(kVideoParamsInput, NodeValue::kVideoParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable | kInputFlagArray));
|
||||
AddInput(kVideoParamsInput, NodeValue::kVideoParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable | kInputFlagArray | kInputFlagHidden));
|
||||
SetInputProperty(kVideoParamsInput, QStringLiteral("mask"), QVariant::fromValue(kVideoParamEditMask));
|
||||
|
||||
AddInput(kAudioParamsInput, NodeValue::kAudioParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable | kInputFlagArray));
|
||||
AddInput(kAudioParamsInput, NodeValue::kAudioParams, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable | kInputFlagArray | kInputFlagHidden));
|
||||
|
||||
if (create_buffer_inputs) {
|
||||
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
|
||||
|
||||
@@ -38,16 +38,12 @@ ParamPanel::ParamPanel(QWidget* parent) :
|
||||
|
||||
void ParamPanel::SelectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->SelectNodes(nodes);
|
||||
|
||||
Retranslate();
|
||||
//static_cast<NodeParamView*>(GetTimeBasedWidget())->SelectNodes(nodes);
|
||||
}
|
||||
|
||||
void ParamPanel::DeselectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->DeselectNodes(nodes);
|
||||
|
||||
Retranslate();
|
||||
//static_cast<NodeParamView*>(GetTimeBasedWidget())->DeselectNodes(nodes);
|
||||
}
|
||||
|
||||
void ParamPanel::DeleteSelected()
|
||||
@@ -65,19 +61,14 @@ void ParamPanel::DeselectAll()
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->DeselectAll();
|
||||
}
|
||||
|
||||
void ParamPanel::SetContexts(const QVector<Node *> &contexts)
|
||||
{
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->SetContexts(contexts);
|
||||
}
|
||||
|
||||
void ParamPanel::Retranslate()
|
||||
{
|
||||
SetTitle(tr("Parameter Editor"));
|
||||
|
||||
NodeParamView* view = static_cast<NodeParamView*>(GetTimeBasedWidget());
|
||||
|
||||
if (view->GetItemMap().isEmpty()) {
|
||||
SetSubtitle(tr("(none)"));
|
||||
} else if (view->GetItemMap().size() == 1) {
|
||||
SetSubtitle(view->GetItemMap().firstKey()->Name());
|
||||
} else {
|
||||
SetSubtitle(tr("(multiple)"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ public slots:
|
||||
|
||||
virtual void DeselectAll() override;
|
||||
|
||||
void SetContexts(const QVector<Node*> &contexts);
|
||||
|
||||
signals:
|
||||
void RequestSelectNode(const QVector<Node*>& target);
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ QIcon icon::Clock;
|
||||
QIcon icon::Diamond;
|
||||
QIcon icon::Plus;
|
||||
QIcon icon::Minus;
|
||||
QIcon icon::AddEffect;
|
||||
|
||||
void icon::LoadAll(const QString& theme)
|
||||
{
|
||||
@@ -129,6 +130,7 @@ void icon::LoadAll(const QString& theme)
|
||||
Diamond = Create(theme, "diamond");
|
||||
Plus = Create(theme, "plus");
|
||||
Minus = Create(theme, "minus");
|
||||
AddEffect = Create(theme, "add-effect");
|
||||
}
|
||||
|
||||
QIcon icon::Create(const QString& theme, const QString &name)
|
||||
|
||||
@@ -86,6 +86,7 @@ extern QIcon Clock;
|
||||
extern QIcon Diamond;
|
||||
extern QIcon Plus;
|
||||
extern QIcon Minus;
|
||||
extern QIcon AddEffect;
|
||||
|
||||
/**
|
||||
* @brief Create an icon object loaded from file
|
||||
|
||||
@@ -16,23 +16,29 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/nodeparamview/nodeparamview.h
|
||||
widget/nodeparamview/nodeparamview.cpp
|
||||
widget/nodeparamview/nodeparamviewarraywidget.h
|
||||
widget/nodeparamview/nodeparamview.h
|
||||
widget/nodeparamview/nodeparamviewarraywidget.cpp
|
||||
widget/nodeparamview/nodeparamviewconnectedlabel.h
|
||||
widget/nodeparamview/nodeparamviewarraywidget.h
|
||||
widget/nodeparamview/nodeparamviewconnectedlabel.cpp
|
||||
widget/nodeparamview/nodeparamviewdockarea.h
|
||||
widget/nodeparamview/nodeparamviewconnectedlabel.h
|
||||
widget/nodeparamview/nodeparamviewcontext.cpp
|
||||
widget/nodeparamview/nodeparamviewcontext.h
|
||||
widget/nodeparamview/nodeparamviewdockarea.cpp
|
||||
widget/nodeparamview/nodeparamviewitem.h
|
||||
widget/nodeparamview/nodeparamviewdockarea.h
|
||||
widget/nodeparamview/nodeparamviewitem.cpp
|
||||
widget/nodeparamview/nodeparamviewkeyframecontrol.h
|
||||
widget/nodeparamview/nodeparamviewitem.h
|
||||
widget/nodeparamview/nodeparamviewitembase.cpp
|
||||
widget/nodeparamview/nodeparamviewitembase.h
|
||||
widget/nodeparamview/nodeparamviewitemtitlebar.cpp
|
||||
widget/nodeparamview/nodeparamviewitemtitlebar.h
|
||||
widget/nodeparamview/nodeparamviewkeyframecontrol.cpp
|
||||
widget/nodeparamview/nodeparamviewtextedit.h
|
||||
widget/nodeparamview/nodeparamviewkeyframecontrol.h
|
||||
widget/nodeparamview/nodeparamviewtextedit.cpp
|
||||
widget/nodeparamview/nodeparamviewundo.h
|
||||
widget/nodeparamview/nodeparamviewtextedit.h
|
||||
widget/nodeparamview/nodeparamviewundo.cpp
|
||||
widget/nodeparamview/nodeparamviewwidgetbridge.h
|
||||
widget/nodeparamview/nodeparamviewundo.h
|
||||
widget/nodeparamview/nodeparamviewwidgetbridge.cpp
|
||||
widget/nodeparamview/nodeparamviewwidgetbridge.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QScrollBar>
|
||||
#include <QSplitter>
|
||||
|
||||
#include "common/functiontimer.h"
|
||||
#include "common/timecodefunctions.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
|
||||
@@ -61,12 +62,6 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
|
||||
|
||||
param_widget_area_ = new NodeParamViewDockArea();
|
||||
|
||||
// Disable dock widgets from tabbing and disable glitchy animations
|
||||
param_widget_area_->setDockOptions(static_cast<QMainWindow::DockOption>(0));
|
||||
|
||||
// HACK: Hide the main window separators (unfortunately the cursors still appear)
|
||||
param_widget_area_->setStyleSheet(QStringLiteral("QMainWindow::separator {background: rgba(0, 0, 0, 0)}"));
|
||||
|
||||
QVBoxLayout* param_widget_container_layout = new QVBoxLayout(param_widget_container_);
|
||||
QMargins param_widget_margin = param_widget_container_layout->contentsMargins();
|
||||
param_widget_margin.setTop(ruler()->height());
|
||||
@@ -76,9 +71,29 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
|
||||
|
||||
param_widget_container_layout->addStretch(INT_MAX);
|
||||
|
||||
// Create contexts for three different types
|
||||
context_items_.resize(Track::kCount + 1);
|
||||
for (int i=0; i<context_items_.size(); i++) {
|
||||
NodeParamViewContext *c = new NodeParamViewContext;
|
||||
c->setVisible(false);
|
||||
static_cast<NodeParamViewItemTitleBar*>(c->titleBarWidget())->SetAddEffectButtonVisible(i == Track::kVideo || i == Track::kAudio);
|
||||
static_cast<NodeParamViewItemTitleBar*>(c->titleBarWidget())->SetText(Footage::GetStreamTypeName(static_cast<Track::Type>(i)));
|
||||
context_items_[i] = c;
|
||||
param_widget_area_->AddItem(c);
|
||||
}
|
||||
|
||||
// Disable collapsing param view (but collapsing keyframe view is permitted)
|
||||
splitter->setCollapsible(0, false);
|
||||
|
||||
// Create global vertical scrollbar on the right
|
||||
vertical_scrollbar_ = new QScrollBar();
|
||||
vertical_scrollbar_->setMaximum(0);
|
||||
layout->addWidget(vertical_scrollbar_);
|
||||
|
||||
// Connect scrollbars together
|
||||
connect(param_scroll_area_->verticalScrollBar(), &QScrollBar::valueChanged, vertical_scrollbar_, &QScrollBar::setValue);
|
||||
connect(vertical_scrollbar_, &QScrollBar::valueChanged, param_scroll_area_->verticalScrollBar(), &QScrollBar::setValue);
|
||||
|
||||
if (create_keyframe_view) {
|
||||
// Set up keyframe view
|
||||
QWidget* keyframe_area = new QWidget();
|
||||
@@ -108,20 +123,7 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
|
||||
|
||||
// Set both widgets to 50/50
|
||||
splitter->setSizes({INT_MAX, INT_MAX});
|
||||
} else {
|
||||
keyframe_view_ = nullptr;
|
||||
}
|
||||
|
||||
// Create global vertical scrollbar on the right
|
||||
vertical_scrollbar_ = new QScrollBar();
|
||||
vertical_scrollbar_->setMaximum(0);
|
||||
layout->addWidget(vertical_scrollbar_);
|
||||
|
||||
// Connect scrollbars together
|
||||
connect(param_scroll_area_->verticalScrollBar(), &QScrollBar::valueChanged, vertical_scrollbar_, &QScrollBar::setValue);
|
||||
connect(vertical_scrollbar_, &QScrollBar::valueChanged, param_scroll_area_->verticalScrollBar(), &QScrollBar::setValue);
|
||||
|
||||
if (keyframe_view_) {
|
||||
connect(keyframe_view_->verticalScrollBar(), &QScrollBar::valueChanged, vertical_scrollbar_, &QScrollBar::setValue);
|
||||
connect(keyframe_view_->verticalScrollBar(), &QScrollBar::valueChanged, param_scroll_area_->verticalScrollBar(), &QScrollBar::setValue);
|
||||
connect(param_scroll_area_->verticalScrollBar(), &QScrollBar::valueChanged, keyframe_view_->verticalScrollBar(), &QScrollBar::setValue);
|
||||
@@ -132,6 +134,8 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
|
||||
keyframe_view_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
|
||||
connect(keyframe_view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
} else {
|
||||
keyframe_view_ = nullptr;
|
||||
}
|
||||
|
||||
// Set a default scale - FIXME: Hardcoded
|
||||
@@ -144,8 +148,14 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) :
|
||||
&NodeParamView::FocusChanged);
|
||||
}
|
||||
|
||||
void NodeParamView::SelectNodes(const QVector<Node *> &nodes)
|
||||
NodeParamView::~NodeParamView()
|
||||
{
|
||||
qDeleteAll(context_items_);
|
||||
}
|
||||
|
||||
/*void NodeParamView::SelectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
return;
|
||||
int original_node_count = items_.size();
|
||||
|
||||
foreach (Node* n, nodes) {
|
||||
@@ -158,7 +168,7 @@ void NodeParamView::SelectNodes(const QVector<Node *> &nodes)
|
||||
active_nodes_.append(n);
|
||||
|
||||
// Create node UI
|
||||
AddNode(n);
|
||||
AddNode(n, param_widget_area_);
|
||||
}
|
||||
|
||||
if (items_.size() > original_node_count ) {
|
||||
@@ -173,6 +183,7 @@ void NodeParamView::SelectNodes(const QVector<Node *> &nodes)
|
||||
|
||||
void NodeParamView::DeselectNodes(const QVector<Node *> &nodes)
|
||||
{
|
||||
return;
|
||||
// Remove item from map and delete the widget
|
||||
int original_node_count = items_.size();
|
||||
|
||||
@@ -199,13 +210,59 @@ void NodeParamView::DeselectNodes(const QVector<Node *> &nodes)
|
||||
|
||||
SignalNodeOrder();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void NodeParamView::SetInputChecked(const NodeInput &input, bool e)
|
||||
{
|
||||
input_checked_.insert(input, e);
|
||||
if (NodeParamViewItem *item = items_.value(input.node())) {
|
||||
item->SetInputChecked(input, e);
|
||||
foreach (NodeParamViewContext *ctx, context_items_) {
|
||||
ctx->SetInputChecked(input, e);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamView::SetContexts(const QVector<Node *> &contexts)
|
||||
{
|
||||
TIME_THIS_FUNCTION;
|
||||
|
||||
foreach (NodeParamViewContext *ctx, context_items_) {
|
||||
ctx->Clear();
|
||||
ctx->setVisible(false);
|
||||
}
|
||||
|
||||
if (focused_node_) {
|
||||
focused_node_ = nullptr;
|
||||
emit FocusedNodeChanged(nullptr);
|
||||
}
|
||||
|
||||
foreach (Node *ctx, contexts) {
|
||||
Track::Type ctx_type = Track::kCount;
|
||||
|
||||
if (ClipBlock *clip = dynamic_cast<ClipBlock*>(ctx)) {
|
||||
if (clip->track()) {
|
||||
if (clip->track()->type() != Track::kNone) {
|
||||
ctx_type = clip->track()->type();
|
||||
}
|
||||
}
|
||||
} else if (Track *track = dynamic_cast<Track*>(ctx)) {
|
||||
if (track->type() != Track::kNone) {
|
||||
ctx_type = track->type();
|
||||
}
|
||||
}
|
||||
|
||||
NodeParamViewContext *item = context_items_.at(ctx_type);
|
||||
|
||||
item->AddContext(ctx);
|
||||
item->setVisible(true);
|
||||
|
||||
for (auto it=ctx->GetContextPositions().cbegin(); it!=ctx->GetContextPositions().cend(); it++) {
|
||||
if (!dynamic_cast<Footage*>(it.key()) && !dynamic_cast<ClipBlock*>(it.key())) {
|
||||
AddNode(it.key(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (NodeParamViewContext *ctx, context_items_) {
|
||||
SortItemsInContext(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,8 +292,8 @@ void NodeParamView::TimebaseChangedEvent(const rational &timebase)
|
||||
keyframe_view_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
item->SetTimebase(timebase);
|
||||
foreach (NodeParamViewContext* ctx, context_items_) {
|
||||
ctx->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
UpdateItemTime(GetTime());
|
||||
@@ -260,7 +317,7 @@ void NodeParamView::ConnectedNodeChangeEvent(ViewerOutput *n)
|
||||
keyframe_view_->SetTimeTarget(n);
|
||||
}
|
||||
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
foreach (NodeParamViewContext* item, context_items_) {
|
||||
item->SetTimeTarget(n);
|
||||
}
|
||||
|
||||
@@ -281,7 +338,7 @@ void NodeParamView::DeleteSelected()
|
||||
|
||||
void NodeParamView::UpdateItemTime(const rational &time)
|
||||
{
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
foreach (NodeParamViewContext* item, context_items_) {
|
||||
item->SetTime(time);
|
||||
}
|
||||
}
|
||||
@@ -293,6 +350,7 @@ void NodeParamView::QueueKeyframePositionUpdate()
|
||||
|
||||
void NodeParamView::SignalNodeOrder()
|
||||
{
|
||||
/*
|
||||
// Sort by item Y (apparently there's no way in Qt to get the order of dock widgets)
|
||||
QVector<Node*> nodes;
|
||||
QVector<int> item_ys;
|
||||
@@ -318,15 +376,12 @@ void NodeParamView::SignalNodeOrder()
|
||||
}
|
||||
|
||||
emit NodeOrderChanged(nodes);
|
||||
*/
|
||||
}
|
||||
|
||||
void NodeParamView::AddNode(Node *n)
|
||||
void NodeParamView::AddNode(Node *n, NodeParamViewContext *context)
|
||||
{
|
||||
NodeParamViewItem* item = new NodeParamViewItem(n, create_checkboxes_, param_widget_area_);
|
||||
|
||||
item->setAllowedAreas(Qt::LeftDockWidgetArea);
|
||||
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
|
||||
item->SetExpanded(node_expanded_state_.value(n, true));
|
||||
NodeParamViewItem* item = new NodeParamViewItem(n, create_checkboxes_, context);
|
||||
|
||||
if (keyframe_view_) {
|
||||
connect(n, &Node::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
|
||||
@@ -357,14 +412,13 @@ void NodeParamView::AddNode(Node *n)
|
||||
// Set the timebase
|
||||
item->SetTimebase(timebase());
|
||||
|
||||
items_.insert(n, item);
|
||||
param_widget_area_->addDockWidget(Qt::LeftDockWidgetArea, item);
|
||||
context->AddNode(item);
|
||||
|
||||
if (!focused_node_ && n->HasGizmos()) {
|
||||
// We'll focus this node now
|
||||
item->SetHighlighted(true);
|
||||
focused_node_ = n;
|
||||
emit FocusedNodeChanged(focused_node_);
|
||||
focused_node_ = item;
|
||||
emit FocusedNodeChanged(n);
|
||||
}
|
||||
|
||||
if (keyframe_view_) {
|
||||
@@ -372,9 +426,21 @@ void NodeParamView::AddNode(Node *n)
|
||||
}
|
||||
}
|
||||
|
||||
/*void NodeParamView::AddNode(Node *node, Node *context, NodeParamViewContext *ctx_item)
|
||||
{
|
||||
int dist = GetDistanceBetweenNodes(context, node);
|
||||
|
||||
if (dist == -1) {
|
||||
dist = 0;
|
||||
}
|
||||
|
||||
ctx_item->GetDockArea()->insert
|
||||
}*/
|
||||
|
||||
void NodeParamView::RemoveNode(Node *n)
|
||||
{
|
||||
if (keyframe_view_) {
|
||||
qDebug() << "STUB!";
|
||||
/*if (keyframe_view_) {
|
||||
keyframe_view_->RemoveKeyframesOfNode(n);
|
||||
|
||||
disconnect(n, &Node::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
|
||||
@@ -395,16 +461,64 @@ void NodeParamView::RemoveNode(Node *n)
|
||||
}
|
||||
|
||||
emit FocusedNodeChanged(focused_node_);
|
||||
}*/
|
||||
}
|
||||
|
||||
int GetDistanceBetweenNodes(Node *start, Node *end)
|
||||
{
|
||||
if (start == end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (auto it=start->input_connections().cbegin(); it!=start->input_connections().cend(); it++) {
|
||||
int this_node_dist = GetDistanceBetweenNodes(it->second, end);
|
||||
if (this_node_dist != -1) {
|
||||
return 1 + this_node_dist;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void NodeParamView::SortItemsInContext(NodeParamViewContext *context_item)
|
||||
{
|
||||
QVector<QPair<NodeParamViewItem*, int> > distances;
|
||||
|
||||
for (auto it=context_item->GetItems().cbegin(); it!=context_item->GetItems().cend(); it++) {
|
||||
int distance = 0;
|
||||
foreach (Node *ctx, context_item->GetContexts()) {
|
||||
distance = qMax(distance, GetDistanceBetweenNodes(ctx, it.key()));
|
||||
}
|
||||
|
||||
bool inserted = false;
|
||||
QPair<NodeParamViewItem*, int> dist(it.value(), distance);
|
||||
|
||||
for (int i=0; i<distances.size(); i++) {
|
||||
if (distances.at(i).second < distance) {
|
||||
distances.insert(i, dist);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inserted) {
|
||||
distances.append(dist);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (auto info, distances) {
|
||||
context_item->GetDockArea()->AddItem(info.first);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamView::UpdateGlobalScrollBar()
|
||||
{
|
||||
int height_offscreen = param_widget_container_->height() - ruler()->height() + scrollbar()->height();
|
||||
int height_offscreen = param_widget_container_->height() + scrollbar()->height();
|
||||
|
||||
if (keyframe_view_) {
|
||||
keyframe_view_->SetMaxScroll(height_offscreen);
|
||||
}
|
||||
|
||||
vertical_scrollbar_->setRange(0, height_offscreen - param_scroll_area_->height());
|
||||
}
|
||||
|
||||
@@ -430,28 +544,36 @@ void NodeParamView::FocusChanged(QWidget* old, QWidget* now)
|
||||
Q_UNUSED(old)
|
||||
|
||||
QObject* parent = now;
|
||||
NodeParamViewItem* item;
|
||||
|
||||
while (parent) {
|
||||
item = dynamic_cast<NodeParamViewItem*>(parent);
|
||||
if (NodeParamViewItem* item = dynamic_cast<NodeParamViewItem*>(parent)) {
|
||||
if (item != focused_node_) {
|
||||
// Found a NodeParamViewItem that isn't already focused, see if it belongs to us
|
||||
bool ours = false;
|
||||
|
||||
if (item) {
|
||||
if (item->parent() == param_widget_area_) {
|
||||
// Found it!
|
||||
if (item->GetNode() != focused_node_) {
|
||||
do {
|
||||
parent = parent->parent();
|
||||
|
||||
if (parent == this) {
|
||||
ours = true;
|
||||
break;
|
||||
}
|
||||
} while (parent);
|
||||
|
||||
if (ours) {
|
||||
// This item is ours,
|
||||
if (focused_node_) {
|
||||
// De-focus current node
|
||||
items_.value(focused_node_)->SetHighlighted(false);
|
||||
focused_node_->SetHighlighted(false);
|
||||
}
|
||||
|
||||
focused_node_ = item->GetNode();
|
||||
focused_node_ = item;
|
||||
|
||||
item->SetHighlighted(true);
|
||||
|
||||
emit FocusedNodeChanged(focused_node_);
|
||||
emit FocusedNodeChanged(item->GetNode());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -469,7 +591,8 @@ void NodeParamView::KeyframeViewDragged(int x, int y)
|
||||
|
||||
void NodeParamView::UpdateElementY()
|
||||
{
|
||||
if (keyframe_view_) {
|
||||
qDebug() << "STUB";
|
||||
/*if (keyframe_view_) {
|
||||
for (auto it=items_.cbegin(); it!=items_.cend(); it++) {
|
||||
foreach (const QString& input, it.key()->inputs()) {
|
||||
int arr_sz = it.key()->InputArraySize(input);
|
||||
@@ -482,7 +605,7 @@ void NodeParamView::UpdateElementY()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
#include "node/node.h"
|
||||
#include "nodeparamviewcontext.h"
|
||||
#include "nodeparamviewdockarea.h"
|
||||
#include "nodeparamviewitem.h"
|
||||
#include "widget/keyframeview/keyframeview.h"
|
||||
@@ -64,8 +65,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void SelectNodes(const QVector<Node *> &nodes);
|
||||
void DeselectNodes(const QVector<Node*>& nodes);
|
||||
virtual ~NodeParamView() override;
|
||||
|
||||
void SetCreateCheckBoxes(NodeParamViewCheckBoxBehavior e)
|
||||
{
|
||||
@@ -77,11 +77,6 @@ public:
|
||||
return input_checked_.value(input);
|
||||
}
|
||||
|
||||
const QMap<Node*, NodeParamViewItem*>& GetItemMap() const
|
||||
{
|
||||
return items_;
|
||||
}
|
||||
|
||||
Node* GetTimeTarget() const;
|
||||
|
||||
void DeleteSelected();
|
||||
@@ -99,6 +94,8 @@ public:
|
||||
public slots:
|
||||
void SetInputChecked(const NodeInput &input, bool e);
|
||||
|
||||
void SetContexts(const QVector<Node*> &contexts);
|
||||
|
||||
signals:
|
||||
void RequestSelectNode(const QVector<Node*>& target);
|
||||
|
||||
@@ -122,13 +119,17 @@ private:
|
||||
|
||||
void SignalNodeOrder();
|
||||
|
||||
void AddNode(Node* n);
|
||||
void AddNode(Node* n, NodeParamViewContext *context);
|
||||
|
||||
//void AddNode(Node *node, Node *context, NodeParamViewContext *ctx_item);
|
||||
|
||||
void RemoveNode(Node* n);
|
||||
|
||||
void SortItemsInContext(NodeParamViewContext *context);
|
||||
|
||||
KeyframeView* keyframe_view_;
|
||||
|
||||
QMap<Node*, NodeParamViewItem*> items_;
|
||||
QVector<NodeParamViewContext*> context_items_;
|
||||
|
||||
QScrollBar* vertical_scrollbar_;
|
||||
|
||||
@@ -144,9 +145,7 @@ private:
|
||||
|
||||
QVector<Node*> active_nodes_;
|
||||
|
||||
QMap<Node*, bool> node_expanded_state_;
|
||||
|
||||
Node* focused_node_;
|
||||
NodeParamViewItem* focused_node_;
|
||||
|
||||
NodeParamViewCheckBoxBehavior create_checkboxes_;
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "nodeparamviewcontext.h"
|
||||
|
||||
#include "node/block/clip/clip.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super NodeParamViewItemBase
|
||||
|
||||
NodeParamViewContext::NodeParamViewContext(QWidget *parent) :
|
||||
super(parent)
|
||||
{
|
||||
QWidget *body = new QWidget();
|
||||
QHBoxLayout *body_layout = new QHBoxLayout(body);
|
||||
SetBody(body);
|
||||
|
||||
dock_area_ = new NodeParamViewDockArea();
|
||||
body_layout->addWidget(dock_area_);
|
||||
|
||||
setBackgroundRole(QPalette::Base);
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void NodeParamViewContext::AddNode(NodeParamViewItem *item)
|
||||
{
|
||||
items_.insert(item->GetNode(), item);
|
||||
dock_area_->AddItem(item);
|
||||
}
|
||||
|
||||
void NodeParamViewContext::RemoveNode(Node *node)
|
||||
{
|
||||
}
|
||||
|
||||
void NodeParamViewContext::Clear()
|
||||
{
|
||||
qDeleteAll(items_);
|
||||
items_.clear();
|
||||
}
|
||||
|
||||
void NodeParamViewContext::SetInputChecked(const NodeInput &input, bool e)
|
||||
{
|
||||
if (NodeParamViewItem *item = items_.value(input.node())) {
|
||||
item->SetInputChecked(input, e);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewContext::SetTimebase(const rational &timebase)
|
||||
{
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
item->SetTimebase(timebase);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewContext::SetTimeTarget(Node *n)
|
||||
{
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
item->SetTimeTarget(n);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewContext::SetTime(const rational &time)
|
||||
{
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
item->SetTime(time);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewContext::Retranslate()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef NODEPARAMVIEWCONTEXT_H
|
||||
#define NODEPARAMVIEWCONTEXT_H
|
||||
|
||||
#include "nodeparamviewdockarea.h"
|
||||
#include "nodeparamviewitembase.h"
|
||||
#include "nodeparamviewitem.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class NodeParamViewContext : public NodeParamViewItemBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeParamViewContext(QWidget *parent = nullptr);
|
||||
|
||||
NodeParamViewDockArea *GetDockArea() const
|
||||
{
|
||||
return dock_area_;
|
||||
}
|
||||
|
||||
const QVector<Node*> &GetContexts() const
|
||||
{
|
||||
return contexts_;
|
||||
}
|
||||
|
||||
const QMap<Node*, NodeParamViewItem*> &GetItems() const
|
||||
{
|
||||
return items_;
|
||||
}
|
||||
|
||||
void AddNode(NodeParamViewItem *item);
|
||||
|
||||
void RemoveNode(Node *node);
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetInputChecked(const NodeInput &input, bool e);
|
||||
|
||||
void SetTimebase(const rational &timebase);
|
||||
|
||||
void SetTimeTarget(Node *n);
|
||||
|
||||
void SetTime(const rational &time);
|
||||
|
||||
public slots:
|
||||
void AddContext(Node *node)
|
||||
{
|
||||
contexts_.append(node);
|
||||
}
|
||||
|
||||
void RemoveContext(Node *node)
|
||||
{
|
||||
contexts_.removeOne(node);
|
||||
}
|
||||
|
||||
protected slots:
|
||||
virtual void Retranslate() override;
|
||||
|
||||
private:
|
||||
NodeParamViewDockArea *dock_area_;
|
||||
|
||||
QVector<Node*> contexts_;
|
||||
|
||||
QMap<Node*, NodeParamViewItem*> items_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // NODEPARAMVIEWCONTEXT_H
|
||||
@@ -20,11 +20,18 @@
|
||||
|
||||
#include "nodeparamviewdockarea.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
namespace olive {
|
||||
|
||||
NodeParamViewDockArea::NodeParamViewDockArea(QWidget *parent) :
|
||||
QMainWindow(parent)
|
||||
{
|
||||
// Disable dock widgets from tabbing and disable glitchy animations
|
||||
setDockOptions(static_cast<QMainWindow::DockOption>(0));
|
||||
|
||||
// HACK: Hide the main window separators (unfortunately the cursors still appear)
|
||||
setStyleSheet(QStringLiteral("QMainWindow::separator {background: rgba(0, 0, 0, 0)}"));
|
||||
}
|
||||
|
||||
QMenu *NodeParamViewDockArea::createPopupMenu()
|
||||
@@ -32,4 +39,11 @@ QMenu *NodeParamViewDockArea::createPopupMenu()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NodeParamViewDockArea::AddItem(QDockWidget *item)
|
||||
{
|
||||
item->setAllowedAreas(Qt::LeftDockWidgetArea);
|
||||
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
virtual QMenu *createPopupMenu() override;
|
||||
|
||||
void AddItem(QDockWidget *item);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QEvent>
|
||||
#include <QPainter>
|
||||
|
||||
#include "common/qtutils.h"
|
||||
#include "core.h"
|
||||
@@ -43,18 +41,13 @@ const int NodeParamViewItemBody::kArrayCollapseBtnColumn = 1;
|
||||
const int NodeParamViewItemBody::kLabelColumn = 2;
|
||||
const int NodeParamViewItemBody::kWidgetStartColumn = 3;
|
||||
|
||||
#define super QDockWidget
|
||||
#define super NodeParamViewItemBase
|
||||
|
||||
NodeParamViewItem::NodeParamViewItem(Node *node, NodeParamViewCheckBoxBehavior create_checkboxes, QWidget *parent) :
|
||||
super(parent),
|
||||
node_(node),
|
||||
highlighted_(false)
|
||||
node_(node)
|
||||
{
|
||||
// Create title bar widget
|
||||
title_bar_ = new NodeParamViewItemTitleBar(this);
|
||||
|
||||
// Add title bar to widget
|
||||
this->setTitleBarWidget(title_bar_);
|
||||
node_->Retranslate();
|
||||
|
||||
// Create and add contents widget
|
||||
body_ = new NodeParamViewItemBody(node_, create_checkboxes);
|
||||
@@ -62,109 +55,31 @@ NodeParamViewItem::NodeParamViewItem(Node *node, NodeParamViewCheckBoxBehavior c
|
||||
connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime);
|
||||
connect(body_, &NodeParamViewItemBody::ArrayExpandedChanged, this, &NodeParamViewItem::ArrayExpandedChanged);
|
||||
connect(body_, &NodeParamViewItemBody::InputCheckedChanged, this, &NodeParamViewItem::InputCheckedChanged);
|
||||
connect(title_bar_, &NodeParamViewItemTitleBar::ExpandedStateChanged, this, &NodeParamViewItem::SetExpanded);
|
||||
connect(title_bar_, &NodeParamViewItemTitleBar::PinToggled, this, &NodeParamViewItem::PinToggled);
|
||||
|
||||
this->setWidget(body_);
|
||||
|
||||
// Use dummy QWidget to retain width when not expanded (QDockWidget seems to ignore the titlebar
|
||||
// size hints and will shrink as small as possible if the body is hidden)
|
||||
hidden_body_ = new QWidget(this);
|
||||
SetBody(body_);
|
||||
|
||||
connect(node_, &Node::LabelChanged, this, &NodeParamViewItem::Retranslate);
|
||||
|
||||
setBackgroundRole(QPalette::Base);
|
||||
setAutoFillBackground(true);
|
||||
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setBackgroundRole(QPalette::Window);
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void NodeParamViewItem::SetTimeTarget(Node *target)
|
||||
{
|
||||
body_->SetTimeTarget(target);
|
||||
}
|
||||
|
||||
void NodeParamViewItem::SetTime(const rational &time)
|
||||
{
|
||||
time_ = time;
|
||||
|
||||
body_->SetTime(time_);
|
||||
}
|
||||
|
||||
void NodeParamViewItem::SetTimebase(const rational& timebase)
|
||||
{
|
||||
body_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
Node *NodeParamViewItem::GetNode() const
|
||||
{
|
||||
return node_;
|
||||
}
|
||||
|
||||
void NodeParamViewItem::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
super::changeEvent(e);
|
||||
}
|
||||
|
||||
void NodeParamViewItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
super::paintEvent(event);
|
||||
|
||||
// Draw border if focused
|
||||
if (highlighted_) {
|
||||
QPainter p(this);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(palette().highlight().color());
|
||||
p.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItem::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
super::moveEvent(event);
|
||||
|
||||
emit Moved();
|
||||
}
|
||||
|
||||
void NodeParamViewItem::Retranslate()
|
||||
{
|
||||
node_->Retranslate();
|
||||
|
||||
if (node_->GetLabel().isEmpty()) {
|
||||
title_bar_->SetText(node_->Name());
|
||||
} else {
|
||||
title_bar_->SetText(tr("%1 (%2)").arg(node_->GetLabel(), node_->Name()));
|
||||
}
|
||||
title_bar()->SetText(GetTitleBarTextFromNode(node_));
|
||||
|
||||
body_->Retranslate();
|
||||
}
|
||||
|
||||
void NodeParamViewItem::SetExpanded(bool e)
|
||||
{
|
||||
setWidget(e ? body_ : hidden_body_);
|
||||
title_bar_->SetExpanded(e);
|
||||
|
||||
emit ExpandedChanged(e);
|
||||
}
|
||||
|
||||
bool NodeParamViewItem::IsExpanded() const
|
||||
{
|
||||
return body_->isVisible();
|
||||
}
|
||||
|
||||
int NodeParamViewItem::GetElementY(const NodeInput &c) const
|
||||
{
|
||||
if (IsExpanded()) {
|
||||
return body_->GetElementY(c);
|
||||
} else {
|
||||
// Not expanded, put keyframes at the titlebar Y
|
||||
return mapToGlobal(title_bar_->rect().center()).y();
|
||||
return mapToGlobal(title_bar()->rect().center()).y();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,63 +88,6 @@ void NodeParamViewItem::SetInputChecked(const NodeInput &input, bool e)
|
||||
body_->SetInputChecked(input, e);
|
||||
}
|
||||
|
||||
void NodeParamViewItem::ToggleExpanded()
|
||||
{
|
||||
SetExpanded(!IsExpanded());
|
||||
}
|
||||
|
||||
NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
draw_border_(true)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
|
||||
collapse_btn_ = new CollapseButton();
|
||||
connect(collapse_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::ExpandedStateChanged);
|
||||
layout->addWidget(collapse_btn_);
|
||||
|
||||
lbl_ = new QLabel();
|
||||
layout->addWidget(lbl_);
|
||||
|
||||
// Place next buttons on the far side
|
||||
layout->addStretch();
|
||||
|
||||
QPushButton* pin_btn = new QPushButton(QStringLiteral("P"));
|
||||
pin_btn->setCheckable(true);
|
||||
pin_btn->setFixedSize(pin_btn->sizeHint().height(), pin_btn->sizeHint().height());
|
||||
layout->addWidget(pin_btn);
|
||||
connect(pin_btn, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::PinToggled);
|
||||
}
|
||||
|
||||
void NodeParamViewItemTitleBar::SetExpanded(bool e)
|
||||
{
|
||||
draw_border_ = e;
|
||||
collapse_btn_->setChecked(e);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void NodeParamViewItemTitleBar::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QWidget::paintEvent(event);
|
||||
|
||||
if (draw_border_) {
|
||||
QPainter p(this);
|
||||
|
||||
// Draw bottom border using text color
|
||||
int bottom = height() - 1;
|
||||
p.setPen(palette().text().color());
|
||||
p.drawLine(0, bottom, width(), bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseDoubleClickEvent(event);
|
||||
|
||||
collapse_btn_->click();
|
||||
}
|
||||
|
||||
NodeParamViewItemBody::NodeParamViewItemBody(Node* node, NodeParamViewCheckBoxBehavior create_checkboxes, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
node_(node),
|
||||
@@ -241,42 +99,42 @@ NodeParamViewItemBody::NodeParamViewItemBody(Node* node, NodeParamViewCheckBoxBe
|
||||
|
||||
// Create widgets all root level components
|
||||
foreach (QString input, node->inputs()) {
|
||||
Node *n;
|
||||
if (NodeGroup *g = dynamic_cast<NodeGroup*>(node)) {
|
||||
Node *n = node;
|
||||
while (NodeGroup *g = dynamic_cast<NodeGroup*>(n)) {
|
||||
const NodeInput &ni = g->GetInputPassthroughs().value(input);
|
||||
n = ni.node();
|
||||
input = ni.input();
|
||||
} else {
|
||||
n = node;
|
||||
}
|
||||
|
||||
CreateWidgets(root_layout, n, input, -1, insert_row);
|
||||
|
||||
insert_row++;
|
||||
|
||||
if (n->InputIsArray(input)) {
|
||||
// Insert here
|
||||
QWidget* array_widget = new QWidget();
|
||||
|
||||
QGridLayout* array_layout = new QGridLayout(array_widget);
|
||||
array_layout->setContentsMargins(QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral(" ")), 0, 0, 0);
|
||||
|
||||
root_layout->addWidget(array_widget, insert_row, 1, 1, 10);
|
||||
|
||||
// Start with zero elements for efficiency. We will make the widgets for them if the user
|
||||
// requests the array UI to be expanded
|
||||
int arr_sz = 0;
|
||||
|
||||
// Add one last add button for appending to the array
|
||||
NodeParamViewArrayButton* append_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd);
|
||||
connect(append_btn, &NodeParamViewArrayButton::clicked, this, &NodeParamViewItemBody::ArrayAppendClicked);
|
||||
array_layout->addWidget(append_btn, arr_sz, kArrayInsertColumn);
|
||||
|
||||
array_widget->setVisible(false);
|
||||
|
||||
array_ui_.insert({n, input}, {array_widget, arr_sz, append_btn});
|
||||
if (!(n->GetInputFlags(input) & kInputFlagHidden)) {
|
||||
CreateWidgets(root_layout, n, input, -1, insert_row);
|
||||
|
||||
insert_row++;
|
||||
|
||||
if (n->InputIsArray(input)) {
|
||||
// Insert here
|
||||
QWidget* array_widget = new QWidget();
|
||||
|
||||
QGridLayout* array_layout = new QGridLayout(array_widget);
|
||||
array_layout->setContentsMargins(QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral(" ")), 0, 0, 0);
|
||||
|
||||
root_layout->addWidget(array_widget, insert_row, 1, 1, 10);
|
||||
|
||||
// Start with zero elements for efficiency. We will make the widgets for them if the user
|
||||
// requests the array UI to be expanded
|
||||
int arr_sz = 0;
|
||||
|
||||
// Add one last add button for appending to the array
|
||||
NodeParamViewArrayButton* append_btn = new NodeParamViewArrayButton(NodeParamViewArrayButton::kAdd);
|
||||
connect(append_btn, &NodeParamViewArrayButton::clicked, this, &NodeParamViewItemBody::ArrayAppendClicked);
|
||||
array_layout->addWidget(append_btn, arr_sz, kArrayInsertColumn);
|
||||
|
||||
array_widget->setVisible(false);
|
||||
|
||||
array_ui_.insert({n, input}, {array_widget, arr_sz, append_btn});
|
||||
|
||||
insert_row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +299,7 @@ int NodeParamViewItemBody::GetElementY(NodeInput c) const
|
||||
c.set_element(-1);
|
||||
}
|
||||
|
||||
if (NodeGroup *g = dynamic_cast<NodeGroup*>(c.node())) {
|
||||
while (NodeGroup *g = dynamic_cast<NodeGroup*>(c.node())) {
|
||||
const NodeInput &passthrough = g->GetInputPassthroughs().value(c.input());
|
||||
c.set_node(passthrough.node());
|
||||
c.set_input(passthrough.input());
|
||||
@@ -503,7 +361,13 @@ void NodeParamViewItemBody::PlaceWidgetsFromBridge(QGridLayout* layout, NodePara
|
||||
|
||||
void NodeParamViewItemBody::InputArraySizeChangedInternal(Node *node, const QString &input, int size)
|
||||
{
|
||||
ArrayUI& array_ui = array_ui_[{node, input}];
|
||||
NodeInputPair nip = {node, input};
|
||||
|
||||
if (!array_ui_.contains(nip)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayUI& array_ui = array_ui_[nip];
|
||||
|
||||
if (size != array_ui.count) {
|
||||
QGridLayout* grid = static_cast<QGridLayout*>(array_ui.widget->layout());
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define NODEPARAMVIEWITEM_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDockWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
@@ -33,6 +32,7 @@
|
||||
#include "nodeparamviewarraywidget.h"
|
||||
#include "nodeparamviewconnectedlabel.h"
|
||||
#include "nodeparamviewkeyframecontrol.h"
|
||||
#include "nodeparamviewitembase.h"
|
||||
#include "nodeparamviewwidgetbridge.h"
|
||||
#include "widget/clickablelabel/clickablelabel.h"
|
||||
#include "widget/collapsebutton/collapsebutton.h"
|
||||
@@ -45,40 +45,6 @@ enum NodeParamViewCheckBoxBehavior {
|
||||
kCheckBoxesOnNonConnected
|
||||
};
|
||||
|
||||
class NodeParamViewItemTitleBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeParamViewItemTitleBar(QWidget* parent = nullptr);
|
||||
|
||||
void SetExpanded(bool e);
|
||||
|
||||
void SetText(const QString& s)
|
||||
{
|
||||
lbl_->setText(s);
|
||||
lbl_->setToolTip(s);
|
||||
lbl_->setMinimumWidth(1);
|
||||
}
|
||||
|
||||
signals:
|
||||
void ExpandedStateChanged(bool e);
|
||||
|
||||
void PinToggled(bool e);
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool draw_border_;
|
||||
|
||||
QLabel* lbl_;
|
||||
|
||||
CollapseButton* collapse_btn_;
|
||||
|
||||
};
|
||||
|
||||
class NodeParamViewItemBody : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -189,77 +155,57 @@ private slots:
|
||||
|
||||
};
|
||||
|
||||
class NodeParamViewItem : public QDockWidget
|
||||
class NodeParamViewItem : public NodeParamViewItemBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeParamViewItem(Node* node, NodeParamViewCheckBoxBehavior create_checkboxes, QWidget* parent = nullptr);
|
||||
|
||||
void SetTimeTarget(Node* target);
|
||||
|
||||
void SetTime(const rational& time);
|
||||
|
||||
// Set the timebase of the NodeParamViewItemBody
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
Node* GetNode() const;
|
||||
|
||||
bool IsExpanded() const;
|
||||
|
||||
void SetHighlighted(bool e)
|
||||
void SetTimeTarget(Node* target)
|
||||
{
|
||||
highlighted_ = e;
|
||||
body_->SetTimeTarget(target);
|
||||
}
|
||||
|
||||
update();
|
||||
void SetTime(const rational& time)
|
||||
{
|
||||
time_ = time;
|
||||
|
||||
body_->SetTime(time_);
|
||||
}
|
||||
|
||||
void SetTimebase(const rational& timebase)
|
||||
{
|
||||
body_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
Node* GetNode() const
|
||||
{
|
||||
return node_;
|
||||
}
|
||||
|
||||
int GetElementY(const NodeInput& c) const;
|
||||
|
||||
void SetInputChecked(const NodeInput &input, bool e);
|
||||
|
||||
public slots:
|
||||
void SetExpanded(bool e);
|
||||
|
||||
void ToggleExpanded();
|
||||
|
||||
signals:
|
||||
void RequestSetTime(const rational& time);
|
||||
|
||||
void RequestSelectNode(const QVector<Node*>& node);
|
||||
|
||||
void PinToggled(bool e);
|
||||
|
||||
void ExpandedChanged(bool e);
|
||||
|
||||
void ArrayExpandedChanged(bool e);
|
||||
|
||||
void Moved();
|
||||
|
||||
void InputCheckedChanged(const NodeInput &input, bool e);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *e) override;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
protected slots:
|
||||
virtual void Retranslate() override;
|
||||
|
||||
private:
|
||||
NodeParamViewItemTitleBar* title_bar_;
|
||||
|
||||
NodeParamViewItemBody* body_;
|
||||
|
||||
QWidget *hidden_body_;
|
||||
|
||||
Node* node_;
|
||||
|
||||
rational time_;
|
||||
|
||||
bool highlighted_;
|
||||
|
||||
private slots:
|
||||
void Retranslate();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "nodeparamviewitembase.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QPainter>
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super QDockWidget
|
||||
|
||||
NodeParamViewItemBase::NodeParamViewItemBase(QWidget *parent) :
|
||||
super(parent),
|
||||
highlighted_(false)
|
||||
{
|
||||
// Create title bar widget
|
||||
title_bar_ = new NodeParamViewItemTitleBar(this);
|
||||
|
||||
// Add title bar to widget
|
||||
this->setTitleBarWidget(title_bar_);
|
||||
|
||||
// Connect title bar to this
|
||||
connect(title_bar_, &NodeParamViewItemTitleBar::ExpandedStateChanged, this, &NodeParamViewItemBase::SetExpanded);
|
||||
connect(title_bar_, &NodeParamViewItemTitleBar::PinToggled, this, &NodeParamViewItemBase::PinToggled);
|
||||
|
||||
// Use dummy QWidget to retain width when not expanded (QDockWidget seems to ignore the titlebar
|
||||
// size hints and will shrink as small as possible if the body is hidden)
|
||||
hidden_body_ = new QWidget(this);
|
||||
|
||||
setAutoFillBackground(true);
|
||||
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
}
|
||||
|
||||
bool NodeParamViewItemBase::IsExpanded() const
|
||||
{
|
||||
return body_->isVisible();
|
||||
}
|
||||
|
||||
QString NodeParamViewItemBase::GetTitleBarTextFromNode(Node *n)
|
||||
{
|
||||
if (n->GetLabel().isEmpty()) {
|
||||
return n->Name();
|
||||
} else {
|
||||
return tr("%1 (%2)").arg(n->GetLabel(), n->Name());
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBase::SetBody(QWidget *body)
|
||||
{
|
||||
body_ = body;
|
||||
body_->setParent(this);
|
||||
|
||||
if (title_bar_->IsExpanded()) {
|
||||
setWidget(body_);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBase::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
super::paintEvent(event);
|
||||
|
||||
// Draw border if focused
|
||||
if (highlighted_) {
|
||||
QPainter p(this);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(palette().highlight().color());
|
||||
p.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBase::SetExpanded(bool e)
|
||||
{
|
||||
setWidget(e ? body_ : hidden_body_);
|
||||
title_bar_->SetExpanded(e);
|
||||
|
||||
emit ExpandedChanged(e);
|
||||
}
|
||||
|
||||
void NodeParamViewItemBase::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
super::changeEvent(e);
|
||||
}
|
||||
|
||||
void NodeParamViewItemBase::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
super::moveEvent(event);
|
||||
|
||||
emit Moved();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef NODEPARAMVIEWITEMBASE_H
|
||||
#define NODEPARAMVIEWITEMBASE_H
|
||||
|
||||
#include <QDockWidget>
|
||||
|
||||
#include "nodeparamviewitemtitlebar.h"
|
||||
#include "node/node.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class NodeParamViewItemBase : public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeParamViewItemBase(QWidget* parent = nullptr);
|
||||
|
||||
void SetHighlighted(bool e)
|
||||
{
|
||||
highlighted_ = e;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
bool IsExpanded() const;
|
||||
|
||||
static QString GetTitleBarTextFromNode(Node *n);
|
||||
|
||||
public slots:
|
||||
void SetExpanded(bool e);
|
||||
|
||||
void ToggleExpanded()
|
||||
{
|
||||
SetExpanded(!IsExpanded());
|
||||
}
|
||||
|
||||
signals:
|
||||
void PinToggled(bool e);
|
||||
|
||||
void ExpandedChanged(bool e);
|
||||
|
||||
void Moved();
|
||||
|
||||
protected:
|
||||
void SetBody(QWidget *body);
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
NodeParamViewItemTitleBar* title_bar() const
|
||||
{
|
||||
return title_bar_;
|
||||
}
|
||||
|
||||
virtual void changeEvent(QEvent *e) override;
|
||||
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
|
||||
protected slots:
|
||||
virtual void Retranslate(){}
|
||||
|
||||
private:
|
||||
NodeParamViewItemTitleBar* title_bar_;
|
||||
|
||||
QWidget *body_;
|
||||
|
||||
QWidget *hidden_body_;
|
||||
|
||||
bool highlighted_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // NODEPARAMVIEWITEMBASE_H
|
||||
@@ -0,0 +1,90 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "nodeparamviewitemtitlebar.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainter>
|
||||
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
draw_border_(true)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
|
||||
collapse_btn_ = new CollapseButton();
|
||||
connect(collapse_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::ExpandedStateChanged);
|
||||
layout->addWidget(collapse_btn_);
|
||||
|
||||
lbl_ = new QLabel();
|
||||
layout->addWidget(lbl_);
|
||||
|
||||
// Place next buttons on the far side
|
||||
layout->addStretch();
|
||||
|
||||
add_fx_btn_ = new QPushButton();
|
||||
add_fx_btn_->setIcon(icon::AddEffect);
|
||||
add_fx_btn_->setFixedSize(add_fx_btn_->sizeHint().height(), add_fx_btn_->sizeHint().height());
|
||||
add_fx_btn_->setVisible(false);
|
||||
layout->addWidget(add_fx_btn_);
|
||||
connect(add_fx_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::AddEffectButtonClicked);
|
||||
|
||||
pin_btn_ = new QPushButton(QStringLiteral("P"));
|
||||
pin_btn_->setCheckable(true);
|
||||
pin_btn_->setFixedSize(pin_btn_->sizeHint().height(), pin_btn_->sizeHint().height());
|
||||
pin_btn_->setVisible(false);
|
||||
layout->addWidget(pin_btn_);
|
||||
connect(pin_btn_, &QPushButton::clicked, this, &NodeParamViewItemTitleBar::PinToggled);
|
||||
}
|
||||
|
||||
void NodeParamViewItemTitleBar::SetExpanded(bool e)
|
||||
{
|
||||
draw_border_ = e;
|
||||
collapse_btn_->setChecked(e);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void NodeParamViewItemTitleBar::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QWidget::paintEvent(event);
|
||||
|
||||
if (draw_border_) {
|
||||
QPainter p(this);
|
||||
|
||||
// Draw bottom border using text color
|
||||
int bottom = height() - 1;
|
||||
p.setPen(palette().text().color());
|
||||
p.drawLine(0, bottom, width(), bottom);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseDoubleClickEvent(event);
|
||||
|
||||
collapse_btn_->click();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef NODEPARAMVIEWITEMTITLEBAR_H
|
||||
#define NODEPARAMVIEWITEMTITLEBAR_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
|
||||
#include "widget/collapsebutton/collapsebutton.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class NodeParamViewItemTitleBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeParamViewItemTitleBar(QWidget* parent = nullptr);
|
||||
|
||||
bool IsExpanded() const
|
||||
{
|
||||
return collapse_btn_->isChecked();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void SetExpanded(bool e);
|
||||
|
||||
void SetText(const QString& s)
|
||||
{
|
||||
lbl_->setText(s);
|
||||
lbl_->setToolTip(s);
|
||||
lbl_->setMinimumWidth(1);
|
||||
}
|
||||
|
||||
void SetPinButtonVisible(bool e)
|
||||
{
|
||||
pin_btn_->setVisible(e);
|
||||
}
|
||||
|
||||
void SetAddEffectButtonVisible(bool e)
|
||||
{
|
||||
add_fx_btn_->setVisible(e);
|
||||
}
|
||||
|
||||
signals:
|
||||
void ExpandedStateChanged(bool e);
|
||||
|
||||
void PinToggled(bool e);
|
||||
|
||||
void AddEffectButtonClicked();
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool draw_border_;
|
||||
|
||||
QLabel* lbl_;
|
||||
|
||||
CollapseButton* collapse_btn_;
|
||||
|
||||
QPushButton *pin_btn_;
|
||||
|
||||
QPushButton *add_fx_btn_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // NODEPARAMVIEWITEMTITLEBAR_H
|
||||
@@ -515,11 +515,11 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
if (!reconnected_to_itself) {
|
||||
Node *creating_output = create_edge_output_item_->GetNode();
|
||||
|
||||
if (NodeGroup *output_group = dynamic_cast<NodeGroup*>(creating_output)) {
|
||||
while (NodeGroup *output_group = dynamic_cast<NodeGroup*>(creating_output)) {
|
||||
creating_output = output_group->GetOutputPassthrough();
|
||||
}
|
||||
|
||||
if (NodeGroup *input_group = dynamic_cast<NodeGroup*>(creating_input.node())) {
|
||||
while (NodeGroup *input_group = dynamic_cast<NodeGroup*>(creating_input.node())) {
|
||||
creating_input = input_group->GetInputPassthroughs().value(creating_input.input());
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,9 @@ NodeViewItem::NodeViewItem(Node *node, const QString &input, int element, Node *
|
||||
}
|
||||
} else {
|
||||
output_connector_->setVisible(false);
|
||||
|
||||
connect(node_, &Node::InputArraySizeChanged, this, &NodeViewItem::InputArraySizeChanged);
|
||||
connect(node_, &Node::InputArraySizeChanged, this, &NodeViewItem::InputArraySizeChanged);
|
||||
}
|
||||
|
||||
// This should be set during runtime, but just in case here's a default fallback
|
||||
@@ -740,14 +743,20 @@ void NodeViewItem::RepopulateInputs()
|
||||
}
|
||||
|
||||
input_connector_->setVisible(has_connectable_inputs_);
|
||||
}
|
||||
|
||||
if (IsExpanded()) {
|
||||
// Create or remove inputs when necessary
|
||||
}
|
||||
} else {
|
||||
if (IsExpanded() && element_ == -1) {
|
||||
// Create or remove array elements when necessary
|
||||
}
|
||||
if (IsExpanded() && (IsOutputItem() || element_ == -1)) {
|
||||
// Create or remove inputs when necessary
|
||||
// NOTE: This is not the most efficient thing in the world, but it does work
|
||||
SetExpanded(false);
|
||||
SetExpanded(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeViewItem::InputArraySizeChanged(const QString &input)
|
||||
{
|
||||
if (input == input_) {
|
||||
RepopulateInputs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +222,8 @@ private slots:
|
||||
|
||||
void RepopulateInputs();
|
||||
|
||||
void InputArraySizeChanged(const QString &input);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -720,6 +720,7 @@ void MainWindow::UpdateNodePanelContextFromTimelinePanel(TimelinePanel *panel)
|
||||
}
|
||||
|
||||
node_panel_->SetContexts(context);
|
||||
param_panel_->SetContexts(context);
|
||||
}
|
||||
|
||||
void MainWindow::FocusedPanelChanged(PanelWidget *panel)
|
||||
|
||||
Reference in New Issue
Block a user