timeline: implemented nudging #1692
This commit is contained in:
@@ -170,6 +170,10 @@ public:
|
||||
|
||||
virtual void SetColorLabel(int){}
|
||||
|
||||
virtual void NudgeLeft(){}
|
||||
|
||||
virtual void NudgeRight(){}
|
||||
|
||||
signals:
|
||||
void CloseRequested();
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ void TimelineWidget::DeleteSelected(bool ripple)
|
||||
ReplaceBlocksWithGaps(clips_to_delete, true, command);
|
||||
|
||||
// Remove all selections
|
||||
command->add_child(new SetSelectionsCommand(this, TimelineWidgetSelections(), GetSelections()));
|
||||
command->add_child(new SetSelectionsCommand(this, TimelineWidgetSelections(), GetSelections(), false));
|
||||
|
||||
// Insert ripple command now that it's all cleaned up gaps
|
||||
if (ripple) {
|
||||
@@ -724,6 +724,20 @@ void TimelineWidget::SetColorLabel(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::NudgeLeft()
|
||||
{
|
||||
if (GetConnectedNode()) {
|
||||
NudgeInternal(-timebase());
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::NudgeRight()
|
||||
{
|
||||
if (GetConnectedNode()) {
|
||||
NudgeInternal(timebase());
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::InsertGapsAt(const rational &earliest_point, const rational &insert_length, MultiUndoCommand *command)
|
||||
{
|
||||
for (int i=0;i<Track::kCount;i++) {
|
||||
@@ -1145,6 +1159,23 @@ void TimelineWidget::UpdateViewTimebases()
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::NudgeInternal(const rational &amount)
|
||||
{
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
foreach (Block* b, selected_blocks_) {
|
||||
command->add_child(new TrackReplaceBlockWithGapCommand(b->track(), b, false));
|
||||
command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(b->track()->type()), b->track()->Index(), b, b->in() + amount));
|
||||
}
|
||||
|
||||
// Nudge selections
|
||||
TimelineWidgetSelections new_sel = GetSelections();
|
||||
new_sel.ShiftTime(amount);
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(this, new_sel, GetSelections(), true));
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
}
|
||||
|
||||
void TimelineWidget::SetViewBeamCursor(const TimelineCoordinate &coord)
|
||||
{
|
||||
foreach (TimelineAndTrackView* tview, views_) {
|
||||
@@ -1428,6 +1459,31 @@ QVector<Block *> TimelineWidget::GetBlocksInGlobalRect(const QPoint &p1, const Q
|
||||
return blocks_in_rect;
|
||||
}
|
||||
|
||||
QVector<Block *> TimelineWidget::GetBlocksInSelection(const TimelineWidgetSelections &sel)
|
||||
{
|
||||
QVector<Block *> blocks;
|
||||
|
||||
for (auto it=sel.cbegin(); it!=sel.cend(); it++) {
|
||||
const Track::Reference &ref = it.key();
|
||||
const TimeRangeList &list = it.value();
|
||||
|
||||
for (const TimeRange &r : list) {
|
||||
Track *track = GetTrackFromReference(ref);
|
||||
if (track) {
|
||||
for (Block *b : track->Blocks()) {
|
||||
if (r.Contains(b->range())) {
|
||||
blocks.append(b);
|
||||
} else if (b->in() >= r.out()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
void TimelineWidget::HideSnaps()
|
||||
{
|
||||
foreach (TimelineAndTrackView* tview, views_) {
|
||||
@@ -1474,7 +1530,7 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
|
||||
QVector<Block*> items_in_rubberband = GetBlocksInGlobalRect(drag_origin_, rubberband_now);
|
||||
|
||||
// Reset selection to whatever it was before
|
||||
SetSelections(rubberband_old_selections_);
|
||||
SetSelections(rubberband_old_selections_, false);
|
||||
|
||||
// Add any blocks in rubberband
|
||||
rubberband_now_selected_.clear();
|
||||
@@ -1544,8 +1600,13 @@ void TimelineWidget::RemoveSelection(Block *item)
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::SetSelections(const TimelineWidgetSelections &s)
|
||||
void TimelineWidget::SetSelections(const TimelineWidgetSelections &s, bool process_block_changes)
|
||||
{
|
||||
if (process_block_changes) {
|
||||
SignalDeselectedBlocks(GetBlocksInSelection(selections_.Subtracted(s)));
|
||||
SignalSelectedBlocks(GetBlocksInSelection(s.Subtracted(selections_)));
|
||||
}
|
||||
|
||||
selections_ = s;
|
||||
|
||||
UpdateViewports();
|
||||
|
||||
@@ -91,6 +91,10 @@ public:
|
||||
|
||||
void SetColorLabel(int index);
|
||||
|
||||
void NudgeLeft();
|
||||
|
||||
void NudgeRight();
|
||||
|
||||
/**
|
||||
* @brief Timelines should always be connected to sequences
|
||||
*/
|
||||
@@ -133,7 +137,7 @@ public:
|
||||
return selections_;
|
||||
}
|
||||
|
||||
void SetSelections(const TimelineWidgetSelections &s);
|
||||
void SetSelections(const TimelineWidgetSelections &s, bool process_block_changes);
|
||||
|
||||
Track* GetTrackFromReference(const Track::Reference& ref) const;
|
||||
|
||||
@@ -208,10 +212,11 @@ public:
|
||||
|
||||
class SetSelectionsCommand : public UndoCommand {
|
||||
public:
|
||||
SetSelectionsCommand(TimelineWidget* timeline, const TimelineWidgetSelections& now, const TimelineWidgetSelections& old) :
|
||||
SetSelectionsCommand(TimelineWidget* timeline, const TimelineWidgetSelections& now, const TimelineWidgetSelections& old, bool process_block_changes) :
|
||||
timeline_(timeline),
|
||||
old_(old),
|
||||
now_(now)
|
||||
now_(now),
|
||||
process_block_changes_(process_block_changes)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -220,18 +225,19 @@ public:
|
||||
protected:
|
||||
virtual void redo() override
|
||||
{
|
||||
timeline_->SetSelections(now_);
|
||||
timeline_->SetSelections(now_, process_block_changes_);
|
||||
}
|
||||
|
||||
virtual void undo() override
|
||||
{
|
||||
timeline_->SetSelections(old_);
|
||||
timeline_->SetSelections(old_, process_block_changes_);
|
||||
}
|
||||
|
||||
private:
|
||||
TimelineWidget* timeline_;
|
||||
TimelineWidgetSelections old_;
|
||||
TimelineWidgetSelections now_;
|
||||
bool process_block_changes_;
|
||||
|
||||
};
|
||||
|
||||
@@ -271,6 +277,8 @@ private:
|
||||
|
||||
QVector<Block*> GetBlocksInGlobalRect(const QPoint &p1, const QPoint &p2);
|
||||
|
||||
QVector<Block*> GetBlocksInSelection(const TimelineWidgetSelections &sel);
|
||||
|
||||
QPoint drag_origin_;
|
||||
|
||||
QRubberBand rubberband_;
|
||||
@@ -307,6 +315,8 @@ private:
|
||||
|
||||
void UpdateViewTimebases();
|
||||
|
||||
void NudgeInternal(const rational &amount);
|
||||
|
||||
private slots:
|
||||
void ViewMousePressed(TimelineViewMouseEvent* event);
|
||||
void ViewMouseMoved(TimelineViewMouseEvent* event);
|
||||
|
||||
@@ -68,4 +68,17 @@ void TimelineWidgetSelections::TrimOut(const rational &diff)
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidgetSelections::Subtract(const TimelineWidgetSelections &selections)
|
||||
{
|
||||
for (auto it=selections.cbegin(); it!=selections.cend(); it++) {
|
||||
const Track::Reference &track = it.key();
|
||||
const TimeRangeList &their_list = it.value();
|
||||
|
||||
if (this->contains(track)) {
|
||||
TimeRangeList &our_list = (*this)[it.key()];
|
||||
our_list.remove(their_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,6 +41,15 @@ public:
|
||||
|
||||
void TrimOut(const rational& diff);
|
||||
|
||||
void Subtract(const TimelineWidgetSelections &selections);
|
||||
|
||||
TimelineWidgetSelections Subtracted(const TimelineWidgetSelections &selections) const
|
||||
{
|
||||
TimelineWidgetSelections copy = *this;
|
||||
copy.Subtract(selections);
|
||||
return copy;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ void EditTool::MouseMove(TimelineViewMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
parent()->SetSelections(start_selections_);
|
||||
parent()->SetSelections(start_selections_, false);
|
||||
parent()->AddSelection(TimeRange(start_coord_.GetFrame(), end_frame),
|
||||
start_coord_.GetTrack());
|
||||
} else {
|
||||
@@ -73,6 +73,10 @@ void EditTool::MouseMove(TimelineViewMouseEvent *event)
|
||||
|
||||
void EditTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
{
|
||||
auto current_sel = parent()->GetSelections();
|
||||
parent()->SetSelections(start_selections_, false);
|
||||
parent()->SetSelections(current_sel, true);
|
||||
|
||||
dragging_ = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
|
||||
} else {
|
||||
new_sel.TrimOut(reference_ghost->GetOutAdjustment());
|
||||
}
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections()));
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections(), false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,7 +620,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
|
||||
TimelineWidgetSelections new_sel = parent()->GetSelections();
|
||||
new_sel.ShiftTime(blocks_moving.first().ghost->GetInAdjustment());
|
||||
new_sel.ShiftTracks(drag_track_type_, blocks_moving.first().ghost->GetTrackAdjustment());
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections()));
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections(), false));
|
||||
}
|
||||
|
||||
if (!blocks_sliding.isEmpty()) {
|
||||
@@ -681,7 +681,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event)
|
||||
// Adjust selections
|
||||
TimelineWidgetSelections new_sel = parent()->GetSelections();
|
||||
new_sel.ShiftTime(movement);
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections()));
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections(), false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ void RippleTool::FinishDrag(TimelineViewMouseEvent *event)
|
||||
} else {
|
||||
new_sel.TrimOut(reference_ghost->GetOutAdjustment());
|
||||
}
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections()));
|
||||
command->add_child(new TimelineWidget::SetSelectionsCommand(parent(), new_sel, parent()->GetSelections(), false));
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user