correctly connect timeline and trackview so they vertically scroll in tandem

with each other
This commit is contained in:
itsmattkc
2019-12-31 18:29:23 +11:00
parent 41b53d7a7f
commit 9060636499
11 changed files with 122 additions and 18 deletions
-1
View File
@@ -10,7 +10,6 @@ CurveView::CurveView(QWidget *parent) :
{
setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
setDragMode(RubberBandDrag);
setViewportUpdateMode(FullViewportUpdate);
SetYAxisEnabled(true);
text_padding_ = QFontMetricsWidth(fontMetrics(), QStringLiteral("i"));
@@ -1,6 +1,7 @@
#include "timelineandtrackview.h"
#include <QHBoxLayout>
#include <QScrollBar>
TimelineAndTrackView::TimelineAndTrackView(const TrackType &type, Qt::Alignment vertical_alignment, QWidget *parent) :
QWidget(parent)
@@ -19,6 +20,9 @@ TimelineAndTrackView::TimelineAndTrackView(const TrackType &type, Qt::Alignment
view_ = new TimelineView(type, vertical_alignment);
splitter_->addWidget(view_);
connect(view_->verticalScrollBar(), &QScrollBar::valueChanged, this, &TimelineAndTrackView::ViewValueChanged);
connect(track_view_->verticalScrollBar(), &QScrollBar::valueChanged, this, &TimelineAndTrackView::TracksValueChanged);
splitter_->setSizes({1, width()});
}
@@ -36,3 +40,13 @@ TrackView *TimelineAndTrackView::track_view() const
{
return track_view_;
}
void TimelineAndTrackView::ViewValueChanged(int v)
{
track_view_->verticalScrollBar()->setValue(v - view_->verticalScrollBar()->minimum());
}
void TimelineAndTrackView::TracksValueChanged(int v)
{
view_->verticalScrollBar()->setValue(view_->verticalScrollBar()->minimum() + v);
}
@@ -27,6 +27,11 @@ private:
TrackView* track_view_;
private slots:
void ViewValueChanged(int v);
void TracksValueChanged(int v);
};
#endif // TIMELINEANDTRACKVIEW_H
@@ -13,6 +13,8 @@ TrackView::TrackView(Qt::Alignment vertical_alignment, QWidget *parent) :
list_(nullptr),
alignment_(vertical_alignment)
{
setAlignment(Qt::AlignLeft | alignment_);
QWidget* central = new QWidget();
setWidget(central);
setWidgetResizable(true);
@@ -31,6 +33,11 @@ TrackView::TrackView(Qt::Alignment vertical_alignment, QWidget *parent) :
splitter_ = new TrackViewSplitter(alignment_);
splitter_->setChildrenCollapsible(false);
layout->addWidget(splitter_);
if (alignment_ == Qt::AlignTop) {
layout->addStretch();
}
connect(splitter_, SIGNAL(TrackHeightChanged(int, int)), this, SLOT(TrackHeightChanged(int, int)));
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -67,6 +74,13 @@ void TrackView::DisconnectTrackList()
ConnectTrackList(nullptr);
}
void TrackView::resizeEvent(QResizeEvent *e)
{
QScrollArea::resizeEvent(e);
splitter_->SetSpacerHeight(height()/2);
}
void TrackView::ScrollbarRangeChanged(int, int max)
{
if (max != last_scrollbar_max_) {
@@ -74,6 +88,7 @@ void TrackView::ScrollbarRangeChanged(int, int max)
int new_val = max - ba_val;
verticalScrollBar()->setValue(new_val);
emit verticalScrollBar()->valueChanged(new_val);
last_scrollbar_max_ = max;
}
@@ -18,6 +18,9 @@ public:
void ConnectTrackList(TrackList* list);
void DisconnectTrackList();
protected:
virtual void resizeEvent(QResizeEvent *e) override;
private:
QList<TrackViewItem*> items_;
@@ -29,8 +32,6 @@ private:
int last_scrollbar_max_;
QWidget* top_spacer_;
private slots:
void ScrollbarRangeChanged(int min, int max);
@@ -3,16 +3,20 @@
#include <QDebug>
#include <QPainter>
#include "node/output/track/track.h"
TrackViewSplitter::TrackViewSplitter(Qt::Alignment vertical_alignment, QWidget* parent) :
QSplitter(Qt::Vertical, parent),
alignment_(vertical_alignment)
alignment_(vertical_alignment),
spacer_height_(0)
{
setHandleWidth(1);
int initial_height = 0;
// Add empty spacer so we get a splitter handle after the last element
addWidget(new QWidget());
QWidget* spacer = new QWidget();
addWidget(spacer);
setFixedHeight(initial_height);
}
@@ -42,18 +46,15 @@ void TrackViewSplitter::HandleReceiver(TrackViewSplitterHandle *h, int diff)
// Transform element size by diff
int new_ele_sz = old_ele_sz + diff;
// Validate it with the widget's minimum size
new_ele_sz = qMax(new_ele_sz, widget(ele_id)->minimumHeight());
// Correct diff
diff = new_ele_sz - old_ele_sz;
SetTrackHeight(ele_id, new_ele_sz);
// Limit by track minimum height
new_ele_sz = qMax(new_ele_sz, TrackOutput::GetTrackHeightMinimum());
if (alignment_ == Qt::AlignBottom) {
ele_id = count() - ele_id - 1;
}
SetTrackHeight(ele_id, new_ele_sz);
emit TrackHeightChanged(ele_id, new_ele_sz);
}
@@ -67,8 +68,6 @@ void TrackViewSplitter::SetTrackHeight(int index, int h)
int old_ele_sz = element_sizes.at(index);
qDebug() << "Old ele sz" << old_ele_sz << "vs h" << h;
int diff = h - old_ele_sz;
// Set new size on element
@@ -79,14 +78,24 @@ void TrackViewSplitter::SetTrackHeight(int index, int h)
setFixedHeight(height() + diff);
}
void TrackViewSplitter::SetHeightWithSizes(const QList<int> &sizes)
void TrackViewSplitter::SetHeightWithSizes(QList<int> sizes)
{
int start_height = 0;
// Add spacer height too
if (alignment_ == Qt::AlignBottom) {
sizes.replace(0, spacer_height_);
} else {
sizes.replace(count() - 1, spacer_height_);
}
foreach (int s, sizes) {
start_height += s + handleWidth();
}
// The spacer doesn't need a handle width
start_height -= handleWidth();
setFixedHeight(start_height);
setSizes(sizes);
}
@@ -119,6 +128,12 @@ void TrackViewSplitter::Remove(int index)
SetHeightWithSizes(sz);
}
void TrackViewSplitter::SetSpacerHeight(int height)
{
spacer_height_ = height;
SetHeightWithSizes(sizes());
}
QSplitterHandle *TrackViewSplitter::createHandle()
{
return new TrackViewSplitterHandle(orientation(), this);
@@ -30,11 +30,13 @@ public:
void HandleReceiver(TrackViewSplitterHandle* h, int diff);
void SetHeightWithSizes(const QList<int>& sizes);
void SetHeightWithSizes(QList<int> sizes);
void Insert(int index, int height, QWidget* item);
void Remove(int index);
void SetSpacerHeight(int height);
public slots:
void SetTrackHeight(int index, int h);
@@ -46,6 +48,9 @@ protected:
private:
Qt::Alignment alignment_;
int spacer_height_;
};
#endif // TRACKVIEWSPLITTER_H
@@ -151,6 +151,34 @@ void TimelineView::dropEvent(QDropEvent *event)
emit DragDropped(&timeline_event);
}
void TimelineView::drawBackground(QPainter *painter, const QRectF &rect)
{
if (!connected_track_list_) {
return;
}
painter->setPen(palette().base().color());
int line_y = 0;
foreach (TrackOutput* track, connected_track_list_->Tracks()) {
line_y += track->GetTrackHeight();
// One px gap between tracks
line_y++;
int this_line_y;
if (alignment() & Qt::AlignTop) {
this_line_y = line_y;
} else {
this_line_y = -line_y;
}
painter->drawLine(qRound(rect.left()), this_line_y, qRound(rect.right()), this_line_y);
}
}
Stream::Type TimelineView::TrackTypeToStreamType(TrackType track_type)
{
switch (track_type) {
@@ -188,10 +216,13 @@ int TimelineView::GetTrackY(int track_index)
for (int i=0;i<track_index;i++) {
y += GetTrackHeight(i);
// One px line between each track
y++;
}
if (alignment() & Qt::AlignBottom) {
y = -y;
y = -y + 1;
}
return y;
@@ -219,7 +250,15 @@ void TimelineView::SetScrollCoordinates(const QPoint &pt)
void TimelineView::ConnectTrackList(TrackList *list)
{
if (connected_track_list_) {
disconnect(connected_track_list_, SIGNAL(TrackHeightChanged(int, int)), viewport(), SLOT(update()));
}
connected_track_list_ = list;
if (connected_track_list_) {
connect(connected_track_list_, SIGNAL(TrackHeightChanged(int, int)), viewport(), SLOT(update()));
}
}
int TimelineView::SceneToTrack(double y)
@@ -83,6 +83,8 @@ protected:
virtual void dragLeaveEvent(QDragLeaveEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
virtual void drawBackground(QPainter *painter, const QRectF &rect) override;
private:
TrackType ConnectedTrackType();
Stream::Type TrackTypeToStreamType(TrackType track_type);
@@ -22,6 +22,8 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) :
// Set default scale
SetScale(1.0);
setViewportUpdateMode(FullViewportUpdate);
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect()));
}
@@ -113,6 +115,13 @@ void TimelineViewBase::UpdateSceneRect()
QRectF bounding_rect = scene_.itemsBoundingRect();
if (limit_y_axis_) {
// Make a gap of half the viewport height
if (alignment() & Qt::AlignBottom) {
bounding_rect.setTop(bounding_rect.top() - height()/2);
} else {
bounding_rect.setBottom(bounding_rect.bottom() + height()/2);
}
// Ensure the scene height is always AT LEAST the height of the view
// The scrollbar appears to have a 1px margin on the top and bottom, hence the -2
int minimum_height = height() - horizontalScrollBar()->height() - 2;
@@ -64,7 +64,7 @@ void TimelineViewBlockItem::UpdateRect()
double item_width = TimeToScene(block_->length());
// -1 on width and height so we don't overlap any adjacent clips
setRect(0, y_, item_width - 1, height_ - 1);
setRect(0, y_, item_width - 1, height_);
setPos(item_left, 0.0);
setToolTip(QCoreApplication::translate("TimelineViewBlockItem",