timeline: reworked rubberband

This commit is contained in:
itsmattkc
2020-10-06 00:20:54 +11:00
parent 2ccbfa7715
commit 2d93e82489
2 changed files with 78 additions and 70 deletions
+51 -67
View File
@@ -183,8 +183,7 @@ void TimelineWidget::Clear()
block_items_.clear();
// Emit that we've deselected any selected blocks
emit BlocksDeselected(selected_blocks_);
selected_blocks_.clear();
SignalDeselectedAllBlocks();
// Set null timebase
SetTimebase(0);
@@ -380,7 +379,7 @@ void TimelineWidget::SelectAll()
}
}
SignalSelectedBlocks(newly_selected_blocks);
SignalSelectedBlocks(newly_selected_blocks, false);
}
void TimelineWidget::DeselectAll()
@@ -391,11 +390,8 @@ void TimelineWidget::DeselectAll()
// Update all viewports
UpdateViewports();
// Emit signal that any previously selected block is no longer selected
emit BlocksDeselected(selected_blocks_);
// Empty selected blocks list
selected_blocks_.clear();
// Clear list and emit signal
SignalDeselectedAllBlocks();
}
void TimelineWidget::RippleToIn()
@@ -1232,11 +1228,23 @@ const QRect& TimelineWidget::GetRubberBandGeometry() const
return rubberband_.geometry();
}
void TimelineWidget::SignalSelectedBlocks(const QList<Block *> &selected_blocks)
void TimelineWidget::SignalSelectedBlocks(QList<Block *> input, bool filter)
{
selected_blocks_.append(selected_blocks);
if (filter) {
// If filtering, remove all the blocks that are already selected
for (int i=0; i<input.size(); i++) {
Block* b = input.at(i);
emit BlocksSelected(selected_blocks);
if (selected_blocks_.contains(b)) {
input.removeAt(i);
i--;
}
}
}
selected_blocks_.append(input);
emit BlocksSelected(input);
}
void TimelineWidget::SignalDeselectedBlocks(const QList<Block *> &deselected_blocks)
@@ -1248,6 +1256,12 @@ void TimelineWidget::SignalDeselectedBlocks(const QList<Block *> &deselected_blo
emit BlocksDeselected(deselected_blocks);
}
void TimelineWidget::SignalDeselectedAllBlocks()
{
emit BlocksDeselected(selected_blocks_);
selected_blocks_.clear();
}
QVector<Timeline::EditToInfo> TimelineWidget::GetEditToInfo(const rational& playhead_time,
Timeline::MovementMode mode)
{
@@ -1423,10 +1437,8 @@ void TimelineWidget::StartRubberBandSelect(bool enable_selecting, bool select_li
rubberband_.show();
// We don't touch any blocks that are already selected. If you want these to be deselected by
// default, call DeselectAll() befoer calling StartRubberBandSelect()
foreach (Block* b, selected_blocks_) {
rubberband_already_selected_.append(block_items_.value(b));
}
// default, call DeselectAll() before calling StartRubberBandSelect()
rubberband_old_selections_ = selections_;
MoveRubberBandSelect(enable_selecting, select_links);
}
@@ -1441,7 +1453,7 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
return;
}
QList<QGraphicsItem*> new_selected_list;
QList<QGraphicsItem*> items_in_rubberband;
// Determine all items in the rubberband
foreach (TimelineAndTrackView* tview, views_) {
@@ -1454,64 +1466,40 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
// Normalize and get items in rect
QList<QGraphicsItem*> rubberband_items = view->items(mapped_rect.normalized());
new_selected_list.append(rubberband_items);
items_in_rubberband.append(rubberband_items);
}
// Filter out any items that were already selected
if (!rubberband_already_selected_.isEmpty()) {
for (int i=0; i<new_selected_list.size(); i++) {
if (rubberband_already_selected_.contains(new_selected_list.at(i))) {
new_selected_list.removeAt(i);
i--;
}
}
}
// Reset selection to whatever it was before
SetSelections(rubberband_old_selections_);
foreach (QGraphicsItem* item, rubberband_now_selected_) {
// Add any blocks in rubberband
rubberband_now_selected_.clear();
foreach (QGraphicsItem* item, items_in_rubberband) {
TimelineViewBlockItem* block_item = dynamic_cast<TimelineViewBlockItem*>(item);
if (block_item) {
RemoveSelection(block_item);
}
}
// Cache limit because we append to this array in this loop and don't need to process those
int lim = new_selected_list.size();
for (int i=0;i<lim;i++) {
TimelineViewBlockItem* block_item = static_cast<TimelineViewBlockItem*>(new_selected_list.at(i));
if (block_item->block()->type() == Block::kGap) {
continue;
}
TrackOutput* t = GetTrackFromReference(block_item->Track());
if (t && t->IsLocked()) {
continue;
}
// Since new_selected_list is filtered by rubberband_already_selected_, this should certainly
// be deselected by now
AddSelection(block_item);
if (select_links) {
// Select the block's links
Block* b = block_item->block();
// Add its links to the list
TimelineViewBlockItem* link_item;
foreach (Block* link, b->linked_clips()) {
if ((link_item = block_items_[link]) != nullptr) {
AddSelection(link_item);
if (b->type() == Block::kGap) {
continue;
}
if (!new_selected_list.contains(link_item)
&& !rubberband_already_selected_.contains(link_item)) {
new_selected_list.append(link_item);
}
TrackOutput* t = GetTrackFromReference(block_item->Track());
if (t && t->IsLocked()) {
continue;
}
AddSelection(block_item);
rubberband_now_selected_.append(block_item->block());
if (select_links) {
foreach (Block* link, b->linked_clips()) {
AddSelection(block_items_.value(link));
rubberband_now_selected_.append(link);
}
}
}
}
rubberband_now_selected_ = new_selected_list;
}
void TimelineWidget::EndRubberBandSelect()
@@ -1519,14 +1507,10 @@ void TimelineWidget::EndRubberBandSelect()
rubberband_.hide();
// Emit any blocks that were newly selected
QList<Block*> selected_blocks;
foreach (QGraphicsItem* item, rubberband_now_selected_) {
selected_blocks.append(static_cast<TimelineViewBlockItem*>(item)->block());
}
emit BlocksSelected(selected_blocks);
SignalSelectedBlocks(rubberband_now_selected_);
rubberband_now_selected_.clear();
rubberband_already_selected_.clear();
rubberband_old_selections_.clear();
}
void TimelineWidget::AddSelection(const TimeRange &time, const TrackReference &track)
+27 -3
View File
@@ -169,10 +169,34 @@ public:
const QRect &GetRubberBandGeometry() const;
void SignalSelectedBlocks(const QList<Block*>& selected_blocks);
/**
* @brief Track blocks that have newly been selected (this is preferred over emitting BlocksSelected directly)
*
* TimelineWidget keeps track of which blocks are selected internally. Calling this function will
* add to that list and emit a signal to other widgets that said blocks have been selected.
*
* @param selected_blocks
*
* The list of blocks to add to the internal selection list and signal.
*
* @param filter
*
* TRUE to automatically filter blocks that are already selected from the list. In most cases,
* this is preferable and should only be set to FALSE if the list is guaranteed not to contain
* already selected blocks (and therefore filtering can be skipped to save time).
*/
void SignalSelectedBlocks(QList<Block *> selected_blocks, bool filter = true);
/**
* @brief Track blocks that have been newly deselected
*/
void SignalDeselectedBlocks(const QList<Block*>& deselected_blocks);
/**
* @brief Convenience function to deselect all blocks and signal them
*/
void SignalDeselectedAllBlocks();
signals:
void BlocksSelected(const QList<Block*>& selected_blocks);
@@ -212,8 +236,8 @@ private:
QPoint drag_origin_;
QRubberBand rubberband_;
QList<QGraphicsItem*> rubberband_already_selected_;
QList<QGraphicsItem*> rubberband_now_selected_;
TimelineWidgetSelections rubberband_old_selections_;
QList<Block*> rubberband_now_selected_;
TimelineWidgetSelections selections_;