nodeparamview: reworked based on QMainWindow for docking functionality

This commit is contained in:
itsmattkc
2020-09-28 19:55:18 +10:00
parent dac68cabc2
commit 4c30773fd4
4 changed files with 149 additions and 40 deletions
+38 -19
View File
@@ -49,18 +49,26 @@ NodeParamView::NodeParamView(QWidget *parent) :
splitter->addWidget(scroll_area);
// Param widget
param_widget_area_ = new QWidget();
scroll_area->setWidget(param_widget_area_);
param_widget_container_ = new NodeParamViewParamContainer();
connect(param_widget_container_, &NodeParamViewParamContainer::Resized, this, &NodeParamView::UpdateGlobalScrollBar);
scroll_area->setWidget(param_widget_container_);
// Set up scroll area layout
param_layout_ = new QVBoxLayout(param_widget_area_);
param_layout_->setSpacing(0);
param_widget_area_ = new QMainWindow();
// KeyframeView is offset by a ruler, so to stay synchronized with it, we should be too
param_layout_->setContentsMargins(0, ruler()->height(), 0, 0);
// Disable dock widgets from tabbing and disable glitchy animations
param_widget_area_->setDockOptions(static_cast<QMainWindow::DockOption>(0));
// Add a stretch to allow empty space at the bottom of the layout
param_layout_->addStretch();
// 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());
param_widget_container_layout->setContentsMargins(param_widget_margin);
param_widget_container_layout->setSpacing(0);
param_widget_container_layout->addWidget(param_widget_area_);
param_widget_container_layout->addStretch(INT_MAX);
// Set up keyframe view
QWidget* keyframe_area = new QWidget();
@@ -100,9 +108,8 @@ NodeParamView::NodeParamView(QWidget *parent) :
layout->addWidget(vertical_scrollbar_);
// Connect scrollbars together
connect(scroll_area->verticalScrollBar(), &QScrollBar::rangeChanged, vertical_scrollbar_, &QScrollBar::setRange);
connect(scroll_area->verticalScrollBar(), &QScrollBar::rangeChanged, this, &NodeParamView::ForceKeyframeViewToScroll);
//connect(scroll_area->verticalScrollBar(), &QScrollBar::rangeChanged, vertical_scrollbar_, &QScrollBar::setRange);
//connect(scroll_area->verticalScrollBar(), &QScrollBar::rangeChanged, this, &NodeParamView::ForceKeyframeViewToScroll);
connect(keyframe_view_->verticalScrollBar(), &QScrollBar::valueChanged, vertical_scrollbar_, &QScrollBar::setValue);
connect(keyframe_view_->verticalScrollBar(), &QScrollBar::valueChanged, scroll_area->verticalScrollBar(), &QScrollBar::setValue);
connect(scroll_area->verticalScrollBar(), &QScrollBar::valueChanged, vertical_scrollbar_, &QScrollBar::setValue);
@@ -125,27 +132,29 @@ NodeParamView::NodeParamView(QWidget *parent) :
void NodeParamView::SelectNodes(const QList<Node *> &nodes)
{
foreach (Node* n, nodes) {
NodeParamViewItem* item = new NodeParamViewItem(n);
NodeParamViewItem* item = new NodeParamViewItem(n, param_widget_area_);
// Insert the widget before the stretch
param_layout_->insertWidget(param_layout_->count() - 1, item);
item->setAllowedAreas(Qt::LeftDockWidgetArea);
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
connect(item, &NodeParamViewItem::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
connect(item, &NodeParamViewItem::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
connect(item, &NodeParamViewItem::RequestSetTime, this, &NodeParamView::ItemRequestedTimeChanged);
connect(item, &NodeParamViewItem::InputDoubleClicked, this, &NodeParamView::InputDoubleClicked);
connect(item, &NodeParamViewItem::RequestSelectNode, this, &NodeParamView::RequestSelectNode);
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::QueueKeyframePositionUpdate);
// Set time target
item->SetTimeTarget(GetTimeTarget());
items_.insert(n, item);
param_widget_area_->addDockWidget(Qt::LeftDockWidgetArea, item);
}
UpdateItemTime(GetTimestamp());
// Re-arrange keyframes
QMetaObject::invokeMethod(this, "PlaceKeyframesOnView", Qt::QueuedConnection);
QueueKeyframePositionUpdate();
}
void NodeParamView::DeselectNodes(const QList<Node *> &nodes)
@@ -159,7 +168,7 @@ void NodeParamView::DeselectNodes(const QList<Node *> &nodes)
}
// Re-arrange keyframes
QMetaObject::invokeMethod(this, "PlaceKeyframesOnView", Qt::QueuedConnection);
QueueKeyframePositionUpdate();
}
void NodeParamView::resizeEvent(QResizeEvent *event)
@@ -167,6 +176,8 @@ void NodeParamView::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event);
vertical_scrollbar_->setPageStep(vertical_scrollbar_->height());
UpdateGlobalScrollBar();
}
void NodeParamView::ScaleChangedEvent(const double &scale)
@@ -223,14 +234,22 @@ void NodeParamView::UpdateItemTime(const int64_t &timestamp)
}
}
void NodeParamView::QueueKeyframePositionUpdate()
{
QMetaObject::invokeMethod(this, "PlaceKeyframesOnView", Qt::QueuedConnection);
}
void NodeParamView::ItemRequestedTimeChanged(const rational &time)
{
SetTimeAndSignal(Timecode::time_to_timestamp(time, keyframe_view_->timebase()));
}
void NodeParamView::ForceKeyframeViewToScroll()
void NodeParamView::UpdateGlobalScrollBar()
{
keyframe_view_->SetMaxScroll(param_widget_area_->height() - ruler()->height());
int height_offscreen = param_widget_container_->height() - ruler()->height();
keyframe_view_->SetMaxScroll(height_offscreen);
vertical_scrollbar_->setRange(0, height_offscreen - keyframe_view_->height());
}
void NodeParamView::PlaceKeyframesOnView()
+30 -3
View File
@@ -21,6 +21,7 @@
#ifndef NODEPARAMVIEW_H
#define NODEPARAMVIEW_H
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
@@ -31,6 +32,28 @@
OLIVE_NAMESPACE_ENTER
class NodeParamViewParamContainer : public QWidget
{
Q_OBJECT
public:
NodeParamViewParamContainer(QWidget* parent = nullptr) :
QWidget(parent)
{
}
protected:
virtual void resizeEvent(QResizeEvent *event) override
{
QWidget::resizeEvent(event);
emit Resized(event->size().height());
}
signals:
void Resized(int new_height);
};
class NodeParamView : public TimeBasedWidget
{
Q_OBJECT
@@ -66,7 +89,7 @@ protected:
private:
void UpdateItemTime(const int64_t &timestamp);
QVBoxLayout* param_layout_;
void QueueKeyframePositionUpdate();
KeyframeView* keyframe_view_;
@@ -76,12 +99,16 @@ private:
int last_scroll_val_;
QWidget* param_widget_area_;
NodeParamViewParamContainer* param_widget_container_;
// This may look weird, but QMainWindow is just a QWidget with a fancy layout that allows
// docking windows
QMainWindow* param_widget_area_;
private slots:
void ItemRequestedTimeChanged(const rational& time);
void ForceKeyframeViewToScroll();
void UpdateGlobalScrollBar();
void PlaceKeyframesOnView();
+58 -16
View File
@@ -32,16 +32,11 @@
OLIVE_NAMESPACE_ENTER
NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
QWidget(parent),
QDockWidget(parent),
node_(node)
{
QVBoxLayout* main_layout = new QVBoxLayout(this);
main_layout->setSpacing(0);
main_layout->setMargin(0);
// Create title bar widget
title_bar_ = new NodeParamViewItemTitleBar(this);
title_bar_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
QHBoxLayout* title_bar_layout = new QHBoxLayout(title_bar_);
@@ -52,7 +47,7 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
title_bar_layout->addWidget(title_bar_lbl_);
// Add title bar to widget
main_layout->addWidget(title_bar_);
this->setTitleBarWidget(title_bar_);
// Create and add contents widget
QVector<NodeInput*> inputs;
@@ -70,11 +65,24 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime);
connect(body_, &NodeParamViewItemBody::KeyframeAdded, this, &NodeParamViewItem::KeyframeAdded);
connect(body_, &NodeParamViewItemBody::KeyframeRemoved, this, &NodeParamViewItem::KeyframeRemoved);
connect(title_bar_collapse_btn_, &QPushButton::toggled, body_, &NodeParamViewItemBody::setVisible);
main_layout->addWidget(body_);
connect(title_bar_collapse_btn_, &QPushButton::toggled, this, &NodeParamViewItem::SetExpanded);
connect(title_bar_, &NodeParamViewItemTitleBar::DoubleClicked, this, &NodeParamViewItem::ToggleExpanded);
QWidget* body_container = new QWidget();
body_container->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
QHBoxLayout* body_container_layout = new QHBoxLayout(body_container);
body_container_layout->setSpacing(0);
body_container_layout->setMargin(0);
body_container_layout->addWidget(body_);
this->setWidget(body_container);
connect(node_, &Node::LabelChanged, this, &NodeParamViewItem::Retranslate);
setBackgroundRole(QPalette::Base);
setAutoFillBackground(true);
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
Retranslate();
}
@@ -122,21 +130,55 @@ void NodeParamViewItem::Retranslate()
body_->Retranslate();
}
NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) :
QWidget(parent)
void NodeParamViewItem::SetExpanded(bool e)
{
body_->setVisible(e);
title_bar_->SetBorderVisible(e);
title_bar_collapse_btn_->setChecked(e);
}
bool NodeParamViewItem::IsExpanded() const
{
return body_->isVisible();
}
void NodeParamViewItem::ToggleExpanded()
{
SetExpanded(!IsExpanded());
}
NodeParamViewItemTitleBar::NodeParamViewItemTitleBar(QWidget *parent) :
QWidget(parent),
draw_border_(true)
{
}
void NodeParamViewItemTitleBar::SetBorderVisible(bool e)
{
draw_border_ = e;
update();
}
void NodeParamViewItemTitleBar::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
QPainter p(this);
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);
// 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);
emit DoubleClicked();
}
NodeParamViewItemBody::NodeParamViewItemBody(const QVector<NodeInput *> &inputs, QWidget *parent) :
+23 -2
View File
@@ -21,6 +21,7 @@
#ifndef NODEPARAMVIEWITEM_H
#define NODEPARAMVIEWITEM_H
#include <QDockWidget>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
@@ -36,12 +37,25 @@
OLIVE_NAMESPACE_ENTER
class NodeParamViewItemTitleBar : public QWidget {
class NodeParamViewItemTitleBar : public QWidget
{
Q_OBJECT
public:
NodeParamViewItemTitleBar(QWidget* parent = nullptr);
void SetBorderVisible(bool e);
signals:
void DoubleClicked();
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
private:
bool draw_border_;
};
class NodeParamViewItemBody : public QWidget {
@@ -99,7 +113,7 @@ private slots:
};
class NodeParamViewItem : public QWidget
class NodeParamViewItem : public QDockWidget
{
Q_OBJECT
public:
@@ -111,6 +125,8 @@ public:
Node* GetNode() const;
bool IsExpanded() const;
public slots:
void SignalAllKeyframes();
@@ -125,6 +141,11 @@ signals:
void RequestSelectNode(const QList<Node*>& node);
public slots:
void SetExpanded(bool e);
void ToggleExpanded();
protected:
virtual void changeEvent(QEvent *e) override;