wrangled QWidgets to allow for resizable tracks with track headers
This commit is contained in:
@@ -13,7 +13,7 @@ TimelineAndTrackView::TimelineAndTrackView(const TrackType &type, Qt::Alignment
|
||||
splitter_->setChildrenCollapsible(false);
|
||||
layout->addWidget(splitter_);
|
||||
|
||||
track_view_ = new TrackView();
|
||||
track_view_ = new TrackView(vertical_alignment);
|
||||
splitter_->addWidget(track_view_);
|
||||
|
||||
view_ = new TimelineView(type, vertical_alignment);
|
||||
|
||||
@@ -18,5 +18,9 @@ set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/timelinewidget/trackview/trackview.h
|
||||
widget/timelinewidget/trackview/trackview.cpp
|
||||
widget/timelinewidget/trackview/trackviewitem.h
|
||||
widget/timelinewidget/trackview/trackviewitem.cpp
|
||||
widget/timelinewidget/trackview/trackviewsplitter.h
|
||||
widget/timelinewidget/trackview/trackviewsplitter.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -1,29 +1,52 @@
|
||||
#include "trackview.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QSplitter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
TrackView::TrackView(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
#include "trackviewitem.h"
|
||||
|
||||
TrackView::TrackView(Qt::Alignment vertical_alignment, QWidget *parent) :
|
||||
QScrollArea(parent),
|
||||
alignment_(vertical_alignment)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(0);
|
||||
QWidget* central = new QWidget();
|
||||
setWidget(central);
|
||||
setWidgetResizable(true);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(central);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
QSplitter* splitter = new QSplitter(Qt::Vertical);
|
||||
splitter->setChildrenCollapsible(false);
|
||||
splitter->setHandleWidth(1);
|
||||
layout->addWidget(splitter);
|
||||
if (alignment_ == Qt::AlignBottom) {
|
||||
layout->addStretch();
|
||||
|
||||
QWidget* test1 = new QWidget();
|
||||
test1->setStyleSheet("background: red;");
|
||||
splitter->addWidget(test1);
|
||||
connect(verticalScrollBar(), SIGNAL(rangeChanged(int, int)), this, SLOT(ScrollbarRangeChanged(int, int)));
|
||||
last_scrollbar_max_ = verticalScrollBar()->maximum();
|
||||
}
|
||||
|
||||
QWidget* test3 = new QWidget();
|
||||
test3->setStyleSheet("background: yellow;");
|
||||
splitter->addWidget(test3);
|
||||
splitter_ = new TrackViewSplitter(alignment_);
|
||||
splitter_->setChildrenCollapsible(false);
|
||||
layout->addWidget(splitter_);
|
||||
}
|
||||
|
||||
QWidget* test2 = new QWidget();
|
||||
test2->setStyleSheet("background: blue;");
|
||||
splitter->addWidget(test2);
|
||||
void TrackView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QScrollArea::resizeEvent(event);
|
||||
|
||||
//splitter_->setFixedWidth(viewport()->width());
|
||||
}
|
||||
|
||||
void TrackView::ScrollbarRangeChanged(int, int max)
|
||||
{
|
||||
if (max != last_scrollbar_max_) {
|
||||
int ba_val = last_scrollbar_max_ - verticalScrollBar()->value();
|
||||
int new_val = max - ba_val;
|
||||
|
||||
verticalScrollBar()->setValue(new_val);
|
||||
|
||||
last_scrollbar_max_ = max;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
#ifndef TRACKVIEW_H
|
||||
#define TRACKVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QScrollArea>
|
||||
#include <QSplitter>
|
||||
|
||||
class TrackView : public QWidget
|
||||
#include "trackviewsplitter.h"
|
||||
|
||||
class TrackView : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackView(QWidget* parent = nullptr);
|
||||
TrackView(Qt::Alignment vertical_alignment = Qt::AlignTop,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private:
|
||||
TrackViewSplitter* splitter_;
|
||||
|
||||
Qt::Alignment alignment_;
|
||||
|
||||
int last_scrollbar_max_;
|
||||
|
||||
QWidget* top_spacer_;
|
||||
|
||||
private slots:
|
||||
void ScrollbarRangeChanged(int min, int max);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "trackviewitem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QtMath>
|
||||
|
||||
TrackViewItem::TrackViewItem(Qt::Alignment alignment, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
alignment_(alignment)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
layout->setSpacing(0);
|
||||
layout->setMargin(0);
|
||||
|
||||
label_ = new QLabel(tr("Track"));
|
||||
layout->addWidget(label_);
|
||||
|
||||
mute_button_ = CreateMSLButton(tr("M"), Qt::red);
|
||||
layout->addWidget(mute_button_);
|
||||
|
||||
solo_button_ = CreateMSLButton(tr("S"), Qt::yellow);
|
||||
layout->addWidget(solo_button_);
|
||||
|
||||
lock_button_ = CreateMSLButton(tr("L"), Qt::gray);
|
||||
layout->addWidget(lock_button_);
|
||||
|
||||
setMinimumHeight(mute_button_->height());
|
||||
}
|
||||
|
||||
QPushButton *TrackViewItem::CreateMSLButton(const QString& text, const QColor& checked_color) const
|
||||
{
|
||||
QPushButton* button = new QPushButton(text);
|
||||
button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
button->setCheckable(true);
|
||||
button->setStyleSheet(QStringLiteral("QPushButton::checked { background: %1; }").arg(checked_color.name()));
|
||||
|
||||
int size = button->sizeHint().height();
|
||||
size = qRound(size * 0.75);
|
||||
button->setFixedSize(size, size);
|
||||
|
||||
return button;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef TRACKVIEWITEM_H
|
||||
#define TRACKVIEWITEM_H
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
class TrackViewItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackViewItem(Qt::Alignment alignment = Qt::AlignTop,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QPushButton* CreateMSLButton(const QString &text, const QColor &checked_color) const;
|
||||
|
||||
Qt::Alignment alignment_;
|
||||
|
||||
QLabel* label_;
|
||||
|
||||
QPushButton* mute_button_;
|
||||
QPushButton* solo_button_;
|
||||
QPushButton* lock_button_;
|
||||
|
||||
};
|
||||
|
||||
#endif // TRACKVIEWITEM_H
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "trackviewsplitter.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
|
||||
#include "trackviewitem.h"
|
||||
|
||||
TrackViewSplitter::TrackViewSplitter(Qt::Alignment vertical_alignment, QWidget* parent) :
|
||||
QSplitter(Qt::Vertical, parent),
|
||||
alignment_(vertical_alignment)
|
||||
{
|
||||
setHandleWidth(1);
|
||||
|
||||
int initial_height = 0;
|
||||
|
||||
if (alignment_ == Qt::AlignBottom) {
|
||||
// Add empty spacer so we get a splitter handle after the last element
|
||||
addWidget(new QWidget());
|
||||
}
|
||||
|
||||
for (int i=0;i<3;i++) {
|
||||
TrackViewItem* w = new TrackViewItem();
|
||||
addWidget(w);
|
||||
|
||||
initial_height += w->sizeHint().height() + handleWidth();
|
||||
}
|
||||
|
||||
if (alignment_ == Qt::AlignTop) {
|
||||
// Add empty spacer so we get a splitter handle after the last element
|
||||
addWidget(new QWidget());
|
||||
}
|
||||
|
||||
setFixedHeight(initial_height);
|
||||
}
|
||||
|
||||
void TrackViewSplitter::HandleReceiver(TrackViewSplitterHandle *h, int diff)
|
||||
{
|
||||
int ele_id = -1;
|
||||
|
||||
for (int i=0;i<count();i++) {
|
||||
if (handle(i) == h) {
|
||||
ele_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The handle index is actually always one above the element index
|
||||
if (alignment_ == Qt::AlignTop) {
|
||||
ele_id--;
|
||||
} else if (alignment_ == Qt::AlignBottom) {
|
||||
diff = -diff;
|
||||
}
|
||||
|
||||
QList<int> element_sizes = sizes();
|
||||
|
||||
int old_ele_sz = element_sizes.at(ele_id);
|
||||
|
||||
// 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;
|
||||
|
||||
// Set new size on element
|
||||
element_sizes.replace(ele_id, new_ele_sz);
|
||||
setSizes(element_sizes);
|
||||
|
||||
// Increase height by the difference
|
||||
setFixedHeight(height() + diff);
|
||||
}
|
||||
|
||||
QSplitterHandle *TrackViewSplitter::createHandle()
|
||||
{
|
||||
return new TrackViewSplitterHandle(orientation(), this);
|
||||
}
|
||||
|
||||
TrackViewSplitterHandle::TrackViewSplitterHandle(Qt::Orientation orientation, QSplitter *parent) :
|
||||
QSplitterHandle(orientation, parent),
|
||||
dragging_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void TrackViewSplitterHandle::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
}
|
||||
|
||||
void TrackViewSplitterHandle::mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
if (dragging_) {
|
||||
static_cast<TrackViewSplitter*>(parent())->HandleReceiver(this, QCursor::pos().y() - drag_y_);
|
||||
}
|
||||
|
||||
drag_y_ = QCursor::pos().y();
|
||||
dragging_ = true;
|
||||
}
|
||||
|
||||
void TrackViewSplitterHandle::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
dragging_ = false;
|
||||
}
|
||||
|
||||
void TrackViewSplitterHandle::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(rect(), palette().base());
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef TRACKVIEWSPLITTER_H
|
||||
#define TRACKVIEWSPLITTER_H
|
||||
|
||||
#include <QSplitter>
|
||||
|
||||
class TrackViewSplitterHandle : public QSplitterHandle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackViewSplitterHandle(Qt::Orientation orientation, QSplitter *parent);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *e) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *e) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
int drag_y_;
|
||||
|
||||
bool dragging_;
|
||||
};
|
||||
|
||||
class TrackViewSplitter : public QSplitter
|
||||
{
|
||||
public:
|
||||
TrackViewSplitter(Qt::Alignment vertical_alignment, QWidget* parent = nullptr);
|
||||
|
||||
void HandleReceiver(TrackViewSplitterHandle* h, int diff);
|
||||
|
||||
protected:
|
||||
virtual QSplitterHandle *createHandle() override;
|
||||
|
||||
private:
|
||||
Qt::Alignment alignment_;
|
||||
};
|
||||
|
||||
#endif // TRACKVIEWSPLITTER_H
|
||||
Reference in New Issue
Block a user