2012-05-26 14:49:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
|
|
|
// Linux Music Score Editor
|
|
|
|
// $Id: navigator.cpp 5630 2012-05-15 15:07:54Z lasconic $
|
|
|
|
//
|
|
|
|
// Copyright (C) 2002-2011 Werner Schweer and others
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2.
|
|
|
|
//
|
|
|
|
// 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, write to the Free Software
|
|
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "navigator.h"
|
|
|
|
#include "musescore.h"
|
|
|
|
#include "scoreview.h"
|
|
|
|
#include "libmscore/score.h"
|
|
|
|
#include "libmscore/page.h"
|
|
|
|
#include "preferences.h"
|
|
|
|
#include "libmscore/mscore.h"
|
|
|
|
#include "libmscore/system.h"
|
|
|
|
#include "libmscore/measurebase.h"
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// showNavigator
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void MuseScore::showNavigator(bool visible)
|
|
|
|
{
|
|
|
|
Navigator* n = static_cast<Navigator*>(_navigator->widget());
|
|
|
|
if (n == 0 && visible) {
|
|
|
|
n = new Navigator(_navigator, this);
|
|
|
|
n->setScoreView(cv);
|
|
|
|
n->updateViewRect();
|
|
|
|
}
|
2012-05-31 16:24:35 +02:00
|
|
|
_navigator->setVisible(visible);
|
2012-05-26 14:49:10 +02:00
|
|
|
getAction("toggle-navigator")->setChecked(visible);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// NScrollArea
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
NScrollArea::NScrollArea(QWidget* w)
|
|
|
|
: QScrollArea(w)
|
|
|
|
{
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
|
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
setMinimumHeight(40);
|
|
|
|
setLineWidth(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// resizeEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void NScrollArea::resizeEvent(QResizeEvent* ev)
|
|
|
|
{
|
|
|
|
if (widget() && (ev->size().height() != ev->oldSize().height())) {
|
|
|
|
widget()->resize(widget()->width(), ev->size().height());
|
|
|
|
}
|
|
|
|
QScrollArea::resizeEvent(ev);
|
|
|
|
}
|
|
|
|
|
2012-12-05 17:46:08 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// ViewRect
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
ViewRect::ViewRect(QWidget* w)
|
|
|
|
: QWidget(w)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// paintEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void ViewRect::paintEvent(QPaintEvent* ev)
|
|
|
|
{
|
|
|
|
QPainter p(this);
|
|
|
|
QPen pen(Qt::blue, 2.0);
|
|
|
|
p.setPen(pen);
|
|
|
|
p.setBrush(QColor(0, 0, 255, 40));
|
|
|
|
p.drawRect(ev->rect());
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// Navigator
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Navigator::Navigator(NScrollArea* sa, QWidget* parent)
|
|
|
|
: QWidget(parent)
|
|
|
|
{
|
|
|
|
setAttribute(Qt::WA_NoBackground);
|
|
|
|
_score = 0;
|
|
|
|
scrollArea = sa;
|
|
|
|
_cv = 0;
|
2012-12-05 17:46:08 +01:00
|
|
|
viewRect = new ViewRect(this);
|
2012-05-26 14:49:10 +02:00
|
|
|
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
|
|
|
sa->setWidget(this);
|
|
|
|
sa->setWidgetResizable(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// resizeEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::resizeEvent(QResizeEvent* ev)
|
|
|
|
{
|
|
|
|
if (_score) {
|
|
|
|
rescale();
|
2012-12-05 14:49:42 +01:00
|
|
|
updateViewRect();
|
|
|
|
layoutChanged();
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setScoreView
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::setScoreView(ScoreView* v)
|
|
|
|
{
|
|
|
|
if (_cv) {
|
|
|
|
disconnect(this, SIGNAL(viewRectMoved(const QRectF&)), _cv, SLOT(setViewRect(const QRectF&)));
|
|
|
|
disconnect(_cv, SIGNAL(viewRectChanged()), this, SLOT(updateViewRect()));
|
|
|
|
}
|
|
|
|
_cv = QPointer<ScoreView>(v);
|
|
|
|
if (v) {
|
|
|
|
_score = v->score();
|
|
|
|
rescale();
|
|
|
|
connect(this, SIGNAL(viewRectMoved(const QRectF&)), v, SLOT(setViewRect(const QRectF&)));
|
|
|
|
connect(_cv, SIGNAL(viewRectChanged()), this, SLOT(updateViewRect()));
|
|
|
|
updateViewRect();
|
|
|
|
layoutChanged();
|
|
|
|
rescale();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_score = 0;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setScore
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::setScore(Score* v)
|
|
|
|
{
|
|
|
|
_cv = 0;
|
2012-12-06 15:15:02 +01:00
|
|
|
_score = v;
|
2012-12-07 16:42:05 +01:00
|
|
|
rescale();
|
|
|
|
setViewRect(QRect());
|
2012-12-05 17:46:08 +01:00
|
|
|
update();
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// rescale
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::rescale()
|
|
|
|
{
|
2012-12-07 16:42:05 +01:00
|
|
|
if (!_score) {
|
|
|
|
setFixedWidth(0);
|
|
|
|
return;
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
if (_score->pages().isEmpty())
|
|
|
|
return;
|
|
|
|
int h = height();
|
|
|
|
Page* lp = _score->pages().back();
|
|
|
|
qreal scoreWidth = lp->x() + lp->width();
|
|
|
|
qreal scoreHeight = lp->height();
|
|
|
|
|
|
|
|
qreal m;
|
|
|
|
qreal m1 = h / scoreHeight;
|
|
|
|
int w1 = int (scoreWidth * m1);
|
2012-05-31 16:24:35 +02:00
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
setFixedWidth(w1);
|
|
|
|
m = m1;
|
2012-05-31 16:24:35 +02:00
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
matrix.setMatrix(m, matrix.m12(), matrix.m13(), matrix.m21(), m,
|
|
|
|
matrix.m23(), matrix.m31(), matrix.m32(), matrix.m33());
|
2012-12-05 17:46:08 +01:00
|
|
|
update();
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// updateViewRect
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::updateViewRect()
|
|
|
|
{
|
|
|
|
if (_score == 0) {
|
|
|
|
setViewRect(QRect());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (_cv) {
|
|
|
|
QRectF r(0.0, 0.0, _cv->width(), _cv->height());
|
|
|
|
setViewRect(_cv->toLogical(r));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// mousePressEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::mousePressEvent(QMouseEvent* ev)
|
|
|
|
{
|
|
|
|
if (_cv == 0)
|
|
|
|
return;
|
|
|
|
startMove = ev->pos();
|
2012-12-05 17:46:08 +01:00
|
|
|
if (!viewRect->geometry().contains(startMove)) {
|
2012-05-26 14:49:10 +02:00
|
|
|
QPointF p = matrix.inverted().map(QPointF(ev->pos()));
|
|
|
|
QRectF r(_cv->toLogical(QRectF(0.0, 0.0, _cv->width(), _cv->height())));
|
|
|
|
double dx = p.x() - (r.x() + (r.width() * .5));
|
|
|
|
double dy = p.y() - (r.y() + (r.height() * .5));
|
|
|
|
r.translate(dx, dy);
|
|
|
|
setViewRect(r);
|
2012-12-05 17:46:08 +01:00
|
|
|
emit viewRectMoved(matrix.inverted().mapRect(viewRect->geometry()));
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// mouseMoveEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::mouseMoveEvent(QMouseEvent* ev)
|
|
|
|
{
|
|
|
|
QPoint delta = ev->pos() - startMove;
|
2012-12-05 17:46:08 +01:00
|
|
|
QRect r(viewRect->geometry().translated(delta));
|
2012-05-26 14:49:10 +02:00
|
|
|
startMove = ev->pos();
|
|
|
|
|
2012-12-05 17:46:08 +01:00
|
|
|
if (r.width() == width())
|
|
|
|
r.moveLeft(0);
|
|
|
|
else if (r.width() < width()) {
|
|
|
|
if (r.x() < 0)
|
|
|
|
r.moveLeft(0);
|
|
|
|
else if (r.right() > width())
|
|
|
|
r.moveRight(width());
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
else {
|
2012-12-05 17:46:08 +01:00
|
|
|
if (r.right() < width())
|
|
|
|
r.moveRight(width());
|
|
|
|
else if (r.left() > 0)
|
|
|
|
r.moveLeft(0);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
2012-12-05 17:46:08 +01:00
|
|
|
if (r.height() == height())
|
|
|
|
r.moveTop(0);
|
|
|
|
else if (r.height() < height()) {
|
|
|
|
if (r.y() < 0)
|
|
|
|
r.moveTop(0);
|
|
|
|
else if (r.bottom() > height())
|
|
|
|
r.moveBottom(height());
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
else {
|
2012-12-05 17:46:08 +01:00
|
|
|
if (r.bottom() < height())
|
|
|
|
r.moveBottom(height());
|
|
|
|
else if (r.top() > 0)
|
|
|
|
r.moveTop(0);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
2012-12-05 17:46:08 +01:00
|
|
|
viewRect->setGeometry(r);
|
|
|
|
|
|
|
|
emit viewRectMoved(matrix.inverted().mapRect(r));
|
|
|
|
int x = delta.x() > 0 ? r.x() + r.width() : r.x();
|
2012-05-26 14:49:10 +02:00
|
|
|
scrollArea->ensureVisible(x, height()/2, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setViewRect
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::setViewRect(const QRectF& _viewRect)
|
|
|
|
{
|
2012-12-05 17:46:08 +01:00
|
|
|
viewRect->setGeometry(matrix.mapRect(_viewRect).toRect());
|
|
|
|
scrollArea->ensureVisible(viewRect->x(), 0);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// paintElement
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
static void paintElement(void* data, Element* e)
|
|
|
|
{
|
|
|
|
QPainter* p = static_cast<QPainter*>(data);
|
2012-12-05 14:49:42 +01:00
|
|
|
QPointF pos(e->pagePos());
|
|
|
|
p->translate(pos);
|
2012-05-26 14:49:10 +02:00
|
|
|
e->draw(p);
|
2012-12-05 14:49:42 +01:00
|
|
|
p->translate(-pos);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// layoutChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::layoutChanged()
|
|
|
|
{
|
2012-12-05 17:46:08 +01:00
|
|
|
if (_score && !_score->pages().isEmpty())
|
|
|
|
rescale();
|
2012-05-26 14:49:10 +02:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// paintEvent
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Navigator::paintEvent(QPaintEvent* ev)
|
|
|
|
{
|
|
|
|
QPainter p(this);
|
|
|
|
QRect r(ev->rect());
|
2012-12-05 14:49:42 +01:00
|
|
|
p.fillRect(r, Qt::gray);
|
|
|
|
|
|
|
|
if (!_score)
|
|
|
|
return;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
2012-12-05 14:49:42 +01:00
|
|
|
p.setTransform(matrix);
|
|
|
|
QRectF fr = matrix.inverted().mapRect(QRectF(r));
|
|
|
|
|
|
|
|
foreach (Page* page, _score->pages()) {
|
|
|
|
QPointF pos(page->pos());
|
|
|
|
QRectF pr(page->abbox().translated(pos));
|
|
|
|
if (pr.right() < fr.left())
|
|
|
|
continue;
|
|
|
|
if (pr.left() > fr.right())
|
|
|
|
break;
|
|
|
|
|
|
|
|
p.fillRect(pr, Qt::white);
|
|
|
|
p.translate(pos);
|
|
|
|
foreach(System* s, *page->systems()) {
|
|
|
|
foreach(MeasureBase* m, s->measures())
|
|
|
|
m->scanElements(&p, paintElement, false);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
2012-12-05 14:49:42 +01:00
|
|
|
page->scanElements(&p, paintElement, false);
|
|
|
|
if (page->score()->layoutMode() == LayoutPage) {
|
|
|
|
p.setFont(QFont("FreeSans", 400)); // !!
|
|
|
|
p.setPen(QColor(0, 0, 255, 50));
|
|
|
|
p.drawText(page->bbox(), Qt::AlignCenter, QString("%1").arg(page->no()+1));
|
|
|
|
}
|
|
|
|
p.translate(-pos);
|
2012-05-26 14:49:10 +02:00
|
|
|
}
|
|
|
|
}
|