diff --git a/app/node/output/timeline/timeline.cpp b/app/node/output/timeline/timeline.cpp index 91e4204c0..03603c403 100644 --- a/app/node/output/timeline/timeline.cpp +++ b/app/node/output/timeline/timeline.cpp @@ -46,6 +46,7 @@ TimelineOutput::TimelineOutput() connect(list, SIGNAL(BlockRemoved(Block*)), this, SIGNAL(BlockRemoved(Block*))); connect(list, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(TrackListAddedTrack(TrackOutput*))); connect(list, SIGNAL(TrackRemoved(TrackOutput*)), this, SIGNAL(TrackRemoved(TrackOutput*))); + connect(list, SIGNAL(TrackHeightChanged(int, int)), this, SLOT(TrackHeightChangedSlot(int, int))); } } @@ -196,3 +197,8 @@ void TimelineOutput::TrackListAddedTrack(TrackOutput *track) TrackType type = static_cast(sender())->TrackType(); emit TrackAdded(track, type); } + +void TimelineOutput::TrackHeightChangedSlot(int index, int height) +{ + emit TrackHeightChanged(static_cast(sender())->type(), index, height); +} diff --git a/app/node/output/timeline/timeline.h b/app/node/output/timeline/timeline.h index 4b69397f2..8958fc46f 100644 --- a/app/node/output/timeline/timeline.h +++ b/app/node/output/timeline/timeline.h @@ -70,6 +70,8 @@ signals: void TrackAdded(TrackOutput* track, TrackType type); void TrackRemoved(TrackOutput* track); + void TrackHeightChanged(TrackType type, int index, int height); + protected: virtual NodeValueTable Value(const NodeValueDatabase& value) const override; @@ -93,6 +95,8 @@ private slots: void TrackListAddedTrack(TrackOutput* track); + void TrackHeightChangedSlot(int index, int height); + }; #endif // TIMELINEOUTPUT_H diff --git a/app/node/output/timeline/tracklist.cpp b/app/node/output/timeline/tracklist.cpp index 2dee5c2b7..839b9f2d1 100644 --- a/app/node/output/timeline/tracklist.cpp +++ b/app/node/output/timeline/tracklist.cpp @@ -33,6 +33,11 @@ TrackList::TrackList(TimelineOutput* parent, const enum TrackType &type, NodeInp connect(track_input, SIGNAL(SizeChanged(int)), this, SLOT(TrackListSizeChanged(int))); } +const TrackType &TrackList::type() const +{ + return type_; +} + void TrackList::TrackAddedBlock(Block *block) { emit BlockAdded(block, static_cast(sender())->Index()); @@ -55,12 +60,12 @@ void TrackList::TrackListSizeChanged(int size) } } -const QVector &TrackList::Tracks() +const QVector &TrackList::Tracks() const { return track_cache_; } -TrackOutput *TrackList::TrackAt(int index) +TrackOutput *TrackList::TrackAt(int index) const { if (index < 0 || index >= track_cache_.size()) { return nullptr; @@ -69,16 +74,21 @@ TrackOutput *TrackList::TrackAt(int index) return track_cache_.at(index); } -const rational &TrackList::TrackLength() +const rational &TrackList::TrackLength() const { return total_length_; } -const enum TrackType &TrackList::TrackType() +const enum TrackType &TrackList::TrackType() const { return type_; } +int TrackList::TrackCount() const +{ + return track_cache_.size(); +} + TrackOutput* TrackList::AddTrack() { TrackOutput* track = new TrackOutput(); @@ -104,9 +114,6 @@ TrackOutput* TrackList::AddTrack() }*/ // End test code - // Connect this track to the current last track - NodeParam::ConnectEdge(track->output(), assoc_input); - return track; } @@ -132,13 +139,14 @@ void TrackList::TrackConnected(NodeEdgePtr edge) Node* connected_node = edge->output()->parentNode(); if (connected_node->IsTrack()) { - TrackOutput* connected_track = static_cast(connected_node);// Traverse through Tracks caching and connecting them + TrackOutput* connected_track = static_cast(connected_node); track_cache_.replace(track_index, connected_track); connect(connected_track, SIGNAL(BlockAdded(Block*)), this, SLOT(TrackAddedBlock(Block*))); connect(connected_track, SIGNAL(BlockRemoved(Block*)), this, SLOT(TrackRemovedBlock(Block*))); connect(connected_track, SIGNAL(TrackLengthChanged()), this, SLOT(UpdateTotalLength())); + connect(connected_track, SIGNAL(TrackHeightChanged(int)), this, SLOT(TrackHeightChangedSlot(int))); connected_track->SetIndex(track_index); connected_track->set_track_type(type_); @@ -175,6 +183,7 @@ void TrackList::TrackDisconnected(NodeEdgePtr edge) disconnect(track, SIGNAL(BlockAdded(Block*)), this, SLOT(TrackAddedBlock(Block*))); disconnect(track, SIGNAL(BlockRemoved(Block*)), this, SLOT(TrackRemovedBlock(Block*))); disconnect(track, SIGNAL(TrackLengthChanged()), this, SLOT(UpdateTotalLength())); + disconnect(track, SIGNAL(TrackHeightChanged(int)), this, SLOT(TrackHeightChangedSlot(int))); emit TrackListChanged(); @@ -182,7 +191,7 @@ void TrackList::TrackDisconnected(NodeEdgePtr edge) } } -NodeGraph *TrackList::GetParentGraph() +NodeGraph *TrackList::GetParentGraph() const { return static_cast(parent()->parent()); } @@ -199,3 +208,8 @@ void TrackList::UpdateTotalLength() emit LengthChanged(total_length_); } + +void TrackList::TrackHeightChangedSlot(int height) +{ + emit TrackHeightChanged(static_cast(sender())->Index(), height); +} diff --git a/app/node/output/timeline/tracklist.h b/app/node/output/timeline/tracklist.h index ec3fed10c..1036864cf 100644 --- a/app/node/output/timeline/tracklist.h +++ b/app/node/output/timeline/tracklist.h @@ -34,17 +34,21 @@ class TrackList : public QObject { public: TrackList(TimelineOutput *parent, const enum TrackType& type, NodeInputArray* track_input); - const QVector& Tracks(); + const enum TrackType& type() const; - TrackOutput* TrackAt(int index); + const QVector& Tracks() const; + + TrackOutput* TrackAt(int index) const; TrackOutput *AddTrack(); void RemoveTrack(); - const rational& TrackLength(); + const rational& TrackLength() const; - const enum TrackType& TrackType(); + const enum TrackType& TrackType() const; + + int TrackCount() const; signals: void BlockAdded(Block* block, int index); @@ -59,8 +63,10 @@ signals: void LengthChanged(const rational &length); + void TrackHeightChanged(int index, int height); + private: - NodeGraph* GetParentGraph(); + NodeGraph* GetParentGraph() const; /** * @brief A cache of connected Tracks @@ -104,6 +110,11 @@ private slots: */ void UpdateTotalLength(); + /** + * @brief Slot when a track height changes, transforms to the TrackHeightChanged signal which includes a track index + */ + void TrackHeightChangedSlot(int height); + }; #endif // TRACKLIST_H diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 5c44649ed..f4d50713b 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -20,7 +20,9 @@ #include "track.h" +#include #include +#include #include "node/block/gap/gap.h" #include "node/graph.h" @@ -35,6 +37,9 @@ TrackOutput::TrackOutput() : connect(block_input_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(BlockConnected(NodeEdgePtr))); connect(block_input_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(BlockDisconnected(NodeEdgePtr))); connect(block_input_, SIGNAL(SizeChanged(int)), this, SLOT(BlockListSizeChanged(int))); + + // Set default height + track_height_ = GetDefaultTrackHeight(); } void TrackOutput::set_track_type(const TrackType &track_type) @@ -78,6 +83,26 @@ QString TrackOutput::Description() const "a Sequence."); } +QString TrackOutput::GetTrackName() +{ + if (track_name_.isEmpty()) { + return GetDefaultTrackName(track_type_, index_); + } + + return track_name_; +} + +const int &TrackOutput::GetTrackHeight() const +{ + return track_height_; +} + +void TrackOutput::SetTrackHeight(const int &height) +{ + track_height_ = height; + emit TrackHeightChanged(track_height_); +} + void TrackOutput::Retranslate() { block_input_->set_name(tr("Blocks")); @@ -310,6 +335,33 @@ bool TrackOutput::IsTrack() const return true; } +int TrackOutput::GetDefaultTrackHeight() +{ + return qApp->fontMetrics().height() * 3; +} + +QString TrackOutput::GetDefaultTrackName(TrackType type, int index) +{ + // Starts tracks at 1 rather than 0 + int user_friendly_index = index+1; + + switch (type) { + case kTrackTypeVideo: return tr("Video %1").arg(user_friendly_index); + case kTrackTypeAudio: return tr("Audio %1").arg(user_friendly_index); + case kTrackTypeSubtitle: return tr("Subtitle %1").arg(user_friendly_index); + case kTrackTypeNone: + case kTrackTypeCount: + break; + } + + return tr("Track %1").arg(user_friendly_index); +} + +void TrackOutput::SetTrackName(const QString &name) +{ + track_name_ = name; +} + void TrackOutput::UpdateInOutFrom(int index) { Q_ASSERT(index >= 0); diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index d60e8a02c..b2e94c306 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -45,6 +45,11 @@ public: virtual QString Category() const override; virtual QString Description() const override; + QString GetTrackName(); + + const int& GetTrackHeight() const; + void SetTrackHeight(const int& height); + virtual void Retranslate() override; const int& Index(); @@ -127,6 +132,13 @@ public: virtual bool IsTrack() const override; + static int GetDefaultTrackHeight(); + + static QString GetDefaultTrackName(TrackType type, int index); + +public slots: + void SetTrackName(const QString& name); + signals: /** * @brief Signal emitted when a Block is added to this Track @@ -143,6 +155,11 @@ signals: */ void TrackLengthChanged(); + /** + * @brief Signal emitted when the height of the track has changed + */ + void TrackHeightChanged(int height); + protected: private: @@ -158,6 +175,10 @@ private: rational track_length_; + int track_height_; + + QString track_name_; + int block_invalidate_cache_stack_; int index_; diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index b5cc509ec..c59d4a8f9 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -52,7 +52,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : tools_.fill(nullptr); tools_.replace(olive::tool::kPointer, std::make_shared(this)); - // tools_.replace(olive::tool::kEdit, new PointerTool(this)); FIXME: Implement + // tools_.replace(olive::tool::kEdit, new PointerTool(this)); FIXME: Implement tools_.replace(olive::tool::kRipple, std::make_shared(this)); tools_.replace(olive::tool::kRolling, std::make_shared(this)); tools_.replace(olive::tool::kRazor, std::make_shared(this)); @@ -60,9 +60,9 @@ TimelineWidget::TimelineWidget(QWidget *parent) : tools_.replace(olive::tool::kSlide, std::make_shared(this)); tools_.replace(olive::tool::kHand, std::make_shared(this)); tools_.replace(olive::tool::kZoom, std::make_shared(this)); - //tools_.replace(olive::tool::kTransition, new (this)); FIXME: Implement - //tools_.replace(olive::tool::kRecord, new PointerTool(this)); FIXME: Implement - //tools_.replace(olive::tool::kAdd, new PointerTool(this)); FIXME: Implement + //tools_.replace(olive::tool::kTransition, new (this)); FIXME: Implement + //tools_.replace(olive::tool::kRecord, new PointerTool(this)); FIXME: Implement + //tools_.replace(olive::tool::kAdd, new PointerTool(this)); FIXME: Implement import_tool_ = std::make_shared(this); @@ -178,10 +178,16 @@ void TimelineWidget::ConnectTimelineNode(TimelineOutput *node) disconnect(timeline_node_, SIGNAL(TrackAdded(TrackOutput*, TrackType)), this, SLOT(AddTrack(TrackOutput*, TrackType))); disconnect(timeline_node_, SIGNAL(TrackRemoved(TrackOutput*)), this, SLOT(RemoveTrack(TrackOutput*))); disconnect(timeline_node_, SIGNAL(TimebaseChanged(const rational&)), this, SLOT(SetTimebase(const rational&))); + disconnect(timeline_node_, SIGNAL(TrackHeightChanged(TrackType, int, int)), this, SLOT(TrackHeightChanged(TrackType, int, int))); SetTimebase(0); Clear(); + + for (int i=0;itrack_view(); + track_view->DisconnectTrackList(); + } } timeline_node_ = node; @@ -193,14 +199,18 @@ void TimelineWidget::ConnectTimelineNode(TimelineOutput *node) connect(timeline_node_, SIGNAL(TrackAdded(TrackOutput*, TrackType)), this, SLOT(AddTrack(TrackOutput*, TrackType))); connect(timeline_node_, SIGNAL(TrackRemoved(TrackOutput*)), this, SLOT(RemoveTrack(TrackOutput*))); connect(timeline_node_, SIGNAL(TimebaseChanged(const rational&)), this, SLOT(SetTimebase(const rational&))); + connect(timeline_node_, SIGNAL(TrackHeightChanged(TrackType, int, int)), this, SLOT(TrackHeightChanged(TrackType, int, int))); SetTimebase(timeline_node_->timebase()); for (int i=0;i(i); - TimelineView* view = views_.at(i)->view(); + TrackList* track_list = timeline_node_->track_list(track_type); + TrackView* track_view = views_.at(i)->track_view(); + track_view->ConnectTrackList(track_list); + view->ConnectTrackList(track_list); view->SetEndTime(timeline_node_->timeline_length()); // Defer to the track to make all the block UI items necessary @@ -675,6 +685,24 @@ void TimelineWidget::UpdateTimecodeWidthFromSplitters(QSplitter* s) timecode_label_->setFixedWidth(s->sizes().first() + s->handleWidth()); } +void TimelineWidget::TrackHeightChanged(TrackType type, int index, int height) +{ + Q_UNUSED(index) + Q_UNUSED(height) + + QMap::const_iterator iterator; + TimelineView* view = views_.at(type)->view(); + + for (iterator=block_items_.begin();iterator!=block_items_.end();iterator++) { + TimelineViewBlockItem* block_item = iterator.value(); + + if (block_item->Track().type() == type) { + block_item->SetYCoords(view->GetTrackY(block_item->Track().index()), + view->GetTrackHeight(block_item->Track().index())); + } + } +} + void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost) { ghost->SetScale(scale_); diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 74faebc1e..c9c4e7823 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -379,6 +379,8 @@ private slots: void UpdateTimecodeWidthFromSplitters(QSplitter *s); + void TrackHeightChanged(TrackType type, int index, int height); + }; #endif // TIMELINEWIDGET_H diff --git a/app/widget/timelinewidget/trackview/trackview.cpp b/app/widget/timelinewidget/trackview/trackview.cpp index fed6d7526..94a85b476 100644 --- a/app/widget/timelinewidget/trackview/trackview.cpp +++ b/app/widget/timelinewidget/trackview/trackview.cpp @@ -10,6 +10,7 @@ TrackView::TrackView(Qt::Alignment vertical_alignment, QWidget *parent) : QScrollArea(parent), + list_(nullptr), alignment_(vertical_alignment) { QWidget* central = new QWidget(); @@ -30,13 +31,40 @@ TrackView::TrackView(Qt::Alignment vertical_alignment, QWidget *parent) : splitter_ = new TrackViewSplitter(alignment_); splitter_->setChildrenCollapsible(false); layout->addWidget(splitter_); + connect(splitter_, SIGNAL(TrackHeightChanged(int, int)), this, SLOT(TrackHeightChanged(int, int))); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } -void TrackView::resizeEvent(QResizeEvent *event) +void TrackView::ConnectTrackList(TrackList *list) { - QScrollArea::resizeEvent(event); + if (list_ != nullptr) { + foreach (TrackViewItem* item, items_) { + delete item; + } + items_.clear(); - //splitter_->setFixedWidth(viewport()->width()); + disconnect(list_, SIGNAL(TrackHeightChanged(int, int)), splitter_, SLOT(SetTrackHeight(int, int))); + disconnect(list_, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(InsertTrack(TrackOutput*))); + disconnect(list_, SIGNAL(TrackRemoved(TrackOutput*)), this, SLOT(RemoveTrack(TrackOutput*))); + } + + list_ = list; + + if (list_ != nullptr) { + foreach (TrackOutput* track, list_->Tracks()) { + splitter_->Insert(track->Index(), track->GetTrackHeight(), new TrackViewItem(track->GetTrackName())); + } + + connect(list_, SIGNAL(TrackHeightChanged(int, int)), splitter_, SLOT(SetTrackHeight(int, int))); + connect(list_, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(InsertTrack(TrackOutput*))); + connect(list_, SIGNAL(TrackRemoved(TrackOutput*)), this, SLOT(RemoveTrack(TrackOutput*))); + } +} + +void TrackView::DisconnectTrackList() +{ + ConnectTrackList(nullptr); } void TrackView::ScrollbarRangeChanged(int, int max) @@ -50,3 +78,18 @@ void TrackView::ScrollbarRangeChanged(int, int max) last_scrollbar_max_ = max; } } + +void TrackView::TrackHeightChanged(int index, int height) +{ + list_->TrackAt(index)->SetTrackHeight(height); +} + +void TrackView::InsertTrack(TrackOutput *track) +{ + splitter_->Insert(track->Index(), track->GetTrackHeight(), new TrackViewItem(track->GetTrackName())); +} + +void TrackView::RemoveTrack(TrackOutput *track) +{ + splitter_->Remove(track->Index()); +} diff --git a/app/widget/timelinewidget/trackview/trackview.h b/app/widget/timelinewidget/trackview/trackview.h index e6309ccc9..89b3c75c3 100644 --- a/app/widget/timelinewidget/trackview/trackview.h +++ b/app/widget/timelinewidget/trackview/trackview.h @@ -4,6 +4,8 @@ #include #include +#include "node/output/timeline/tracklist.h" +#include "trackviewitem.h" #include "trackviewsplitter.h" class TrackView : public QScrollArea @@ -13,10 +15,14 @@ public: TrackView(Qt::Alignment vertical_alignment = Qt::AlignTop, QWidget* parent = nullptr); -protected: - virtual void resizeEvent(QResizeEvent* event) override; + void ConnectTrackList(TrackList* list); + void DisconnectTrackList(); private: + QList items_; + + TrackList* list_; + TrackViewSplitter* splitter_; Qt::Alignment alignment_; @@ -28,6 +34,12 @@ private: private slots: void ScrollbarRangeChanged(int min, int max); + void TrackHeightChanged(int index, int height); + + void InsertTrack(TrackOutput* track); + + void RemoveTrack(TrackOutput* track); + }; #endif // TRACKVIEW_H diff --git a/app/widget/timelinewidget/trackview/trackviewitem.cpp b/app/widget/timelinewidget/trackview/trackviewitem.cpp index e61b79201..f20dfb65f 100644 --- a/app/widget/timelinewidget/trackview/trackviewitem.cpp +++ b/app/widget/timelinewidget/trackview/trackviewitem.cpp @@ -6,7 +6,7 @@ #include #include -TrackViewItem::TrackViewItem(Qt::Alignment alignment, QWidget *parent) : +TrackViewItem::TrackViewItem(const QString& name, Qt::Alignment alignment, QWidget *parent) : QWidget(parent), alignment_(alignment) { @@ -14,8 +14,17 @@ TrackViewItem::TrackViewItem(Qt::Alignment alignment, QWidget *parent) : layout->setSpacing(0); layout->setMargin(0); - label_ = new QLabel(tr("Track")); - layout->addWidget(label_); + stack_ = new QStackedWidget(); + layout->addWidget(stack_); + + label_ = new ClickableLabel(name); + connect(label_, SIGNAL(MouseDoubleClicked()), this, SLOT(LabelClicked())); + stack_->addWidget(label_); + + line_edit_ = new FocusableLineEdit(); + connect(line_edit_, SIGNAL(Confirmed()), this, SLOT(LineEditConfirmed())); + connect(line_edit_, SIGNAL(Cancelled()), this, SLOT(LineEditCancelled())); + stack_->addWidget(line_edit_); mute_button_ = CreateMSLButton(tr("M"), Qt::red); layout->addWidget(mute_button_); @@ -42,3 +51,34 @@ QPushButton *TrackViewItem::CreateMSLButton(const QString& text, const QColor& c return button; } + +void TrackViewItem::LabelClicked() +{ + stack_->setCurrentWidget(line_edit_); + line_edit_->setFocus(); + line_edit_->selectAll(); +} + +void TrackViewItem::LineEditConfirmed() +{ + line_edit_->blockSignals(true); + + QString line_edit_str = line_edit_->text(); + if (!line_edit_str.isEmpty()) { + label_->setText(line_edit_str); + emit NameChanged(line_edit_str); + } + + stack_->setCurrentWidget(label_); + + line_edit_->blockSignals(false); +} + +void TrackViewItem::LineEditCancelled() +{ + line_edit_->blockSignals(true); + + stack_->setCurrentWidget(label_); + + line_edit_->blockSignals(false); +} diff --git a/app/widget/timelinewidget/trackview/trackviewitem.h b/app/widget/timelinewidget/trackview/trackviewitem.h index 2d5b6a61f..ccc6bc8a4 100644 --- a/app/widget/timelinewidget/trackview/trackviewitem.h +++ b/app/widget/timelinewidget/trackview/trackviewitem.h @@ -1,28 +1,45 @@ #ifndef TRACKVIEWITEM_H #define TRACKVIEWITEM_H -#include #include +#include #include +#include "widget/clickablelabel/clickablelabel.h" +#include "widget/focusablelineedit/focusablelineedit.h" + class TrackViewItem : public QWidget { Q_OBJECT public: - TrackViewItem(Qt::Alignment alignment = Qt::AlignTop, + TrackViewItem(const QString& name, + Qt::Alignment alignment = Qt::AlignTop, QWidget* parent = nullptr); +signals: + void NameChanged(const QString& name); + private: QPushButton* CreateMSLButton(const QString &text, const QColor &checked_color) const; Qt::Alignment alignment_; - QLabel* label_; + QStackedWidget* stack_; + + ClickableLabel* label_; + FocusableLineEdit* line_edit_; QPushButton* mute_button_; QPushButton* solo_button_; QPushButton* lock_button_; +private slots: + void LabelClicked(); + + void LineEditConfirmed(); + + void LineEditCancelled(); + }; #endif // TRACKVIEWITEM_H diff --git a/app/widget/timelinewidget/trackview/trackviewsplitter.cpp b/app/widget/timelinewidget/trackview/trackviewsplitter.cpp index 1d939c580..5883a07c9 100644 --- a/app/widget/timelinewidget/trackview/trackviewsplitter.cpp +++ b/app/widget/timelinewidget/trackview/trackviewsplitter.cpp @@ -3,8 +3,6 @@ #include #include -#include "trackviewitem.h" - TrackViewSplitter::TrackViewSplitter(Qt::Alignment vertical_alignment, QWidget* parent) : QSplitter(Qt::Vertical, parent), alignment_(vertical_alignment) @@ -13,22 +11,8 @@ TrackViewSplitter::TrackViewSplitter(Qt::Alignment vertical_alignment, QWidget* 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()); - } + // Add empty spacer so we get a splitter handle after the last element + addWidget(new QWidget()); setFixedHeight(initial_height); } @@ -64,14 +48,71 @@ void TrackViewSplitter::HandleReceiver(TrackViewSplitterHandle *h, int diff) // Correct diff diff = new_ele_sz - old_ele_sz; + SetTrackHeight(ele_id, new_ele_sz); + + if (alignment_ == Qt::AlignBottom) { + ele_id = count() - ele_id - 1; + } + + emit TrackHeightChanged(ele_id, new_ele_sz); +} + +void TrackViewSplitter::SetTrackHeight(int index, int h) +{ + QList element_sizes = sizes(); + + int old_ele_sz = element_sizes.at(index); + + int diff = h - old_ele_sz; + // Set new size on element - element_sizes.replace(ele_id, new_ele_sz); + element_sizes.replace(index, h); setSizes(element_sizes); // Increase height by the difference setFixedHeight(height() + diff); } +void TrackViewSplitter::SetHeightWithSizes(const QList &sizes) +{ + int start_height = 0; + + foreach (int s, sizes) { + start_height += s + handleWidth(); + } + + setFixedHeight(start_height); + setSizes(sizes); +} + +void TrackViewSplitter::Insert(int index, int height, QWidget *item) +{ + QList sz = sizes(); + + if (alignment_ == Qt::AlignBottom) { + index = count() - index; + } + + sz.insert(index, height); + insertWidget(index, item); + + SetHeightWithSizes(sz); +} + +void TrackViewSplitter::Remove(int index) +{ + QList sz = sizes(); + + if (alignment_ == Qt::AlignBottom) { + index = count() - index; + } + + sz.removeAt(index); + delete widget(index); + + SetHeightWithSizes(sz); +} + QSplitterHandle *TrackViewSplitter::createHandle() { return new TrackViewSplitterHandle(orientation(), this); diff --git a/app/widget/timelinewidget/trackview/trackviewsplitter.h b/app/widget/timelinewidget/trackview/trackviewsplitter.h index 803d88bda..f6bb30ae8 100644 --- a/app/widget/timelinewidget/trackview/trackviewsplitter.h +++ b/app/widget/timelinewidget/trackview/trackviewsplitter.h @@ -24,11 +24,23 @@ private: class TrackViewSplitter : public QSplitter { + Q_OBJECT public: TrackViewSplitter(Qt::Alignment vertical_alignment, QWidget* parent = nullptr); void HandleReceiver(TrackViewSplitterHandle* h, int diff); + void SetHeightWithSizes(const QList& sizes); + + void Insert(int index, int height, QWidget* item); + void Remove(int index); + +public slots: + void SetTrackHeight(int index, int h); + +signals: + void TrackHeightChanged(int index, int height); + protected: virtual QSplitterHandle *createHandle() override; diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 2e039d0d9..fdef54aef 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -35,6 +35,7 @@ TimelineView::TimelineView(const TrackType &type, Qt::Alignment vertical_alignment, QWidget *parent) : QGraphicsView(parent), + connected_track_list_(nullptr), playhead_(0), type_(type) { @@ -230,12 +231,16 @@ int TimelineView::GetTrackY(int track_index) { int y = 0; + if (alignment() & Qt::AlignBottom) { + track_index++; + } + for (int i=0;i= connected_track_list_->TrackCount()) { + return TrackOutput::GetDefaultTrackHeight(); + } - return fontMetrics().height() * 3; + return connected_track_list_->TrackAt(track_index)->GetTrackHeight(); } QPoint TimelineView::GetScrollCoordinates() @@ -260,6 +266,11 @@ void TimelineView::SetScrollCoordinates(const QPoint &pt) verticalScrollBar()->setValue(pt.y()); } +void TimelineView::ConnectTrackList(TrackList *list) +{ + connected_track_list_ = list; +} + int TimelineView::SceneToTrack(double y) { int track = -1; diff --git a/app/widget/timelinewidget/view/timelineview.h b/app/widget/timelinewidget/view/timelineview.h index 2f334b96f..649508532 100644 --- a/app/widget/timelinewidget/view/timelineview.h +++ b/app/widget/timelinewidget/view/timelineview.h @@ -64,6 +64,8 @@ public: QPoint GetScrollCoordinates(); void SetScrollCoordinates(const QPoint& pt); + void ConnectTrackList(TrackList* list); + public slots: void SetTimebase(const rational& timebase); @@ -110,20 +112,20 @@ private: void UserSetTime(const int64_t& time); + rational GetPlayheadTime(); + + void UpdatePlayheadRect(); + + TrackList* connected_track_list_; + QGraphicsScene scene_; int64_t playhead_; - QVector track_heights_; - TimelineViewEndItem* end_item_; TimelinePlayhead playhead_style_; - rational GetPlayheadTime(); - - void UpdatePlayheadRect(); - QRect playhead_rect_; TrackType type_;