ui: optimized widget signals for selecting clips/nodes

Decent performance optimization when working with the UI.
This commit is contained in:
itsmattkc
2020-08-01 02:12:20 +10:00
parent fb05594b50
commit 2afa5a42c7
25 changed files with 491 additions and 351 deletions
+67 -55
View File
@@ -129,7 +129,6 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
connect(view, &TimelineView::DragMoved, this, &TimelineWidget::ViewDragMoved);
connect(view, &TimelineView::DragLeft, this, &TimelineWidget::ViewDragLeft);
connect(view, &TimelineView::DragDropped, this, &TimelineWidget::ViewDragDropped);
ConnectViewSelectionSignal(view);
connect(tview->splitter(), &QSplitter::splitterMoved, this, &TimelineWidget::UpdateHorizontalSplitters);
@@ -163,21 +162,19 @@ TimelineWidget::~TimelineWidget()
void TimelineWidget::Clear()
{
foreach (TimelineAndTrackView* tview, views_) {
DisconnectViewSelectionSignal(tview->view());
}
QList<Block*> deselected_blocks;
QMap<Block*, TimelineViewBlockItem*>::const_iterator iterator;
for (iterator=block_items_.begin(); iterator!=block_items_.end(); iterator++) {
if (iterator.value()->isSelected()) {
deselected_blocks.append(iterator.key());
}
delete iterator.value();
}
block_items_.clear();
foreach (TimelineAndTrackView* tview, views_) {
ConnectViewSelectionSignal(tview->view());
}
emit SelectionChanged(QList<Block*>());
emit BlocksDeselected(deselected_blocks);
SetTimebase(0);
}
@@ -379,24 +376,34 @@ rational TimelineWidget::GetToolTipTimebase() const
void TimelineWidget::SelectAll()
{
foreach (TimelineAndTrackView* view, views_) {
DisconnectViewSelectionSignal(view->view());
view->view()->SelectAll();
ConnectViewSelectionSignal(view->view());
QList<Block*> blocks_selected;
QMap<Block*, TimelineViewBlockItem*>::const_iterator i;
for (i=block_items_.constBegin(); i!=block_items_.end(); i++) {
if (!i.value()->isSelected()) {
i.value()->setSelected(true);
blocks_selected.append(i.key());
}
}
ViewSelectionChanged();
emit BlocksSelected(blocks_selected);
}
void TimelineWidget::DeselectAll()
{
foreach (TimelineAndTrackView* view, views_) {
DisconnectViewSelectionSignal(view->view());
view->view()->DeselectAll();
ConnectViewSelectionSignal(view->view());
QList<Block*> blocks_deselected;
QMap<Block*, TimelineViewBlockItem*>::const_iterator i;
for (i=block_items_.constBegin(); i!=block_items_.end(); i++) {
if (i.value()->isSelected()) {
i.value()->setSelected(false);
blocks_deselected.append(i.key());
}
}
emit SelectionChanged(QList<Block*>());
emit BlocksDeselected(blocks_deselected);
}
void TimelineWidget::RippleToIn()
@@ -803,16 +810,6 @@ TrackOutput *TimelineWidget::GetTrackFromReference(const TrackReference &ref)
return GetConnectedNode()->track_list(ref.type())->GetTrackAt(ref.index());
}
void TimelineWidget::ConnectViewSelectionSignal(TimelineView *view)
{
connect(view, &TimelineView::SelectionChanged, this, &TimelineWidget::ViewSelectionChanged);
}
void TimelineWidget::DisconnectViewSelectionSignal(TimelineView *view)
{
disconnect(view, &TimelineView::SelectionChanged, this, &TimelineWidget::ViewSelectionChanged);
}
int TimelineWidget::GetTrackY(const TrackReference &ref)
{
return views_.at(ref.type())->view()->GetTrackY(ref.index());
@@ -983,22 +980,6 @@ void TimelineWidget::TrackIndexChanged()
}
}
void TimelineWidget::ViewSelectionChanged()
{
if (rubberband_.isVisible()) {
return;
}
QList<TimelineViewBlockItem*> selected_items = GetSelectedBlocks();
QList<Block*> selected_blocks;
foreach (TimelineViewBlockItem* item, selected_items) {
selected_blocks.append(item->block());
}
emit SelectionChanged(selected_blocks);
}
void TimelineWidget::BlockRefreshed()
{
TimelineViewRect* rect = block_items_.value(static_cast<Block*>(sender()));
@@ -1393,6 +1374,14 @@ void TimelineWidget::StartRubberBandSelect(bool enable_selecting, bool select_li
drag_origin_ = QCursor::pos();
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 (TimelineViewBlockItem* block, block_items_) {
if (block->isSelected()) {
rubberband_already_selected_.append(block);
}
}
MoveRubberBandSelect(enable_selecting, select_links);
}
@@ -1408,10 +1397,11 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
QList<QGraphicsItem*> new_selected_list;
// Determine all items in the rubberband
foreach (TimelineAndTrackView* tview, views_) {
// Map global mouse coordinates to viewport
TimelineView* view = tview->view();
// Map global mouse coordinates to viewport
QRect mapped_rect(view->viewport()->mapFromGlobal(drag_origin_),
view->viewport()->mapFromGlobal(rubberband_now));
@@ -1421,13 +1411,25 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
new_selected_list.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--;
}
}
}
foreach (QGraphicsItem* item, rubberband_now_selected_) {
item->setSelected(false);
}
foreach (QGraphicsItem* item, new_selected_list) {
TimelineViewBlockItem* block_item = dynamic_cast<TimelineViewBlockItem*>(item);
if (!block_item || block_item->block()->type() == Block::kGap) {
// 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;
}
@@ -1436,18 +1438,22 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
continue;
}
// Since new_selected_list is filtered by rubberband_already_selected_, this should certainly
// be deselected by now
block_item->setSelected(true);
if (select_links) {
// Select the block's links
Block* b = block_item->block();
SetBlockLinksSelected(b, true);
// Add its links to the list
TimelineViewBlockItem* link_item;
foreach (Block* link, b->linked_clips()) {
if ((link_item = block_items_[link]) != nullptr) {
if (!new_selected_list.contains(link_item)) {
link_item->setSelected(true);
if (!new_selected_list.contains(link_item)
&& !rubberband_already_selected_.contains(link_item)) {
new_selected_list.append(link_item);
}
}
@@ -1458,13 +1464,19 @@ void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_lin
rubberband_now_selected_ = new_selected_list;
}
void TimelineWidget::EndRubberBandSelect(bool enable_selecting, bool select_links)
void TimelineWidget::EndRubberBandSelect()
{
MoveRubberBandSelect(enable_selecting, select_links);
rubberband_.hide();
rubberband_now_selected_.clear();
ViewSelectionChanged();
// 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);
rubberband_now_selected_.clear();
rubberband_already_selected_.clear();
}
struct SnapData {
+5 -8
View File
@@ -104,7 +104,9 @@ public:
void RestoreSplitterState(const QByteArray& state);
signals:
void SelectionChanged(const QList<Block*>& selected_blocks);
void BlocksSelected(const QList<Block*>& selected_blocks);
void BlocksDeselected(const QList<Block*>& deselected_blocks);
protected:
virtual void resizeEvent(QResizeEvent *event) override;
@@ -474,8 +476,9 @@ private:
void StartRubberBandSelect(bool enable_selecting, bool select_links);
void MoveRubberBandSelect(bool enable_selecting, bool select_links);
void EndRubberBandSelect(bool enable_selecting, bool select_links);
void EndRubberBandSelect();
QRubberBand rubberband_;
QList<QGraphicsItem*> rubberband_already_selected_;
QList<QGraphicsItem*> rubberband_now_selected_;
Tool* GetActiveTool();
@@ -496,10 +499,6 @@ private:
TrackOutput* GetTrackFromReference(const TrackReference& ref);
void ConnectViewSelectionSignal(TimelineView* view);
void DisconnectViewSelectionSignal(TimelineView* view);
QList<TimelineAndTrackView*> views_;
TimeSlider* timecode_label_;
@@ -539,8 +538,6 @@ private slots:
void RemoveTrack(TrackOutput* track);
void TrackIndexChanged();
void ViewSelectionChanged();
/**
* @brief Slot for when a Block node changes its parameters and the graphics need to update
*
+19 -1
View File
@@ -78,16 +78,23 @@ void TimelineWidget::PointerTool::MousePress(TimelineViewMouseEvent *event)
// If this item is already selected, no further selection needs to be made
if (clicked_item_->isSelected()) {
// Collect item deselections
QList<Block*> deselected_blocks;
// If shift is held, deselect it
if (event->GetModifiers() & Qt::ShiftModifier) {
clicked_item_->setSelected(false);
deselected_blocks.append(clicked_item_->block());
// 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().toList());
}
}
emit parent()->BlocksDeselected(deselected_blocks);
return;
}
}
@@ -98,18 +105,29 @@ void TimelineWidget::PointerTool::MousePress(TimelineViewMouseEvent *event)
}
if (selectable_item) {
// Collect item selections
QList<Block*> selected_blocks;
// Select this item
clicked_item_->setSelected(true);
selected_blocks.append(clicked_item_->block());
// 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().toList());
}
emit parent()->BlocksSelected(selected_blocks);
} else if (event->GetButton() == Qt::LeftButton) {
// Start rubberband drag
parent()->StartRubberBandSelect(true, !(event->GetModifiers() & Qt::AltModifier));
rubberband_selecting_ = true;
}
}
@@ -150,7 +168,7 @@ void TimelineWidget::PointerTool::MouseRelease(TimelineViewMouseEvent *event)
{
if (rubberband_selecting_) {
// Finish rubberband select
parent()->EndRubberBandSelect(true, !(event->GetModifiers() & Qt::AltModifier));
parent()->EndRubberBandSelect();
rubberband_selecting_ = false;
return;
}
+1 -1
View File
@@ -51,7 +51,7 @@ void TimelineWidget::ZoomTool::MouseRelease(TimelineViewMouseEvent *event)
// Zoom into the rubberband selection
QRect screen_coords = parent()->rubberband_.geometry();
parent()->EndRubberBandSelect(false, false);
parent()->EndRubberBandSelect();
TimelineView* reference_view = parent()->views_.first()->view();
QPointF scene_topleft = reference_view->mapToScene(reference_view->mapFrom(parent(), screen_coords.topLeft()));
@@ -47,26 +47,6 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
setBackgroundRole(QPalette::Window);
setContextMenuPolicy(Qt::CustomContextMenu);
viewport()->setMouseTracking(true);
connect(scene(), &QGraphicsScene::selectionChanged, this, &TimelineView::SelectionChanged);
}
void TimelineView::SelectAll()
{
QList<QGraphicsItem*> all_items = items();
foreach (QGraphicsItem* i, all_items) {
i->setSelected(true);
}
}
void TimelineView::DeselectAll()
{
QList<QGraphicsItem*> all_items = items();
foreach (QGraphicsItem* i, all_items) {
i->setSelected(false);
}
}
void TimelineView::mousePressEvent(QMouseEvent *event)
@@ -49,10 +49,6 @@ public:
TimelineView(Qt::Alignment vertical_alignment = Qt::AlignTop,
QWidget* parent = nullptr);
void SelectAll();
void DeselectAll();
int GetTrackY(int track_index) const;
int GetTrackHeight(int track_index) const;
@@ -74,8 +70,6 @@ signals:
void DragLeft(QDragLeaveEvent* event);
void DragDropped(TimelineViewMouseEvent* event);
void SelectionChanged();
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;