Skip to content

Commit

Permalink
NotationNavigator: decouple cursor from rest of navigator
Browse files Browse the repository at this point in the history
This avoids having to redraw the whole navigator when only the
cursor is moved, improving performance on large scores.

Resolves musescore#10201 (partially)
  • Loading branch information
bluebear94 committed Nov 4, 2023
1 parent 9b07303 commit b49dd18
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 27 deletions.
76 changes: 52 additions & 24 deletions src/notation/view/notationnavigator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,49 @@
*/
#include "notationnavigator.h"

#include "draw/types/geometry.h"
#include "engraving/dom/system.h"

#include "log.h"
#include <memory>
#include <qevent.h>
#include <qpainter.h>
#include <qquickitem.h>
#include <qquickpainteditem.h>
#include <qwidget.h>

using namespace mu::notation;

NotationNavigatorViewRect::NotationNavigatorViewRect(QQuickItem* parent)
: QQuickPaintedItem(parent)
{
this->setSize(parent->size()); // FIXME: doesn't set the size
}

void NotationNavigatorViewRect::paint(QPainter* painter)
{
TRACEFUNC;

QColor color(configuration()->selectionColor());
QPen pen(color, configuration()->borderWidth());
painter->setPen(pen);
painter->setBrush(QColor(color.red(), color.green(), color.blue(), configuration()->cursorOpacity()));

painter->drawRect(m_cursorRect.toQRectF());
}

mu::RectF NotationNavigatorViewRect::getRect()
{
return m_cursorRect;
}

void NotationNavigatorViewRect::setRect(RectF cursorRect)
{
m_cursorRect = cursorRect;
}

NotationNavigator::NotationNavigator(QQuickItem* parent)
: AbstractNotationPaintView(parent)
: AbstractNotationPaintView(parent), m_viewRect(std::make_unique<NotationNavigatorViewRect>(this))
{
setReadonly(true);
}
Expand All @@ -42,6 +77,7 @@ void NotationNavigator::load()

uiConfiguration()->currentThemeChanged().onNotify(this, [this]() {
update();
m_viewRect->update();
});

AbstractNotationPaintView::load();
Expand Down Expand Up @@ -103,14 +139,15 @@ void NotationNavigator::mousePressEvent(QMouseEvent* event)
{
TRACEFUNC;

RectF cursorRect = m_viewRect->getRect();
PointF logicPos = toLogical(event->pos());
m_startMove = logicPos;
if (m_cursorRect.contains(logicPos)) {
if (cursorRect.contains(logicPos)) {
return;
}

double dx = logicPos.x() - (m_cursorRect.x() + (m_cursorRect.width() / 2));
double dy = logicPos.y() - (m_cursorRect.y() + (m_cursorRect.height() / 2));
double dx = logicPos.x() - (cursorRect.x() + (cursorRect.width() / 2));
double dy = logicPos.y() - (cursorRect.y() + (cursorRect.height() / 2));

moveNotationRequested(-dx, -dy);
}
Expand All @@ -126,7 +163,7 @@ void NotationNavigator::mouseMoveEvent(QMouseEvent* event)
m_startMove = logicPos;
}

void NotationNavigator::moveCanvasToRect(const RectF& viewRect)
bool NotationNavigator::moveCanvasToRect(const RectF& viewRect)
{
TRACEFUNC;

Expand All @@ -144,7 +181,7 @@ void NotationNavigator::moveCanvasToRect(const RectF& viewRect)
PointF bottom = newViewRect.bottomRight();

if (!notationContentRect.contains(top) && !notationContentRect.contains(bottom)) {
return;
return false;
}

if (viewport.top() > top.y()) {
Expand All @@ -159,7 +196,7 @@ void NotationNavigator::moveCanvasToRect(const RectF& viewRect)
PointF right = newViewRect.bottomRight();

if (!notationContentRect.contains(left) && !notationContentRect.contains(right)) {
return;
return false;
}

if (viewport.left() > left.x()) {
Expand All @@ -169,7 +206,7 @@ void NotationNavigator::moveCanvasToRect(const RectF& viewRect)
}
}

moveCanvas(-dx, -dy);
return moveCanvas(-dx, -dy);
}

void NotationNavigator::setCursorRect(const QRectF& rect)
Expand All @@ -182,11 +219,15 @@ void NotationNavigator::setCursorRect(const QRectF& rect)

RectF newCursorRect = notationContentRect().intersected(RectF::fromQRectF(rect));

moveCanvasToRect(newCursorRect);
bool moved = moveCanvasToRect(newCursorRect);

m_viewRect->setRect(newCursorRect);

m_cursorRect = newCursorRect;
rescale();
update();
if (moved) {
update();
}
m_viewRect->update();
}

int NotationNavigator::orientation() const
Expand Down Expand Up @@ -238,25 +279,12 @@ void NotationNavigator::paint(QPainter* painter)
AbstractNotationPaintView::paint(painter);

paintPageNumbers(painter);
paintCursor(painter);
}

void NotationNavigator::onViewSizeChanged()
{
}

void NotationNavigator::paintCursor(QPainter* painter)
{
TRACEFUNC;

QColor color(configuration()->selectionColor());
QPen pen(color, configuration()->borderWidth());
painter->setPen(pen);
painter->setBrush(QColor(color.red(), color.green(), color.blue(), configuration()->cursorOpacity()));

painter->drawRect(m_cursorRect.toQRectF());
}

void NotationNavigator::paintPageNumbers(QPainter* painter)
{
if (notationViewMode() != ViewMode::PAGE) {
Expand Down
26 changes: 23 additions & 3 deletions src/notation/view/notationnavigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@
#include <QMouseEvent>
#include <QPainter>
#include <QQuickPaintedItem>
#include <memory>
#include <qpainter.h>
#include <qquickpainteditem.h>
#include <qwidget.h>

#include "draw/types/geometry.h"
#include "modularity/ioc.h"
#include "async/asyncable.h"
#include "inotationconfiguration.h"
Expand All @@ -36,6 +41,22 @@
#include "abstractnotationpaintview.h"

namespace mu::notation {
class NotationNavigatorViewRect : public QQuickPaintedItem
{
Q_OBJECT

INJECT(INotationConfiguration, configuration)

virtual void paint(QPainter* painter) override;
RectF m_cursorRect;

public:
NotationNavigatorViewRect(QQuickItem* parent = nullptr);

RectF getRect();
void setRect(RectF cursorRect);
};

class NotationNavigator : public AbstractNotationPaintView
{
Q_OBJECT
Expand Down Expand Up @@ -76,16 +97,15 @@ class NotationNavigator : public AbstractNotationPaintView
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;

void paintCursor(QPainter* painter);
void paintPageNumbers(QPainter* painter);

void moveCanvasToRect(const RectF& viewRect);
bool moveCanvasToRect(const RectF& viewRect);

bool isVerticalOrientation() const;

PageList pages() const;

RectF m_cursorRect;
std::unique_ptr<NotationNavigatorViewRect> m_viewRect;
PointF m_startMove;
};
}
Expand Down

0 comments on commit b49dd18

Please sign in to comment.