began some rewrites to timeline drawing

This commit is contained in:
itsmattkc
2021-01-14 10:30:20 +11:00
parent fbdda3d6d4
commit f7883bd02c
60 changed files with 3134 additions and 951 deletions
@@ -460,13 +460,13 @@ void ProjectExplorer::set_root(Item *item)
tree_view_->setRootIndex(index);
}
QList<Item *> ProjectExplorer::SelectedItems() const
QVector<Item *> ProjectExplorer::SelectedItems() const
{
// Determine which view is active and get its selected indexes
QModelIndexList index_list = CurrentView()->selectionModel()->selectedRows();
// Convert indexes to item objects
QList<Item*> selected_items;
QVector<Item*> selected_items;
for (int i=0;i<index_list.size();i++) {
const QModelIndex& index = index_list.at(i);
@@ -488,7 +488,7 @@ Folder *ProjectExplorer::GetSelectedFolder() const
Folder* folder = nullptr;
// Get the selected items from the panel
QList<Item*> selected_items = SelectedItems();
QVector<Item*> selected_items = SelectedItems();
// Heuristic for finding the selected folder:
//
@@ -565,7 +565,7 @@ QVector<MediaInput *> ProjectExplorer::GetMediaNodesUsingFootage(Footage *item)
void ProjectExplorer::DeleteSelected()
{
QList<Item*> selected = SelectedItems();
QVector<Item*> selected = SelectedItems();
if (selected.isEmpty()) {
return;
+2 -2
View File
@@ -59,7 +59,7 @@ public:
void set_root(Item* item);
QList<Item*> SelectedItems() const;
QVector<Item *> SelectedItems() const;
/**
* @brief Use a heuristic to determine which (if any) folder is selected
@@ -157,7 +157,7 @@ private:
QTimer rename_timer_;
QList<Item*> context_menu_items_;
QVector<Item*> context_menu_items_;
private slots:
void ItemClickedSlot(const QModelIndex& index);
+1 -1
View File
@@ -20,7 +20,7 @@ public:
/**
* @brief Snaps point `start_point` that is moving by `movement` to currently existing clips
*/
virtual bool SnapPoint(QList<rational> start_times, rational *movement, int snap_points = kSnapAll) = 0;
virtual bool SnapPoint(QVector<rational> start_times, rational *movement, int snap_points = kSnapAll) = 0;
virtual void HideSnaps() = 0;
+1 -1
View File
@@ -70,7 +70,7 @@ void TimeBasedView::TimebaseChangedEvent(const rational &)
viewport()->update();
}
void TimeBasedView::EnableSnap(const QList<rational> &points)
void TimeBasedView::EnableSnap(const QVector<rational> &points)
{
snapped_ = true;
snap_time_ = points;
+2 -2
View File
@@ -38,7 +38,7 @@ public:
static const double kMaximumScale;
void EnableSnap(const QList<rational>& points);
void EnableSnap(const QVector<rational> &points);
void DisableSnap();
bool IsSnapped() const
{
@@ -106,7 +106,7 @@ private:
QGraphicsScene scene_;
bool snapped_;
QList<rational> snap_time_;
QVector<rational> snap_time_;
rational end_time_;
+1
View File
@@ -28,6 +28,7 @@
#include "config/config.h"
#include "core.h"
#include "project/item/sequence/sequence.h"
#include "widget/timelinewidget/timelineundo.h"
namespace olive {
+4 -3
View File
@@ -20,12 +20,13 @@ add_subdirectory(view)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/timelinewidget/timelineandtrackview.h
widget/timelinewidget/timelineandtrackview.cpp
widget/timelinewidget/timelineandtrackview.h
widget/timelinewidget/timelineundo.cpp
widget/timelinewidget/timelineundo.h
widget/timelinewidget/timelinewidget.h
widget/timelinewidget/timelinewidget.cpp
widget/timelinewidget/timelinewidgetselections.h
widget/timelinewidget/timelinewidget.h
widget/timelinewidget/timelinewidgetselections.cpp
widget/timelinewidget/timelinewidgetselections.h
PARENT_SCOPE
)
File diff suppressed because it is too large Load Diff
+725
View File
@@ -0,0 +1,725 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2020 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 TIMELINEUNDOABLE_H
#define TIMELINEUNDOABLE_H
#include <QUndoCommand>
#include "node/block/block.h"
#include "node/block/gap/gap.h"
#include "node/block/transition/transition.h"
#include "node/output/track/track.h"
#include "node/output/track/tracklist.h"
#include "timeline/timelinepoints.h"
#include "undo/undocommand.h"
#include "widget/timelinewidget/timelinewidgetselections.h"
namespace olive {
class BlockResizeCommand : public UndoCommand {
public:
BlockResizeCommand(Block* block, rational new_length, QUndoCommand* parent = nullptr) :
UndoCommand(parent),
block_(block),
new_length_(new_length)
{
}
virtual Project* GetRelevantProject() const override
{
return block_->parent()->project();
}
protected:
virtual void redo_internal() override
{
old_length_ = block_->length();
block_->set_length_and_media_out(new_length_);
}
virtual void undo_internal() override
{
block_->set_length_and_media_out(old_length_);
}
private:
Block* block_;
rational old_length_;
rational new_length_;
};
class BlockResizeWithMediaInCommand : public UndoCommand {
public:
BlockResizeWithMediaInCommand(Block* block, rational new_length, QUndoCommand* parent = nullptr) :
UndoCommand(parent),
block_(block),
new_length_(new_length)
{
}
virtual Project* GetRelevantProject() const override
{
return block_->parent()->project();
}
protected:
virtual void redo_internal() override
{
old_length_ = block_->length();
block_->set_length_and_media_in(new_length_);
}
virtual void undo_internal() override
{
block_->set_length_and_media_in(old_length_);
}
private:
Block* block_;
rational old_length_;
rational new_length_;
};
class BlockTrimCommand : public UndoCommand {
public:
BlockTrimCommand(Track *track, Block* block, rational new_length, Timeline::MovementMode mode, QUndoCommand* command = nullptr);
virtual Project* GetRelevantProject() const override;
void SetTrimIsARollEdit(bool e)
{
trim_is_a_roll_edit_ = e;
}
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Track* track_;
Block* block_;
rational old_length_;
rational new_length_;
Timeline::MovementMode mode_;
Block* adjacent_;
bool we_created_adjacent_;
bool we_deleted_adjacent_;
bool trim_is_a_roll_edit_;
QObject memory_manager_;
};
class BlockSetMediaInCommand : public UndoCommand {
public:
BlockSetMediaInCommand(Block* block, rational new_media_in, QUndoCommand* parent = nullptr) :
UndoCommand(parent),
block_(block),
new_media_in_(new_media_in)
{
}
virtual Project* GetRelevantProject() const override
{
return block_->parent()->project();
}
protected:
virtual void redo_internal() override
{
old_media_in_ = block_->media_in();
block_->set_media_in(new_media_in_);
}
virtual void undo_internal() override
{
block_->set_media_in(old_media_in_);
}
private:
Block* block_;
rational old_media_in_;
rational new_media_in_;
};
class TrackRippleRemoveBlockCommand : public UndoCommand {
public:
TrackRippleRemoveBlockCommand(Track* track, Block* block, QUndoCommand* parent = nullptr) :
UndoCommand(parent),
track_(track),
block_(block)
{
}
virtual Project* GetRelevantProject() const override
{
return track_->parent()->project();
}
protected:
virtual void redo_internal() override
{
before_ = block_->previous();
track_->RippleRemoveBlock(block_);
}
virtual void undo_internal() override
{
if (before_) {
track_->InsertBlockAfter(block_, before_);
} else {
track_->PrependBlock(block_);
}
}
private:
Track* track_;
Block* block_;
Block* before_;
};
class TrackPrependBlockCommand : public UndoCommand {
public:
TrackPrependBlockCommand(Track* track, Block* block, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Track* track_;
Block* block_;
};
class TrackInsertBlockAfterCommand : public UndoCommand {
public:
TrackInsertBlockAfterCommand(Track* track, Block* block, Block* before, QUndoCommand* parent = nullptr) :
UndoCommand(parent),
track_(track),
block_(block),
before_(before)
{
}
virtual Project* GetRelevantProject() const override
{
return block_->parent()->project();
}
protected:
virtual void redo_internal() override
{
track_->InsertBlockAfter(block_, before_);
}
virtual void undo_internal() override
{
track_->RippleRemoveBlock(block_);
}
private:
Track* track_;
Block* block_;
Block* before_;
};
/**
* @brief Clears the area between in and out
*
* The area between `in` and `out` is guaranteed to be freed. BLocks are trimmed and removed to free this space.
* By default, nothing takes this area meaning all subsequent clips are pushed backward, however you can specify
* a block to insert at the `in` point. No checking is done to ensure `insert` is the same length as `in` to `out`.
*/
class TrackRippleRemoveAreaCommand : public UndoCommand {
public:
TrackRippleRemoveAreaCommand(Track* track, rational in, rational out, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
void SetInsert(Block* insert);
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
protected:
Project* project_;
Track* track_;
rational in_;
rational out_;
bool splice_;
QUndoCommand* splice_split_command_;
Block* trim_out_;
Block* trim_in_;
QVector<Block*> removed_blocks_;
rational trim_in_old_length_;
rational trim_out_old_length_;
rational trim_in_new_length_;
rational trim_out_new_length_;
Block* insert_;
QObject memory_manager_;
QVector<QUndoCommand*> remove_block_commands_;
};
class TrackListRippleRemoveAreaCommand : public UndoCommand {
public:
TrackListRippleRemoveAreaCommand(TrackList* list, rational in, rational out, QUndoCommand* parent = nullptr);
virtual ~TrackListRippleRemoveAreaCommand() override;
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
TrackList* list_;
QList<Track*> working_tracks_;
rational in_;
rational out_;
bool all_tracks_unlocked_;
QVector<TrackRippleRemoveAreaCommand*> commands_;
};
class TimelineRippleRemoveAreaCommand : public UndoCommand {
public:
TimelineRippleRemoveAreaCommand(ViewerOutput* timeline, rational in, rational out, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
private:
ViewerOutput* timeline_;
};
class TrackListRippleToolCommand : public UndoCommand {
public:
struct RippleInfo {
Block* block;
Block* ref_block;
Track* track;
rational new_length;
rational old_length;
};
TrackListRippleToolCommand(TrackList* track_list,
const QList<RippleInfo>& info,
const Timeline::MovementMode& movement_mode,
QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
TrackList* track_list_;
QList<RippleInfo> info_;
Timeline::MovementMode movement_mode_;
struct WorkingData {
GapBlock* created_gap;
Block* removed_gap_after;
};
QVector<WorkingData> working_data_;
QObject memory_manager_;
bool all_tracks_unlocked_;
};
/**
* @brief Destructively places `block` at the in point `start`
*
* The Block is guaranteed to be placed at the starting point specified. If there are Blocks in this area, they are
* either trimmed or removed to make space for this Block. Additionally, if the Block is placed beyond the end of
* the Sequence, a GapBlock is inserted to compensate.
*/
class TrackPlaceBlockCommand : public TrackRippleRemoveAreaCommand {
public:
TrackPlaceBlockCommand(TrackList *timeline, int track, Block* block, rational in, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
TrackList* timeline_;
int track_index_;
bool append_;
GapBlock* gap_;
QVector<Track*> added_tracks_;
};
class BlockSplitCommand : public UndoCommand {
public:
BlockSplitCommand(Track* track, Block* block, rational point, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
Block* new_block();
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Track* track_;
Block* block_;
Block* new_block_;
rational new_length_;
rational old_length_;
rational point_;
QList<NodeInput*> transitions_to_move_;
QObject memory_manager_;
QUndoCommand* add_command_;
};
class TrackSplitAtTimeCommand : public UndoCommand {
public:
TrackSplitAtTimeCommand(Track* track, rational point, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
private:
Track* track_;
};
class BlockSplitPreservingLinksCommand : public UndoCommand {
public:
BlockSplitPreservingLinksCommand(const QVector<Block *> &blocks, const QList<rational>& times, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
private:
QVector<Block *> blocks_;
QList<rational> times_;
};
/**
* @brief Replaces Block `old` with Block `replace`
*
* Both blocks must have equal lengths.
*/
class TrackReplaceBlockCommand : public UndoCommand {
public:
TrackReplaceBlockCommand(Track* track, Block* old, Block* replace, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Track* track_;
Block* old_;
Block* replace_;
};
class TrackReplaceBlockWithGapCommand : public UndoCommand {
public:
TrackReplaceBlockWithGapCommand(Track* track, Block* block, QUndoCommand* command = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Track* track_;
Block* block_;
GapBlock* existing_gap_;
GapBlock* existing_merged_gap_;
bool existing_gap_precedes_;
GapBlock* our_gap_;
QObject memory_manager_;
};
class TimelineRippleDeleteGapsAtRegionsCommand : public UndoCommand {
public:
TimelineRippleDeleteGapsAtRegionsCommand(ViewerOutput* vo, const TimeRangeList& regions, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
ViewerOutput* timeline_;
TimeRangeList regions_;
QList<UndoCommand*> commands_;
};
class WorkareaSetEnabledCommand : public UndoCommand {
public:
WorkareaSetEnabledCommand(Project *project, TimelinePoints* points, bool enabled, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Project* project_;
TimelinePoints* points_;
bool old_enabled_;
bool new_enabled_;
};
class WorkareaSetRangeCommand : public UndoCommand {
public:
WorkareaSetRangeCommand(Project *project, TimelinePoints* points, const TimeRange& range, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Project* project_;
TimelinePoints* points_;
TimeRange old_range_;
TimeRange new_range_;
};
class BlockLinkManyCommand : public UndoCommand {
public:
BlockLinkManyCommand(const QVector<Block*> blocks, bool link, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
private:
QVector<Block*> blocks_;
};
class BlockLinkCommand : public UndoCommand {
public:
BlockLinkCommand(Block* a, Block* b, bool link, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Block* a_;
Block* b_;
bool link_;
bool done_;
};
class BlockUnlinkAllCommand : public UndoCommand {
public:
BlockUnlinkAllCommand(Block* block, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Block* block_;
QVector<Block*> unlinked_;
};
class BlockEnableDisableCommand : public UndoCommand {
public:
BlockEnableDisableCommand(Block* block, bool enabled, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Block* block_;
bool old_enabled_;
bool new_enabled_;
};
class TrackSlideCommand : public UndoCommand {
public:
TrackSlideCommand(Track* track, const QList<Block*>& moving_blocks, Block* in_adjacent, Block* out_adjacent, const rational& movement, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
void slide_internal(bool undo);
Track* track_;
QList<Block*> blocks_;
rational movement_;
bool we_created_in_adjacent_;
Block* in_adjacent_;
bool we_created_out_adjacent_;
Block* out_adjacent_;
QObject memory_manager_;
};
class TrackListInsertGaps : public UndoCommand {
public:
TrackListInsertGaps(TrackList* track_list, const rational& point, const rational& length, QUndoCommand* parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
TrackList* track_list_;
rational point_;
rational length_;
QList<Track*> working_tracks_;
bool all_tracks_unlocked_;
QList<Block*> gaps_to_extend_;
QList<GapBlock*> gaps_added_;
BlockSplitPreservingLinksCommand* split_command_;
QObject memory_manager_;
};
class TransitionRemoveCommand : public UndoCommand {
public:
TransitionRemoveCommand(Track *track, TransitionBlock* block, QUndoCommand *parent = nullptr);
virtual Project* GetRelevantProject() const override;
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
Track* track_;
TransitionBlock* block_;
Block* out_block_;
Block* in_block_;
};
class TimelineWidget;
class TimelineSetSelectionsCommand : public QUndoCommand {
public:
TimelineSetSelectionsCommand(TimelineWidget* timeline, const TimelineWidgetSelections& now, const TimelineWidgetSelections& old, QUndoCommand* parent = nullptr);
protected:
virtual void redo() override;
virtual void undo() override;
private:
TimelineWidget* timeline_;
TimelineWidgetSelections old_;
TimelineWidgetSelections now_;
};
}
#endif // TIMELINEUNDOABLE_H
+158 -244
View File
@@ -220,12 +220,9 @@ void TimelineWidget::ScaleChangedEvent(const double &scale)
void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
{
connect(n, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock);
connect(n, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock);
connect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
connect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
connect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
connect(n, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged);
ruler()->SetPlaybackCache(n->video_frame_cache());
@@ -241,20 +238,18 @@ void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
view->ConnectTrackList(track_list);
// Defer to the track to make all the block UI items necessary
foreach (Track* track, n->track_list(track_type)->GetTracks()) {
AddTrack(track, track_type);
const QVector<Track*> tracks = n->track_list(track_type)->GetTracks();
foreach (Track* track, tracks) {
AddTrack(track);
}
}
}
void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
{
disconnect(n, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock);
disconnect(n, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock);
disconnect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
disconnect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
disconnect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
disconnect(n, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged);
DeselectAll();
@@ -280,9 +275,7 @@ void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void
QVector<Block*>& selected = *static_cast<QVector<Block*>*>(userdata);
rational earliest_in = RATIONAL_MAX;
foreach (Block* item, selected) {
Block* block = item->block();
foreach (Block* block, selected) {
earliest_in = qMin(earliest_in, block->in());
}
@@ -292,12 +285,9 @@ void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(block)));
writer->writeAttribute(QStringLiteral("in"), (block->in() - earliest_in).toString());
Track* track = GetTrackFromBlock(block);
if (track) {
writer->writeAttribute(QStringLiteral("tracktype"), QString::number(track->track_type()));
writer->writeAttribute(QStringLiteral("trackindex"), QString::number(track->Index()));
}
Track* track = block->track();
writer->writeAttribute(QStringLiteral("tracktype"), QString::number(track->type()));
writer->writeAttribute(QStringLiteral("trackindex"), QString::number(track->Index()));
writer->writeEndElement();
}
@@ -334,10 +324,10 @@ void TimelineWidget::SelectAll()
{
QVector<Block*> newly_selected_blocks;
for (auto it=block_items_.cbegin(); it!=block_items_.cend(); it++) {
if (!selected_blocks_.contains(it.key())) {
newly_selected_blocks.append(it.key());
AddSelection(it.key()->range(), it.value()->Track());
foreach (Block* block, added_blocks_) {
if (!selected_blocks_.contains(block)) {
newly_selected_blocks.append(block);
AddSelection(block);
}
}
@@ -384,7 +374,7 @@ void TimelineWidget::SplitAtPlayhead()
rational playhead_time = Timecode::timestamp_to_time(GetTimestamp(), timebase());
QVector<TimelineViewBlockItem *> selected_blocks = GetSelectedBlocks();
QVector<Block*> selected_blocks = GetSelectedBlocks();
// Prioritize blocks that are selected and overlap the playhead
QVector<Block*> blocks_to_split;
@@ -400,8 +390,8 @@ void TimelineWidget::SplitAtPlayhead()
bool selected = false;
// See if this block is selected
foreach (TimelineViewBlockItem* item, selected_blocks) {
if (item->block() == b) {
foreach (Block* item, selected_blocks) {
if (item == b) {
some_blocks_are_selected = true;
selected = true;
break;
@@ -430,8 +420,8 @@ void TimelineWidget::SplitAtPlayhead()
}
void TimelineWidget::ReplaceBlocksWithGaps(const QVector<Block *> &blocks,
bool remove_from_graph,
QUndoCommand *command)
bool remove_from_graph,
QUndoCommand *command)
{
foreach (Block* b, blocks) {
if (b->type() == Block::kGap) {
@@ -440,7 +430,7 @@ void TimelineWidget::ReplaceBlocksWithGaps(const QVector<Block *> &blocks,
continue;
}
Track* original_track = Track::TrackFromBlock(b);
Track* original_track = b->track();
new TrackReplaceBlockWithGapCommand(original_track, b, command);
@@ -452,12 +442,10 @@ void TimelineWidget::ReplaceBlocksWithGaps(const QVector<Block *> &blocks,
void TimelineWidget::DeleteSelected(bool ripple)
{
QVector<TimelineViewBlockItem *> selected_list = GetSelectedBlocks();
QVector<Block*> selected_list = GetSelectedBlocks();
QVector<Block*> blocks_to_delete;
foreach (TimelineViewBlockItem* item, selected_list) {
Block* b = item->block();
foreach (Block* b, selected_list) {
blocks_to_delete.append(b);
}
@@ -481,7 +469,7 @@ void TimelineWidget::DeleteSelected(bool ripple)
// For transitions, remove them but extend their attached blocks to fill their place
foreach (TransitionBlock* transition, transitions_to_delete) {
new TransitionRemoveCommand(Track::TrackFromBlock(transition),
new TransitionRemoveCommand(transition->track(),
transition,
command);
@@ -536,35 +524,35 @@ void TimelineWidget::DecreaseTrackHeight()
}
}
void TimelineWidget::InsertFootageAtPlayhead(const QList<Footage*>& footage)
void TimelineWidget::InsertFootageAtPlayhead(const QVector<Footage*>& footage)
{
import_tool_->PlaceAt(footage, GetTime(), true);
}
void TimelineWidget::OverwriteFootageAtPlayhead(const QList<Footage *> &footage)
void TimelineWidget::OverwriteFootageAtPlayhead(const QVector<Footage *> &footage)
{
import_tool_->PlaceAt(footage, GetTime(), false);
}
void TimelineWidget::ToggleLinksOnSelected()
{
QVector<TimelineViewBlockItem*> sel = GetSelectedBlocks();
QVector<Block*> sel = GetSelectedBlocks();
QVector<Block*> blocks;
bool link = true;
foreach (TimelineViewBlockItem* item, sel) {
foreach (Block* item, sel) {
// Only clips can be linked
if (item->block()->type() != Block::kClip) {
if (item->type() != Block::kClip) {
continue;
}
// Prioritize unlinking, if any block has links, assume we're unlinking
if (link && item->block()->HasLinks()) {
if (link && item->HasLinks()) {
link = false;
}
blocks.append(item->block());
blocks.append(item);
}
if (blocks.isEmpty()) {
@@ -580,7 +568,7 @@ void TimelineWidget::CopySelected(bool cut)
return;
}
QVector<TimelineViewBlockItem*> selected = GetSelectedBlocks();
QVector<Block*> selected = GetSelectedBlocks();
if (selected.isEmpty()) {
return;
@@ -588,9 +576,7 @@ void TimelineWidget::CopySelected(bool cut)
QVector<Node*> selected_nodes;
foreach (TimelineViewBlockItem* item, selected) {
Node* block = item->block();
foreach (Block* block, selected) {
selected_nodes.append(block);
QVector<Node*> deps = block->GetDependencies();
@@ -675,7 +661,7 @@ void TimelineWidget::DeleteInToOut(bool ripple)
gap,
command);
new TrackPlaceBlockCommand(GetConnectedNode()->track_list(track->track_type()),
new TrackPlaceBlockCommand(GetConnectedNode()->track_list(track->type()),
track->Index(),
gap,
GetConnectedTimelinePoints()->workarea()->in(),
@@ -699,7 +685,7 @@ void TimelineWidget::DeleteInToOut(bool ripple)
void TimelineWidget::ToggleSelectedEnabled()
{
QVector<TimelineViewBlockItem*> items = GetSelectedBlocks();
QVector<Block*> items = GetSelectedBlocks();
if (items.isEmpty()) {
return;
@@ -707,29 +693,18 @@ void TimelineWidget::ToggleSelectedEnabled()
QUndoCommand* command = new QUndoCommand();
foreach (TimelineViewBlockItem* i, items) {
new BlockEnableDisableCommand(i->block(),
!i->block()->is_enabled(),
foreach (Block* i, items) {
new BlockEnableDisableCommand(i,
!i->is_enabled(),
command);
}
Core::instance()->undo_stack()->pushIfHasChildren(command);
}
QVector<Block *> TimelineWidget::GetSelectedBlocks()
{
QVector<Block*> list(selected_blocks_.size());
for (int i=0; i<selected_blocks_.size(); i++) {
list[i] = block_items_.value(selected_blocks_.at(i));
}
return list;
}
void TimelineWidget::InsertGapsAt(const rational &earliest_point, const rational &insert_length, QUndoCommand *command)
{
for (int i=0;i<Timeline::kTrackTypeCount;i++) {
for (int i=0;i<Track::kCount;i++) {
new TrackListInsertGaps(GetConnectedNode()->track_list(static_cast<Track::Type>(i)),
earliest_point,
insert_length,
@@ -737,17 +712,17 @@ void TimelineWidget::InsertGapsAt(const rational &earliest_point, const rational
}
}
Track *TimelineWidget::GetTrackFromReference(const TrackReference &ref) const
Track *TimelineWidget::GetTrackFromReference(const Track::Reference &ref) const
{
return GetConnectedNode()->track_list(ref.type())->GetTrackAt(ref.index());
}
int TimelineWidget::GetTrackY(const TrackReference &ref)
int TimelineWidget::GetTrackY(const Track::Reference &ref)
{
return views_.at(ref.type())->view()->GetTrackY(ref.index());
}
int TimelineWidget::GetTrackHeight(const TrackReference &ref)
int TimelineWidget::GetTrackHeight(const Track::Reference &ref)
{
return views_.at(ref.type())->view()->GetTrackHeight(ref.index());
}
@@ -804,7 +779,6 @@ void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event)
if (hover_tool) {
hover_tool->HoverMove(event);
UpdateViewports();
}
}
}
@@ -851,35 +825,15 @@ void TimelineWidget::ViewDragDropped(TimelineViewMouseEvent *event)
UpdateViewports();
}
void TimelineWidget::AddBlock(Block *block, TrackReference track)
void TimelineWidget::AddBlock(Block *block)
{
// Set up clip with view parameters (clip item will automatically size its rect accordingly)
TimelineViewBlockItem* item = block_items_.value(block);
if (!item) {
// Add to list of clip items that can be iterated through
item = new TimelineViewBlockItem(block);
block_items_.insert(block, item);
// Set scale parameters
item->SetScale(GetScale());
item->SetTimebase(timebase());
item->SetYCoords(GetTrackY(track), GetTrackHeight(track));
item->SetTrack(track);
// Add item to graphics scene
views_.at(track.type())->view()->scene()->addItem(item);
if (!added_blocks_.contains(block)) {
connect(block, &Block::LinksChanged, this, &TimelineWidget::BlockUpdated);
connect(block, &Block::LabelChanged, this, &TimelineWidget::BlockUpdated);
connect(block, &Block::EnabledChanged, this, &TimelineWidget::BlockUpdated);
} else if (item->Track() != track) {
item->SetYCoords(GetTrackY(track), GetTrackHeight(track));
item->SetTrack(track);
added_blocks_.append(block);
}
}
@@ -891,84 +845,54 @@ void TimelineWidget::RemoveBlock(Block *b)
disconnect(b, &Block::EnabledChanged, this, &TimelineWidget::BlockUpdated);
// Take item from map
TimelineViewBlockItem* item = block_items_.take(b);
added_blocks_.removeOne(b);
// If selected, deselect it
int select_index = selected_blocks_.indexOf(b);
if (select_index > -1) {
selected_blocks_.removeAt(select_index);
RemoveSelection(item);
RemoveSelection(b);
emit BlocksDeselected({b});
}
// Finally, delete item
delete item;
emit BlocksDeselected({b});
}
void TimelineWidget::AddTrack(Track *track, Track::Type type)
void TimelineWidget::AddTrack(Track *track)
{
foreach (Block* b, track->Blocks()) {
AddBlock(b, TrackReference(type, track->Index()));
AddBlock(b);
}
connect(track, &Track::IndexChanged, this, &TimelineWidget::TrackIndexChanged);
connect(track, &Track::PreviewChanged, this, &TimelineWidget::TrackPreviewUpdated);
connect(track, &Track::IndexChanged, this, &TimelineWidget::TrackUpdated);
connect(track, &Track::PreviewChanged, this, &TimelineWidget::TrackUpdated);
connect(track, &Track::BlocksRefreshed, this, &TimelineWidget::TrackUpdated);
connect(track, &Track::TrackHeightChangedInPixels, this, &TimelineWidget::TrackUpdated);
connect(track, &Track::BlockAdded, this, &TimelineWidget::AddBlock);
connect(track, &Track::BlockRemoved, this, &TimelineWidget::RemoveBlock);
}
void TimelineWidget::RemoveTrack(Track *track)
{
disconnect(track, &Track::IndexChanged, this, &TimelineWidget::TrackIndexChanged);
disconnect(track, &Track::PreviewChanged, this, &TimelineWidget::TrackPreviewUpdated);
disconnect(track, &Track::IndexChanged, this, &TimelineWidget::TrackUpdated);
disconnect(track, &Track::PreviewChanged, this, &TimelineWidget::TrackUpdated);
disconnect(track, &Track::BlocksRefreshed, this, &TimelineWidget::TrackUpdated);
disconnect(track, &Track::TrackHeightChangedInPixels, this, &TimelineWidget::TrackUpdated);
disconnect(track, &Track::BlockAdded, this, &TimelineWidget::AddBlock);
disconnect(track, &Track::BlockRemoved, this, &TimelineWidget::RemoveBlock);
foreach (Block* b, track->Blocks()) {
RemoveBlock(b);
}
}
void TimelineWidget::TrackIndexChanged()
void TimelineWidget::TrackUpdated()
{
Track* track = static_cast<Track*>(sender());
TrackReference ref(track->track_type(), track->Index());
foreach (Block* b, track->Blocks()) {
TimelineViewBlockItem* item = block_items_.value(b);
item->SetYCoords(GetTrackY(ref), GetTrackHeight(ref));
item->SetTrack(ref);
}
}
void TimelineWidget::BlockRefreshed()
{
TimelineViewRect* rect = block_items_.value(static_cast<Block*>(sender()));
if (rect) {
rect->UpdateRect();
}
UpdateViewports(static_cast<Track*>(sender())->type());
}
void TimelineWidget::BlockUpdated()
{
TimelineViewRect* rect = block_items_.value(static_cast<Block*>(sender()));
if (rect) {
rect->update();
}
}
void TimelineWidget::TrackPreviewUpdated()
{
QMap<Block*, TimelineViewBlockItem*>::const_iterator i;
Track* track = static_cast<Track*>(sender());
TrackReference track_ref(track->track_type(), track->Index());
for (i=block_items_.constBegin(); i!=block_items_.constEnd(); i++) {
if (i.value()->Track() == track_ref) {
i.value()->update();
}
}
UpdateViewports(static_cast<Block*>(sender())->track()->type());
}
void TimelineWidget::UpdateHorizontalSplitters()
@@ -993,29 +917,11 @@ void TimelineWidget::UpdateTimecodeWidthFromSplitters(QSplitter* s)
timecode_label_->setFixedWidth(s->sizes().first() + s->handleWidth());
}
void TimelineWidget::TrackHeightChanged(Track::Type type, int index, int height)
{
Q_UNUSED(index)
Q_UNUSED(height)
QMap<Block*, TimelineViewBlockItem*>::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::ShowContextMenu()
{
Menu menu(this);
QVector<TimelineViewBlockItem*> selected = GetSelectedBlocks();
QVector<Block*> selected = GetSelectedBlocks();
if (!selected.isEmpty()) {
MenuShared::instance()->AddItemsForEditMenu(&menu, true);
@@ -1024,11 +930,11 @@ void TimelineWidget::ShowContextMenu()
QAction* properties_action = menu.addAction(tr("Properties"));
connect(properties_action, &QAction::triggered, this, [this](){
QVector<TimelineViewBlockItem*> block_items = GetSelectedBlocks();
QVector<Block*> block_items = GetSelectedBlocks();
QVector<Node*> nodes;
foreach (TimelineViewBlockItem* i, block_items) {
nodes.append(i->block());
foreach (Block* i, block_items) {
nodes.append(i);
}
Core::instance()->LabelNodes(nodes);
@@ -1082,7 +988,7 @@ void TimelineWidget::SetViewTimestamp(const int64_t &ts)
for (int i=0;i<views_.size();i++) {
TimelineAndTrackView* view = views_.at(i);
if (use_audio_time_units_ && i == Timeline::kTrackTypeAudio) {
if (use_audio_time_units_ && i == Track::kAudio) {
view->view()->SetTime(Timecode::rescale_timestamp(ts,
timebase(),
GetConnectedNode()->audio_params().time_base()));
@@ -1094,7 +1000,7 @@ void TimelineWidget::SetViewTimestamp(const int64_t &ts)
void TimelineWidget::ViewTimestampChanged(int64_t ts)
{
if (use_audio_time_units_ && sender() == views_.at(Timeline::kTrackTypeAudio)) {
if (use_audio_time_units_ && sender() == views_.at(Track::kAudio)) {
ts = Timecode::rescale_timestamp(ts,
GetConnectedNode()->audio_params().time_base(),
timebase());
@@ -1124,7 +1030,7 @@ void TimelineWidget::UpdateViewTimebases()
for (int i=0;i<views_.size();i++) {
TimelineAndTrackView* view = views_.at(i);
if (use_audio_time_units_ && i == Timeline::kTrackTypeAudio) {
if (use_audio_time_units_ && i == Track::kAudio) {
view->view()->SetTimebase(GetConnectedNode()->audio_params().time_base());
} else {
view->view()->SetTimebase(timebase());
@@ -1141,17 +1047,11 @@ void TimelineWidget::SetViewBeamCursor(const TimelineCoordinate &coord)
void TimelineWidget::SetBlockLinksSelected(Block* block, bool selected)
{
TimelineViewBlockItem* link_item;
foreach (Block* link, block->linked_clips()) {
link_item = block_items_.value(link);
if (link_item) {
if (selected) {
AddSelection(link_item);
} else {
RemoveSelection(link_item);
}
if (selected) {
AddSelection(link);
} else {
RemoveSelection(link);
}
}
}
@@ -1357,7 +1257,7 @@ void TimelineWidget::EditTo(Timeline::MovementMode mode)
Core::instance()->undo_stack()->pushIfHasChildren(command);
}
void TimelineWidget::ShowSnap(const QList<rational> &times)
void TimelineWidget::ShowSnap(const QVector<rational> &times)
{
foreach (TimelineAndTrackView* tview, views_) {
tview->view()->EnableSnap(times);
@@ -1366,7 +1266,7 @@ void TimelineWidget::ShowSnap(const QList<rational> &times)
void TimelineWidget::UpdateViewports(const Track::Type &type)
{
if (type == Timeline::kTrackTypeNone) {
if (type == Track::kNone) {
foreach (TimelineAndTrackView* tview, views_) {
tview->view()->viewport()->update();
}
@@ -1375,6 +1275,46 @@ void TimelineWidget::UpdateViewports(const Track::Type &type)
}
}
QVector<Block *> TimelineWidget::GetBlocksInGlobalRect(const QPoint &p1, const QPoint& p2)
{
QVector<Block*> blocks_in_rect;
// Determine which tracks are in the rect
for (int i=0; i<views_.size(); i++) {
TimelineView* view = views_.at(i)->view();
// Map global mouse coordinates to viewport
QRectF mapped_rect(view->mapToScene(view->viewport()->mapFromGlobal(p1)),
view->mapToScene(view->viewport()->mapFromGlobal(p2)));
// Normalize
mapped_rect = mapped_rect.normalized();
// Get tracks
TrackList* track_list = GetConnectedNode()->track_list(static_cast<Track::Type>(i));
for (int j=0; j<track_list->GetTrackCount(); j++) {
int track_top = view->GetTrackY(j);
int track_bottom = track_top + view->GetTrackHeight(j);
if (!(track_bottom < mapped_rect.top() || track_top > mapped_rect.bottom())) {
// This track is in the rect, so we'll iterate through its blocks and see where they start
rational left_time = SceneToTime(mapped_rect.left());
rational right_time = SceneToTime(mapped_rect.right(), true);
Track* track = track_list->GetTrackAt(j);
foreach (Block* b, track->Blocks()) {
if (!(b->out() < left_time || b->in() > right_time)) {
blocks_in_rect.append(b);
}
}
}
}
}
return blocks_in_rect;
}
void TimelineWidget::HideSnaps()
{
foreach (TimelineAndTrackView* tview, views_) {
@@ -1417,21 +1357,8 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
return;
}
QList<QGraphicsItem*> items_in_rubberband;
// Determine all items in the rubberband
foreach (TimelineAndTrackView* tview, views_) {
TimelineView* view = tview->view();
// Map global mouse coordinates to viewport
QRect mapped_rect(view->viewport()->mapFromGlobal(drag_origin_),
view->viewport()->mapFromGlobal(rubberband_now));
// Normalize and get items in rect
QList<QGraphicsItem*> rubberband_items = view->items(mapped_rect.normalized());
items_in_rubberband.append(rubberband_items);
}
// Get current items in rubberband
QVector<Block*> items_in_rubberband = GetBlocksInGlobalRect(drag_origin_, rubberband_now);
// Reset selection to whatever it was before
SetSelections(rubberband_old_selections_);
@@ -1439,32 +1366,26 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
// Add any blocks in rubberband
rubberband_now_selected_.clear();
foreach (QGraphicsItem* item, items_in_rubberband) {
TimelineViewBlockItem* block_item = dynamic_cast<TimelineViewBlockItem*>(item);
foreach (Block* b, items_in_rubberband) {
if (b->type() == Block::kGap) {
continue;
}
if (block_item) {
Block* b = block_item->block();
Track* t = b->track();
if (t->IsLocked()) {
continue;
}
if (b->type() == Block::kGap) {
continue;
}
if (!rubberband_now_selected_.contains(b)) {
AddSelection(b);
rubberband_now_selected_.append(b);
}
Track* t = GetTrackFromReference(block_item->Track());
if (t && t->IsLocked()) {
continue;
}
if (!rubberband_now_selected_.contains(b)) {
AddSelection(block_item);
rubberband_now_selected_.append(b);
}
if (select_links) {
foreach (Block* link, b->linked_clips()) {
if (!rubberband_now_selected_.contains(link)) {
AddSelection(block_items_.value(link));
rubberband_now_selected_.append(link);
}
if (select_links) {
foreach (Block* link, b->linked_clips()) {
if (!rubberband_now_selected_.contains(link)) {
AddSelection(link);
rubberband_now_selected_.append(link);
}
}
}
@@ -1482,7 +1403,7 @@ void TimelineWidget::EndRubberBandSelect()
rubberband_old_selections_.clear();
}
void TimelineWidget::AddSelection(const TimeRange &time, const TrackReference &track)
void TimelineWidget::AddSelection(const TimeRange &time, const Track::Reference &track)
{
selections_[track].insert(time);
@@ -1491,10 +1412,10 @@ void TimelineWidget::AddSelection(const TimeRange &time, const TrackReference &t
void TimelineWidget::AddSelection(Block *item)
{
AddSelection(item->block()->range(), item->Track());
AddSelection(item->range(), item->track()->ToReference());
}
void TimelineWidget::RemoveSelection(const TimeRange &time, const TrackReference &track)
void TimelineWidget::RemoveSelection(const TimeRange &time, const Track::Reference &track)
{
selections_[track].remove(time);
@@ -1503,7 +1424,7 @@ void TimelineWidget::RemoveSelection(const TimeRange &time, const TrackReference
void TimelineWidget::RemoveSelection(Block *item)
{
RemoveSelection(item->block()->range(), item->Track());
RemoveSelection(item->range(), item->track()->ToReference());
}
void TimelineWidget::SetSelections(const TimelineWidgetSelections &s)
@@ -1515,14 +1436,13 @@ void TimelineWidget::SetSelections(const TimelineWidgetSelections &s)
Block *TimelineWidget::GetItemAtScenePos(const TimelineCoordinate& coord)
{
for (auto it=block_items_.cbegin(); it!=block_items_.cend(); it++) {
Block* b = it.key();
TimelineViewBlockItem* item = it.value();
Track* track = GetTrackFromReference(coord.GetTrack());
foreach (Block* b, added_blocks_) {
if (b->in() <= coord.GetFrame()
&& b->out() > coord.GetFrame()
&& item->Track() == coord.GetTrack()) {
return item;
&& b->track() == track) {
return b;
}
}
@@ -1534,13 +1454,13 @@ struct SnapData {
rational movement;
};
QList<SnapData> AttemptSnap(const QList<double>& screen_pt,
double compare_pt,
const QList<rational>& start_times,
const rational& compare_time) {
QVector<SnapData> AttemptSnap(const QVector<double>& screen_pt,
double compare_pt,
const QVector<rational>& start_times,
const rational& compare_time) {
const qreal kSnapRange = 10; // FIXME: Hardcoded number
QList<SnapData> snap_data;
QVector<SnapData> snap_data;
for (int i=0;i<screen_pt.size();i++) {
// Attempt snapping to clip out point
@@ -1552,15 +1472,15 @@ QList<SnapData> AttemptSnap(const QList<double>& screen_pt,
return snap_data;
}
bool TimelineWidget::SnapPoint(QList<rational> start_times, rational* movement, int snap_points)
bool TimelineWidget::SnapPoint(QVector<rational> start_times, rational* movement, int snap_points)
{
QList<double> screen_pt;
QVector<double> screen_pt;
foreach (const rational& s, start_times) {
screen_pt.append(TimeToScene(s + *movement));
}
QList<SnapData> potential_snaps;
QVector<SnapData> potential_snaps;
if (snap_points & kSnapToPlayhead) {
rational playhead_abs_time = GetTime();
@@ -1569,21 +1489,15 @@ bool TimelineWidget::SnapPoint(QList<rational> start_times, rational* movement,
}
if (snap_points & kSnapToClips) {
QMap<Block*, TimelineViewBlockItem*>::const_iterator i;
foreach (Block* b, added_blocks_) {
qreal rect_left = TimeToScene(b->in());
qreal rect_right = TimeToScene(b->out());
for (i=block_items_.constBegin(); i!=block_items_.constEnd(); i++) {
TimelineViewBlockItem* item = i.value();
// Attempt snapping to clip in point
potential_snaps.append(AttemptSnap(screen_pt, rect_left, start_times, b->in()));
if (item) {
qreal rect_left = item->x();
qreal rect_right = rect_left + item->rect().width();
// Attempt snapping to clip in point
potential_snaps.append(AttemptSnap(screen_pt, rect_left, start_times, item->block()->in()));
// Attempt snapping to clip out point
potential_snaps.append(AttemptSnap(screen_pt, rect_right, start_times, item->block()->out()));
}
// Attempt snapping to clip out point
potential_snaps.append(AttemptSnap(screen_pt, rect_right, start_times, b->out()));
}
}
@@ -1620,7 +1534,7 @@ bool TimelineWidget::SnapPoint(QList<rational> start_times, rational* movement,
*movement = potential_snaps.at(closest_snap).movement;
// Find all points at this movement
QList<rational> snap_times;
QVector<rational> snap_times;
foreach (const SnapData& d, potential_snaps) {
if (d.movement == *movement) {
snap_times.append(d.time);
+17 -37
View File
@@ -75,9 +75,9 @@ public:
void DecreaseTrackHeight();
void InsertFootageAtPlayhead(const QList<Footage *> &footage);
void InsertFootageAtPlayhead(const QVector<Footage *> &footage);
void OverwriteFootageAtPlayhead(const QList<Footage *> &footage);
void OverwriteFootageAtPlayhead(const QVector<Footage *> &footage);
void ToggleLinksOnSelected();
@@ -94,17 +94,7 @@ public:
return selected_blocks_;
}
Track* GetTrackFromBlock(Block* block) const
{
return GetTrackFromReference(GetTrackReferenceFromBlock(block));
}
TrackReference GetTrackReferenceFromBlock(Block* block) const
{
return track_lookup_.value(block);
}
virtual bool SnapPoint(QList<rational> start_times, rational *movement, int snap_points = kSnapAll) override;
virtual bool SnapPoint(QVector<rational> start_times, rational *movement, int snap_points = kSnapAll) override;
virtual void HideSnaps() override;
@@ -122,10 +112,10 @@ public:
*/
Block* GetItemAtScenePos(const TimelineCoordinate &coord);
void AddSelection(const TimeRange& time, const TrackReference& track);
void AddSelection(const TimeRange& time, const Track::Reference& track);
void AddSelection(Block* item);
void RemoveSelection(const TimeRange& time, const TrackReference& track);
void RemoveSelection(const TimeRange& time, const Track::Reference& track);
void RemoveSelection(Block* item);
const TimelineWidgetSelections& GetSelections() const
@@ -135,7 +125,7 @@ public:
void SetSelections(const TimelineWidgetSelections &s);
Track* GetTrackFromReference(const TrackReference& ref) const;
Track* GetTrackFromReference(const Track::Reference& ref) const;
void SetViewBeamCursor(const TimelineCoordinate& coord);
@@ -150,8 +140,8 @@ public:
void MoveRubberBandSelect(bool enable_selecting, bool select_links);
void EndRubberBandSelect();
int GetTrackY(const TrackReference& ref);
int GetTrackHeight(const TrackReference& ref);
int GetTrackY(const Track::Reference& ref);
int GetTrackHeight(const Track::Reference& ref);
void AddGhost(TimelineViewGhostItem* ghost);
@@ -237,10 +227,12 @@ private:
void EditTo(Timeline::MovementMode mode);
void ShowSnap(const QList<rational>& times);
void ShowSnap(const QVector<rational>& times);
void UpdateViewports(const Track::Type& type = Track::kNone);
QVector<Block*> GetBlocksInGlobalRect(const QPoint &p1, const QPoint &p2);
QPoint drag_origin_;
QRubberBand rubberband_;
@@ -259,14 +251,14 @@ private:
QVector<TimelineViewGhostItem*> ghost_items_;
QHash<Block*, TrackReference> track_lookup_;
QList<TimelineAndTrackView*> views_;
QVector<TimelineAndTrackView*> views_;
TimeSlider* timecode_label_;
QVector<Block*> selected_blocks_;
QVector<Block*> added_blocks_;
int deferred_scroll_value_;
bool use_audio_time_units_;
@@ -288,31 +280,19 @@ private slots:
void ViewDragLeft(QDragLeaveEvent* event);
void ViewDragDropped(TimelineViewMouseEvent* event);
void AddBlock(Block* block, TrackReference track);
void AddBlock(Block* block);
void RemoveBlock(Block *blocks);
void AddTrack(Track* track, Track::Type type);
void AddTrack(Track* track);
void RemoveTrack(Track* track);
void TrackIndexChanged();
/**
* @brief Slot for when a Block node changes its parameters and the graphics need to update
*
* This slot does a static_cast on sender() to Block*, meaning all objects triggering this slot must be Blocks or
* derivatives.
*/
void BlockRefreshed();
void TrackUpdated();
void BlockUpdated();
void TrackPreviewUpdated();
void UpdateHorizontalSplitters();
void UpdateTimecodeWidthFromSplitters(QSplitter *s);
void TrackHeightChanged(Track::Type type, int index, int height);
void ShowContextMenu();
void DeferredScrollAction();
@@ -48,7 +48,7 @@ void TimelineWidgetSelections::ShiftTracks(Track::Type type, int diff)
// Then re-insert them with the diff applied
for (auto it=cached_selections.cbegin(); it!=cached_selections.cend(); it++) {
TrackReference ref(it.key().type(), it.key().index() + diff);
Track::Reference ref(it.key().type(), it.key().index() + diff);
this->insert(ref, it.value());
}
@@ -24,11 +24,11 @@
#include <QHash>
#include "common/timerange.h"
#include "timeline/trackreference.h"
#include "node/output/track/track.h"
namespace olive {
class TimelineWidgetSelections : public QHash<TrackReference, TimeRangeList>
class TimelineWidgetSelections : public QHash<Track::Reference, TimeRangeList>
{
public:
TimelineWidgetSelections() = default;
+3 -5
View File
@@ -18,14 +18,12 @@
***/
#include "widget/timelinewidget/timelinewidget.h"
#include "add.h"
#include "core.h"
#include "node/factory.h"
#include "node/generator/solid/solid.h"
#include "node/generator/text/text.h"
#include "widget/nodeview/nodeviewundo.h"
#include "widget/timelinewidget/timelinewidget.h"
namespace olive {
@@ -37,7 +35,7 @@ AddTool::AddTool(TimelineWidget *parent) :
void AddTool::MousePress(TimelineViewMouseEvent *event)
{
const TrackReference& track = event->GetTrack();
const Track::Reference& track = event->GetTrack();
// Check if track is locked
Track* t = parent()->GetTrackFromReference(track);
@@ -89,7 +87,7 @@ void AddTool::MouseMove(TimelineViewMouseEvent *event)
void AddTool::MouseRelease(TimelineViewMouseEvent *event)
{
const TrackReference& track = ghost_->GetTrack();
const Track::Reference& track = ghost_->GetTrack();
if (ghost_) {
if (!ghost_->GetAdjustedLength().isNull()) {
+1 -1
View File
@@ -80,7 +80,7 @@ void EditTool::MouseDoubleClick(TimelineViewMouseEvent *event)
{
Block* item = parent()->GetItemAtScenePos(event->GetCoordinates());
if (item && !parent()->GetTrackFromBlock(item)->IsLocked()) {
if (item && !item->track()->IsLocked()) {
parent()->AddSelection(item);
}
}
+8 -22
View File
@@ -18,7 +18,7 @@
***/
#include "widget/timelinewidget/timelinewidget.h"
#include "import.h"
#include <QCheckBox>
#include <QMessageBox>
@@ -192,12 +192,12 @@ void ImportTool::DragDrop(TimelineViewMouseEvent *event)
}
}
void ImportTool::PlaceAt(const QList<Footage *> &footage, const rational &start, bool insert)
void ImportTool::PlaceAt(const QVector<Footage *> &footage, const rational &start, bool insert)
{
PlaceAt(FootageToDraggedFootage(footage), start, insert);
}
void ImportTool::PlaceAt(const QList<DraggedFootage> &footage, const rational &start, bool insert)
void ImportTool::PlaceAt(const QVector<DraggedFootage> &footage, const rational &start, bool insert)
{
dragged_footage_ = footage;
@@ -209,7 +209,7 @@ void ImportTool::PlaceAt(const QList<DraggedFootage> &footage, const rational &s
DropGhosts(insert);
}
void ImportTool::FootageToGhosts(rational ghost_start, const QList<DraggedFootage> &footage_list, const rational& dest_tb, const int& track_start)
void ImportTool::FootageToGhosts(rational ghost_start, const QVector<DraggedFootage> &footage_list, const rational& dest_tb, const int& track_start)
{
foreach (const DraggedFootage& footage, footage_list) {
@@ -255,7 +255,7 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QList<DraggedFootag
}
}
ghost->SetTrack(TrackReference(track_type, track_offsets.at(track_type)));
ghost->SetTrack(Track::Reference(track_type, track_offsets.at(track_type)));
// Increment track count for this track type
track_offsets[track_type]++;
@@ -361,7 +361,7 @@ void ImportTool::DropGhosts(bool insert)
if (behavior == kDWSAuto) {
QList<Footage*> footage_only;
QVector<Footage*> footage_only;
foreach (const DraggedFootage& df, dragged_footage_) {
footage_only.append(df.footage());
@@ -431,25 +431,11 @@ void ImportTool::DropGhosts(bool insert)
video_input->SetStream(footage_stream);
new NodeAddCommand(dst_graph, video_input, command);
TransformDistortNode* transform = new TransformDistortNode();
new NodeAddCommand(dst_graph, transform, command);
new NodeEdgeAddCommand(video_input, transform->texture_input(), -1, command);
new NodeEdgeAddCommand(transform, clip->texture_input(), -1, command);
/*
MatrixGenerator* matrix = new MatrixGenerator();
new NodeAddCommand(dst_graph, matrix, command);
MathNode* multiply = new MathNode();
multiply->SetOperation(MathNode::kOpMultiply);
new NodeAddCommand(dst_graph, multiply, command);
new NodeEdgeAddCommand(video_input->output(), multiply->param_a_in(), command);
new NodeEdgeAddCommand(matrix->output(), multiply->param_b_in(), command);
new NodeEdgeAddCommand(multiply->output(), clip->texture_input(), command);
*/
break;
}
case Stream::kAudio:
@@ -503,9 +489,9 @@ ImportTool::DraggedFootage ImportTool::FootageToDraggedFootage(Footage *f)
return DraggedFootage(f, f->get_enabled_stream_flags());
}
QList<ImportTool::DraggedFootage> ImportTool::FootageToDraggedFootage(QList<Footage *> footage)
QVector<ImportTool::DraggedFootage> ImportTool::FootageToDraggedFootage(QVector<Footage *> footage)
{
QList<DraggedFootage> df;
QVector<DraggedFootage> df;
foreach (Footage* f, footage) {
df.append(FootageToDraggedFootage(f));
+5 -5
View File
@@ -58,8 +58,8 @@ public:
};
void PlaceAt(const QList<Footage*> &footage, const rational& start, bool insert);
void PlaceAt(const QList<DraggedFootage> &footage, const rational& start, bool insert);
void PlaceAt(const QVector<Footage*> &footage, const rational& start, bool insert);
void PlaceAt(const QVector<DraggedFootage> &footage, const rational& start, bool insert);
enum DropWithoutSequenceBehavior {
kDWSAsk,
@@ -70,15 +70,15 @@ public:
private:
static DraggedFootage FootageToDraggedFootage(Footage* f);
static QList<DraggedFootage> FootageToDraggedFootage(QList<Footage*> footage);
static QVector<DraggedFootage> FootageToDraggedFootage(QVector<Footage*> footage);
void FootageToGhosts(rational ghost_start, const QList<DraggedFootage>& footage, const rational &dest_tb, const int &track_start);
void FootageToGhosts(rational ghost_start, const QVector<DraggedFootage> &footage, const rational &dest_tb, const int &track_start);
void PrepGhosts(const rational &frame, const int &track_index);
void DropGhosts(bool insert);
QList<DraggedFootage> dragged_footage_;
QVector<DraggedFootage> dragged_footage_;
int import_pre_buffer_;
+64 -69
View File
@@ -49,17 +49,19 @@ PointerTool::PointerTool(TimelineWidget *parent) :
void PointerTool::MousePress(TimelineViewMouseEvent *event)
{
const Track::Reference& track_ref = event->GetTrack();
// Determine if item clicked on is selectable
clicked_item_ = parent()->GetItemAtScenePos(event->GetCoordinates());
can_rubberband_select_ = false;
bool selectable_item = (clicked_item_
&& !parent()->GetTrackFromReference(clicked_item_->Track())->IsLocked());
&& !parent()->GetTrackFromReference(track_ref)->IsLocked());
if (selectable_item) {
// Cache the clip's type for use later
drag_track_type_ = clicked_item_->Track().type();
drag_track_type_ = track_ref.type();
// If we haven't started dragging yet, we'll initiate a drag here
// Record where the drag started in timeline coordinates
@@ -73,7 +75,7 @@ void PointerTool::MousePress(TimelineViewMouseEvent *event)
// the block is not a gap)
if (drag_movement_mode_ == Timeline::kNone
&& movement_allowed_
&& clicked_item_->block()->type() != Block::kGap) {
&& clicked_item_->type() != Block::kGap) {
drag_movement_mode_ = Timeline::kMove;
}
@@ -86,12 +88,12 @@ void PointerTool::MousePress(TimelineViewMouseEvent *event)
// If shift is held, deselect it
if (event->GetModifiers() & Qt::ShiftModifier) {
parent()->RemoveSelection(clicked_item_);
deselected_blocks.append(clicked_item_->block());
deselected_blocks.append(clicked_item_);
// If not holding alt, deselect all links as well
if (!(event->GetModifiers() & Qt::AltModifier)) {
parent()->SetBlockLinksSelected(clicked_item_->block(), false);
deselected_blocks.append(clicked_item_->block()->linked_clips());
parent()->SetBlockLinksSelected(clicked_item_, false);
deselected_blocks.append(clicked_item_->linked_clips());
}
}
@@ -113,12 +115,12 @@ void PointerTool::MousePress(TimelineViewMouseEvent *event)
// Select this item
parent()->AddSelection(clicked_item_);
selected_blocks.append(clicked_item_->block());
selected_blocks.append(clicked_item_);
// If not holding alt, select all links as well
if (!(event->GetModifiers() & Qt::AltModifier)) {
parent()->SetBlockLinksSelected(clicked_item_->block(), true);
selected_blocks.append(clicked_item_->block()->linked_clips());
parent()->SetBlockLinksSelected(clicked_item_, true);
selected_blocks.append(clicked_item_->linked_clips());
}
parent()->SignalSelectedBlocks(selected_blocks);
@@ -142,7 +144,7 @@ void PointerTool::MouseMove(TimelineViewMouseEvent *event)
// If we clicked an item but are rubberband selecting anyway, deselect it now
if (clicked_item_) {
parent()->RemoveSelection(clicked_item_);
parent()->SignalDeselectedBlocks({clicked_item_->block()});
parent()->SignalDeselectedBlocks({clicked_item_});
clicked_item_ = nullptr;
}
@@ -244,13 +246,13 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
bool slide_instead_of_moving)
{
// Get list of selected blocks
QVector<TimelineViewBlockItem*> clips = parent()->GetSelectedBlocks();
QVector<Block*> clips = parent()->GetSelectedBlocks();
if (trim_mode == Timeline::kMove) {
// Each block type has different behavior, so we determine the type of the block that was
// clicked and filter out any others.
Block::Type clicked_block_type = clicked_item->block()->type();
Block::Type clicked_block_type = clicked_item->type();
// Gaps are not allowed to move, and since we only allow moving one block type at a time,
// dragging a gap is a no-op
@@ -269,43 +271,39 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
// For slides to be legal, we make all blocks "contiguous". This means that only one series
// of blocks can move at a time and prevents.
QHash<TrackReference, Block*> earliest_block_on_track;
QHash<TrackReference, Block*> latest_block_on_track;
QHash<Track*, Block*> earliest_block_on_track;
QHash<Track*, Block*> latest_block_on_track;
foreach (TimelineViewBlockItem* item, clips) {
Block* this_block = item->block();
const TrackReference& track = item->Track();
Block* current_earliest = earliest_block_on_track.value(track, nullptr);
foreach (Block* this_block, clips) {
Block* current_earliest = earliest_block_on_track.value(this_block->track(), nullptr);
if (!current_earliest || this_block->in() < current_earliest->in()) {
earliest_block_on_track.insert(track, item->block());
earliest_block_on_track.insert(this_block->track(), this_block);
}
Block* current_latest = latest_block_on_track.value(track, nullptr);
Block* current_latest = latest_block_on_track.value(this_block->track(), nullptr);
if (!current_latest || this_block->out() > current_earliest->out()) {
latest_block_on_track.insert(track, item->block());
latest_block_on_track.insert(this_block->track(), this_block);
}
}
QHash<TrackReference, Block*>::const_iterator i;
for (i=earliest_block_on_track.constBegin(); i!=earliest_block_on_track.constEnd(); i++) {
for (auto i=earliest_block_on_track.constBegin(); i!=earliest_block_on_track.constEnd(); i++) {
// Make a contiguous stream
const TrackReference& track = i.key();
Track* track = i.key();
Block* earliest = i.value();
Block* latest = latest_block_on_track.value(i.key());
// First we add the block that's out trimming, the one prior to the earliest
TimelineViewGhostItem* earliest_ghost;
if (earliest->previous()) {
earliest_ghost = AddGhostFromBlock(earliest->previous(), track, Timeline::kTrimOut);
earliest_ghost = AddGhostFromBlock(earliest->previous(), Timeline::kTrimOut);
} else {
earliest_ghost = AddGhostFromNull(earliest->in(), earliest->in(), track, Timeline::kTrimOut);
earliest_ghost = AddGhostFromNull(earliest->in(), earliest->in(), track->ToReference(), Timeline::kTrimOut);
}
SetGhostToSlideMode(earliest_ghost);
// Then we add the block that's in trimming, the one after the latest
if (latest->next()) {
TimelineViewGhostItem* latest_ghost = AddGhostFromBlock(latest->next(), track, Timeline::kTrimIn);
TimelineViewGhostItem* latest_ghost = AddGhostFromBlock(latest->next(), Timeline::kTrimIn);
SetGhostToSlideMode(latest_ghost);
}
@@ -320,15 +318,13 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
b = earliest;
}
TimelineViewGhostItem* between_ghost = AddGhostFromBlock(b, track, Timeline::kMove);
TimelineViewGhostItem* between_ghost = AddGhostFromBlock(b, Timeline::kMove);
SetGhostToSlideMode(between_ghost);
} while (b != latest);
}
} else {
// Prepare for a standard pointer move
foreach (TimelineViewBlockItem* clip_item, clips) {
Block* block = clip_item->block();
foreach (Block* block, clips) {
if (block->type() == Block::kGap || block->type() == Block::kTransition) {
// Gaps cannot move, and we handle transitions further down
continue;
@@ -336,24 +332,21 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
// Create ghost
TimelineViewGhostItem* ghost = AddGhostFromBlock(block,
clip_item->Track(),
trim_mode);
Q_UNUSED(ghost)
// Add transitions if this has any
TransitionBlock* opening_transition = TransitionBlock::GetBlockInTransition(block);
TransitionBlock* closing_transition = TransitionBlock::GetBlockOutTransition(block);
TransitionBlock* opening_transition = block->in_transition();
TransitionBlock* closing_transition = block->out_transition();
if (opening_transition) {
TimelineViewGhostItem* ot_ghost = AddGhostFromBlock(opening_transition,
clip_item->Track(),
trim_mode);
Q_UNUSED(ot_ghost)
}
if (closing_transition) {
TimelineViewGhostItem* cl_ghost = AddGhostFromBlock(closing_transition,
clip_item->Track(),
trim_mode);
Q_UNUSED(cl_ghost)
}
@@ -368,7 +361,7 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
bool multitrim_enabled = IsClipTrimmable(clicked_item, clips, trim_mode);
// Create ghosts for trimming
foreach (TimelineViewBlockItem* clip_item, clips) {
foreach (Block* clip_item, clips) {
if (clip_item != clicked_item
&& (!multitrim_enabled || !IsClipTrimmable(clip_item, clips, trim_mode))) {
// Either multitrim is disabled or this clip is NOT the earliest/latest in its track. We
@@ -376,10 +369,10 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
continue;
}
Block* block = clip_item->block();
Block* block = clip_item;
// Create ghost for this block
TimelineViewGhostItem* ghost = AddGhostFromBlock(block, clip_item->Track(), trim_mode);
TimelineViewGhostItem* ghost = AddGhostFromBlock(block, trim_mode);
// If this side of the clip has a transition, we treat it more like a slide for that
// transition than a trim/roll
@@ -391,14 +384,14 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
// Get appropriate transition for the side of the clip
if (trim_mode == Timeline::kTrimIn) {
connected_transition = TransitionBlock::GetBlockInTransition(block);
connected_transition = block->in_transition();
} else {
connected_transition = TransitionBlock::GetBlockOutTransition(block);
connected_transition = block->out_transition();
}
if (connected_transition) {
// We found a transition, we'll make this a "slide" action
TimelineViewGhostItem* transition_ghost = AddGhostFromBlock(connected_transition, clip_item->Track(), Timeline::kMove);
TimelineViewGhostItem* transition_ghost = AddGhostFromBlock(connected_transition, Timeline::kMove);
// This will in effect be a slide with the transition moving between two other blocks
SetGhostToSlideMode(ghost);
@@ -435,11 +428,11 @@ void PointerTool::InitiateDragInternal(Block *clicked_item,
TimelineViewGhostItem* adjacent_ghost;
if (adjacent) {
adjacent_ghost = AddGhostFromBlock(adjacent, clip_item->Track(), flipped_mode);
adjacent_ghost = AddGhostFromBlock(adjacent, flipped_mode);
} else if (trim_mode == Timeline::kTrimIn || block->next()) {
rational null_ghost_pos = (trim_mode == Timeline::kTrimIn) ? block->in() : block->out();
adjacent_ghost = AddGhostFromNull(null_ghost_pos, null_ghost_pos, clip_item->Track(), flipped_mode);
adjacent_ghost = AddGhostFromNull(null_ghost_pos, null_ghost_pos, clip_item->track()->ToReference(), flipped_mode);
} else {
adjacent_ghost = nullptr;
}
@@ -650,7 +643,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
block = static_cast<Block*>(copy);
}
const TrackReference& track_ref = p.ghost->GetAdjustedTrack();
const Track::Reference& track_ref = p.ghost->GetAdjustedTrack();
new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track_ref.type()),
track_ref.index(),
block,
@@ -669,13 +662,13 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
// Assume that the blocks are contiguous per track as set up in InitiateGhostsInternal()
// All we need to do is sort them by track and order them
QHash<TrackReference, QList<Block*> > slide_info;
QHash<TrackReference, Block*> in_adjacents;
QHash<TrackReference, Block*> out_adjacents;
QHash<Track::Reference, QList<Block*> > slide_info;
QHash<Track::Reference, Block*> in_adjacents;
QHash<Track::Reference, Block*> out_adjacents;
rational movement;
foreach (const GhostBlockPair& p, blocks_sliding) {
const TrackReference& track = p.ghost->GetTrack();
const Track::Reference& track = p.ghost->GetTrack();
switch (p.ghost->GetMode()) {
case Timeline::kNone:
@@ -711,7 +704,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
}
if (!movement.isNull()) {
QHash<TrackReference, QList<Block*> >::const_iterator i;
QHash<Track::Reference, QList<Block*> >::const_iterator i;
for (i=slide_info.constBegin(); i!=slide_info.constEnd(); i++) {
new TrackSlideCommand(parent()->GetTrackFromReference(i.key()),
i.value(),
@@ -735,14 +728,18 @@ Timeline::MovementMode PointerTool::IsCursorInTrimHandle(Block *block, qreal cur
{
double kTrimHandle = QtUtils::QFontMetricsWidth(parent()->fontMetrics(), "H");
double block_left = parent()->TimeToScene(block->in());
double block_right = parent()->TimeToScene(block->out());
double block_width = block_right - block_left;
// Block is too narrow, no trimming allowed
if (block->rect().width() <= kTrimHandle * 2) {
if (block_width <= kTrimHandle * 2) {
return Timeline::kNone;
}
if (trimming_allowed_ && cursor_x <= block->x() + kTrimHandle) {
if (trimming_allowed_ && cursor_x <= block_left + kTrimHandle) {
return Timeline::kTrimIn;
} else if (trimming_allowed_ && cursor_x >= block->x() + block->rect().right() - kTrimHandle) {
} else if (trimming_allowed_ && cursor_x >= block_left + block_right - kTrimHandle) {
return Timeline::kTrimOut;
} else {
return Timeline::kNone;
@@ -757,7 +754,7 @@ void PointerTool::InitiateDrag(Block *clicked_item,
//#define HIDE_GAP_GHOSTS
TimelineViewGhostItem* PointerTool::AddGhostFromBlock(Block* block, const TrackReference& track, Timeline::MovementMode mode, bool check_if_exists)
TimelineViewGhostItem* PointerTool::AddGhostFromBlock(Block* block, Timeline::MovementMode mode, bool check_if_exists)
{
if (check_if_exists) {
foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) {
@@ -767,7 +764,7 @@ TimelineViewGhostItem* PointerTool::AddGhostFromBlock(Block* block, const TrackR
}
}
TimelineViewGhostItem* ghost = TimelineViewGhostItem::FromBlock(block, track);
TimelineViewGhostItem* ghost = TimelineViewGhostItem::FromBlock(block);
#ifdef HIDE_GAP_GHOSTS
if (block->type() == Block::kGap) {
@@ -780,7 +777,7 @@ TimelineViewGhostItem* PointerTool::AddGhostFromBlock(Block* block, const TrackR
return ghost;
}
TimelineViewGhostItem* PointerTool::AddGhostFromNull(const rational &in, const rational &out, const TrackReference& track, Timeline::MovementMode mode)
TimelineViewGhostItem* PointerTool::AddGhostFromNull(const rational &in, const rational &out, const Track::Reference& track, Timeline::MovementMode mode)
{
TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
@@ -821,14 +818,14 @@ void PointerTool::AddGhostInternal(TimelineViewGhostItem* ghost, Timeline::Movem
}
bool PointerTool::IsClipTrimmable(Block *clip,
const QVector<TimelineViewBlockItem*>& items,
const QVector<Block*>& items,
const Timeline::MovementMode& mode)
{
foreach (TimelineViewBlockItem* compare, items) {
if (clip->Track() == compare->Track()
foreach (Block* compare, items) {
if (clip->track() == compare->track()
&& clip != compare
&& ((compare->block()->in() < clip->block()->in() && mode == Timeline::kTrimIn)
|| (compare->block()->out() > clip->block()->out() && mode == Timeline::kTrimOut))) {
&& ((compare->in() < clip->in() && mode == Timeline::kTrimIn)
|| (compare->out() > clip->out() && mode == Timeline::kTrimOut))) {
return false;
}
}
@@ -837,7 +834,6 @@ bool PointerTool::IsClipTrimmable(Block *clip,
}
bool PointerTool::AddMovingTransitionsToClipGhost(Block* block,
const TrackReference& track,
Timeline::MovementMode movement,
const QVector<Block *> &selected_items)
{
@@ -845,13 +841,13 @@ bool PointerTool::AddMovingTransitionsToClipGhost(Block* block,
TransitionBlock* transitions[2];
if (movement == Timeline::kMove || movement == Timeline::kTrimOut) {
transitions[0] = TransitionBlock::GetBlockOutTransition(block);
transitions[0] = block->out_transition();
} else {
transitions[0] = nullptr;
}
if (movement == Timeline::kMove || movement == Timeline::kTrimIn) {
transitions[1] = TransitionBlock::GetBlockInTransition(block);
transitions[1] = block->in_transition();
} else {
transitions[1] = nullptr;
}
@@ -865,8 +861,8 @@ bool PointerTool::AddMovingTransitionsToClipGhost(Block* block,
bool found = false;
foreach (TimelineViewBlockItem* item, selected_items) {
if (item->block() == transitions[i]) {
foreach (Block* item, selected_items) {
if (item == transitions[i]) {
// Do nothing
found = true;
break;
@@ -874,8 +870,7 @@ bool PointerTool::AddMovingTransitionsToClipGhost(Block* block,
}
if (!found) {
TimelineViewGhostItem* transition_ghost = AddGhostFromBlock(transitions[i], track,
Timeline::kMove);
TimelineViewGhostItem* transition_ghost = AddGhostFromBlock(transitions[i], Timeline::kMove);
Q_UNUSED(transition_ghost)
+3 -3
View File
@@ -42,9 +42,9 @@ protected:
virtual void InitiateDrag(Block* clicked_item,
Timeline::MovementMode trim_mode);
TimelineViewGhostItem* AddGhostFromBlock(Block *block, const TrackReference& track, Timeline::MovementMode mode, bool check_if_exists = false);
TimelineViewGhostItem* AddGhostFromBlock(Block *block, Timeline::MovementMode mode, bool check_if_exists = false);
TimelineViewGhostItem* AddGhostFromNull(const rational& in, const rational& out, const TrackReference& track, Timeline::MovementMode mode);
TimelineViewGhostItem* AddGhostFromNull(const rational& in, const rational& out, const Track::Reference& track, Timeline::MovementMode mode);
/**
* @brief Validates Ghosts that are getting their in points trimmed
@@ -107,7 +107,7 @@ private:
void ProcessGhostsForRolling();
bool AddMovingTransitionsToClipGhost(Block *block, const TrackReference &track, Timeline::MovementMode movement, const QVector<Block*> &selected_items);
bool AddMovingTransitionsToClipGhost(Block *block, Timeline::MovementMode movement, const QVector<Block*> &selected_items);
bool movement_allowed_;
bool trimming_allowed_;
+2 -2
View File
@@ -43,7 +43,7 @@ void RazorTool::MouseMove(TimelineViewMouseEvent *event)
}
// Split at the current cursor track
TrackReference split_track = event->GetTrack();
Track::Reference split_track = event->GetTrack();
if (!split_tracks_.contains(split_track)) {
split_tracks_.append(split_track);
@@ -59,7 +59,7 @@ void RazorTool::MouseRelease(TimelineViewMouseEvent *event)
QVector<Block*> blocks_to_split;
foreach (const TrackReference& track_ref, split_tracks_) {
foreach (const Track::Reference& track_ref, split_tracks_) {
Track* track = parent()->GetTrackFromReference(track_ref);
if (track == nullptr || track->IsLocked()) {
+1 -1
View File
@@ -35,7 +35,7 @@ public:
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
private:
QVector<TrackReference> split_tracks_;
QVector<Track::Reference> split_tracks_;
};
}
+4 -6
View File
@@ -82,20 +82,18 @@ void RippleTool::InitiateDrag(Block *clicked_item,
if (block_before_ripple) {
TimelineViewGhostItem* ghost;
TrackReference track_ref(track->track_type(), track->Index());
if (block_before_ripple->type() == Block::kGap) {
// If this Block is already a Gap, ghost it now
ghost = AddGhostFromBlock(block_before_ripple, track_ref, trim_mode);
ghost = AddGhostFromBlock(block_before_ripple, trim_mode);
} else if (block_before_ripple->next()) {
// Assuming this block is NOT at the end of the track (i.e. next != null)
// We're going to create a gap after it. If next is a gap, we can just use that
if (block_before_ripple->next()->type() == Block::kGap) {
ghost = AddGhostFromBlock(block_before_ripple->next(), track_ref, trim_mode);
ghost = AddGhostFromBlock(block_before_ripple->next(), trim_mode);
} else {
// If next is NOT a gap, we'll need to create one, for which we'll use a null ghost
ghost = AddGhostFromNull(block_before_ripple->out(), block_before_ripple->out(), track_ref, trim_mode);
ghost = AddGhostFromNull(block_before_ripple->out(), block_before_ripple->out(), track->ToReference(), trim_mode);
ghost->SetData(TimelineViewGhostItem::kReferenceBlock, Node::PtrToValue(block_before_ripple));
}
}
@@ -120,7 +118,7 @@ void RippleTool::FinishDrag(TimelineViewMouseEvent *event)
ghost->GetAdjustedLength(),
ghost->GetLength()};
info_list[track->track_type()].append(i);
info_list[track->type()].append(i);
}
QUndoCommand* command = new QUndoCommand();
-1
View File
@@ -21,7 +21,6 @@
#include "widget/timelinewidget/timelinewidget.h"
#include "node/block/transition/transition.h"
#include "widget/nodeview/nodeviewundo.h"
namespace olive {
+3 -1
View File
@@ -24,6 +24,8 @@
#include <QDragLeaveEvent>
#include "common/rational.h"
#include "widget/nodeview/nodeviewundo.h"
#include "widget/timelinewidget/timelineundo.h"
#include "widget/timelinewidget/view/timelineviewghostitem.h"
#include "widget/timelinewidget/view/timelineviewmouseevent.h"
@@ -75,7 +77,7 @@ protected:
void InsertGapsAtGhostDestination(QUndoCommand* command);
QList<rational> snap_points_;
QVector<rational> snap_points_;
bool dragging_;
@@ -25,6 +25,7 @@
#include "node/factory.h"
#include "transition.h"
#include "widget/nodeview/nodeviewundo.h"
#include "widget/timelinewidget/timelineundo.h"
namespace olive {
@@ -35,7 +36,7 @@ TransitionTool::TransitionTool(TimelineWidget *parent) :
void TransitionTool::MousePress(TimelineViewMouseEvent *event)
{
const TrackReference& track = event->GetTrack();
const Track::Reference& track = event->GetTrack();
Track* t = parent()->GetTrackFromReference(track);
rational cursor_frame = event->GetFrame();
@@ -106,7 +107,7 @@ void TransitionTool::MouseMove(TimelineViewMouseEvent *event)
void TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
{
const TrackReference& track = ghost_->GetTrack();
const Track::Reference& track = ghost_->GetTrack();
if (ghost_) {
if (!ghost_->GetAdjustedLength().isNull()) {
@@ -72,7 +72,6 @@ void TrackView::ConnectTrackList(TrackList *list)
RemoveTrack(track);
}
disconnect(list_, &TrackList::TrackHeightChanged, splitter_, &TrackViewSplitter::SetTrackHeight);
disconnect(list_, &TrackList::TrackAdded, this, &TrackView::InsertTrack);
disconnect(list_, &TrackList::TrackRemoved, this, &TrackView::RemoveTrack);
}
@@ -84,7 +83,6 @@ void TrackView::ConnectTrackList(TrackList *list)
InsertTrack(track);
}
connect(list_, &TrackList::TrackHeightChanged, splitter_, &TrackViewSplitter::SetTrackHeight);
connect(list_, &TrackList::TrackAdded, this, &TrackView::InsertTrack);
connect(list_, &TrackList::TrackRemoved, this, &TrackView::RemoveTrack);
}
@@ -111,7 +111,7 @@ void TrackViewItem::LineEditCancelled()
void TrackViewItem::UpdateLabel()
{
if (track_->GetLabel().isEmpty()) {
label_->setText(track_->GetDefaultTrackName(track_->track_type(), track_->Index()));
label_->setText(track_->GetDefaultTrackName(track_->type(), track_->Index()));
} else {
label_->setText(track_->GetLabel());
}
+60 -17
View File
@@ -229,6 +229,13 @@ void TimelineView::drawBackground(QPainter *painter, const QRectF &rect)
void TimelineView::drawForeground(QPainter *painter, const QRectF &rect)
{
if (!connected_track_list_) {
return;
}
// Draw block backgrounds
DrawBlocks(painter, false);
// Draw selections
if (selections_ && !selections_->isEmpty()) {
painter->setPen(Qt::NoPen);
@@ -248,6 +255,9 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect)
}
}
// Draw block foregrounds
DrawBlocks(painter, true);
// Draw ghosts
if (ghosts_ && !ghosts_->isEmpty()) {
painter->setPen(QPen(Qt::yellow, 2));
@@ -268,7 +278,6 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect)
// Draw beam cursor
if (show_beam_cursor_
&& connected_track_list_
&& cursor_coord_.GetTrack().type() == connected_track_list_->type()) {
painter->setPen(Qt::gray);
@@ -328,20 +337,20 @@ Track::Type TimelineView::ConnectedTrackType()
return connected_track_list_->type();
}
return Timeline::kTrackTypeNone;
return Track::kNone;
}
Stream::Type TimelineView::TrackTypeToStreamType(Track::Type track_type)
{
switch (track_type) {
case Timeline::kTrackTypeNone:
case Timeline::kTrackTypeCount:
case Track::kNone:
case Track::kCount:
break;
case Timeline::kTrackTypeVideo:
case Track::kVideo:
return Stream::kVideo;
case Timeline::kTrackTypeAudio:
case Track::kAudio:
return Stream::kAudio;
case Timeline::kTrackTypeSubtitle:
case Track::kSubtitle:
return Stream::kSubtitle;
}
@@ -355,7 +364,7 @@ TimelineCoordinate TimelineView::ScreenToCoordinate(const QPoint& pt)
TimelineCoordinate TimelineView::SceneToCoordinate(const QPointF& pt)
{
return TimelineCoordinate(SceneToTime(pt.x()), TrackReference(ConnectedTrackType(), SceneToTrack(pt.y())));
return TimelineCoordinate(SceneToTime(pt.x()), Track::Reference(ConnectedTrackType(), SceneToTrack(pt.y())));
}
TimelineViewMouseEvent TimelineView::CreateMouseEvent(QMouseEvent *event)
@@ -370,11 +379,53 @@ TimelineViewMouseEvent TimelineView::CreateMouseEvent(const QPoint& pos, Qt::Mou
return TimelineViewMouseEvent(scene_pt.x(),
GetScale(),
timebase(),
TrackReference(ConnectedTrackType(), SceneToTrack(scene_pt.y())),
Track::Reference(ConnectedTrackType(), SceneToTrack(scene_pt.y())),
button,
modifiers);
}
void TimelineView::DrawBlocks(QPainter *painter, bool foreground)
{
rational start_time = SceneToTime(0);
rational end_time = SceneToTime(viewport()->width());
foreach (Track* track, connected_track_list_->GetTracks()) {
// Get first visible block in this track
Block* block = track->NearestBlockBeforeOrAt(start_time);
while (block) {
if (block->type() == Block::kClip) {
qreal block_left = qMax(0.0, TimeToScene(block->in()));
qreal block_right = qMin(qreal(viewport()->width()), TimeToScene(block->out()));
QRectF r(block_left,
GetTrackY(track->Index()),
block_right - block_left,
GetTrackHeight(track->Index()));
if (foreground) {
painter->setPen(Qt::white);
painter->setBrush(Qt::NoBrush);
painter->drawText(r, block->GetLabel());
} else {
painter->setPen(Qt::NoPen);
painter->setBrush(QColor(128, 128, 192));
painter->drawRect(r);
}
}
if (block->out() >= end_time) {
// Rest of the clips are offscreen, can break loop now
break;
}
block = block->next();
}
}
}
int TimelineView::GetHeightOfAllTracks() const
{
if (connected_track_list_) {
@@ -436,15 +487,7 @@ 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()));
}
}
void TimelineView::SetBeamCursor(const TimelineCoordinate &coord)
@@ -56,7 +56,7 @@ public:
void SetBeamCursor(const TimelineCoordinate& coord);
void SetSelectionList(QHash<TrackReference, TimeRangeList>* s)
void SetSelectionList(QHash<Track::Reference, TimeRangeList>* s)
{
selections_ = s;
}
@@ -66,6 +66,8 @@ public:
ghosts_ = ghosts;
}
int SceneToTrack(double y);
signals:
void MousePressed(TimelineViewMouseEvent* event);
void MouseMoved(TimelineViewMouseEvent* event);
@@ -107,15 +109,15 @@ private:
TimelineViewMouseEvent CreateMouseEvent(QMouseEvent* event);
TimelineViewMouseEvent CreateMouseEvent(const QPoint &pos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers);
int GetHeightOfAllTracks() const;
void DrawBlocks(QPainter* painter, bool foreground);
int SceneToTrack(double y);
int GetHeightOfAllTracks() const;
void UserSetTime(const int64_t& time);
void UpdatePlayheadRect();
QHash<TrackReference, TimeRangeList>* selections_;
QHash<Track::Reference, TimeRangeList>* selections_;
QVector<TimelineViewGhostItem*>* ghosts_;
@@ -25,7 +25,6 @@
#include "project/item/footage/footage.h"
#include "timeline/timelinecommon.h"
#include "timeline/trackreference.h"
namespace olive {
/**
@@ -52,14 +51,14 @@ public:
{
}
static TimelineViewGhostItem* FromBlock(Block *block, const TrackReference &track)
static TimelineViewGhostItem* FromBlock(Block *block)
{
TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
ghost->SetIn(block->in());
ghost->SetOut(block->out());
ghost->SetMediaIn(block->media_in());
ghost->SetTrack(track);
ghost->SetTrack(block->track()->ToReference());
ghost->SetData(kAttachedBlock, Node::PtrToValue(block));
switch (block->type()) {
@@ -187,9 +186,9 @@ public:
return media_in_ + media_in_adj_;
}
TrackReference GetAdjustedTrack() const
Track::Reference GetAdjustedTrack() const
{
return TrackReference(track_.type(), track_.index() + track_adj_);
return Track::Reference(track_.type(), track_.index() + track_adj_);
}
const Timeline::MovementMode& GetMode() const
@@ -220,12 +219,12 @@ public:
data_.insert(key, value);
}
const TrackReference& GetTrack() const
const Track::Reference& GetTrack() const
{
return track_;
}
void SetTrack(const TrackReference& track)
void SetTrack(const Track::Reference& track)
{
track_ = track;
}
@@ -258,7 +257,7 @@ private:
bool can_have_zero_length_;
bool can_move_tracks_;
TrackReference track_;
Track::Reference track_;
QHash<int, QVariant> data_;
@@ -36,7 +36,7 @@ public:
TimelineViewMouseEvent(const qreal& scene_x,
const double& scale_x,
const rational& timebase,
const TrackReference &track,
const Track::Reference &track,
const Qt::MouseButton &button,
const Qt::KeyboardModifiers& modifiers = Qt::NoModifier) :
scene_x_(scene_x),
@@ -74,7 +74,7 @@ public:
return TimeScaledObject::SceneToTime(scene_x_, scale_x_, timebase_, round);
}
const TrackReference& GetTrack() const
const Track::Reference& GetTrack() const
{
return track_;
}
@@ -121,7 +121,7 @@ private:
double scale_x_;
rational timebase_;
TrackReference track_;
Track::Reference track_;
Qt::MouseButton button_;