MuseScore/mscore/navigator.cpp

334 lines
9.9 KiB
C++
Raw Normal View History

2012-05-26 14:49:10 +02:00
//=============================================================================
// MuseScore
2013-05-08 10:54:06 +02:00
// Music Composition & Notation
2012-05-26 14:49:10 +02:00
//
2013-05-08 10:54:06 +02:00
// Copyright (C) 2002-2013 Werner Schweer
2012-05-26 14:49:10 +02:00
//
// This program is free software; you can redistribute it and/or modify
2013-05-08 10:54:06 +02:00
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
2012-05-26 14:49:10 +02:00
//=============================================================================
#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"
2013-05-13 18:49:17 +02:00
namespace Ms {
2012-05-26 14:49:10 +02:00
//---------------------------------------------------------
// 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);
}
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)
{
2013-05-08 10:54:06 +02:00
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
2012-05-26 14:49:10 +02:00
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setMinimumHeight(40);
2013-05-08 10:54:06 +02:00
setMaximumHeight(140);
2012-05-26 14:49:10 +02:00
setLineWidth(0);
}
//---------------------------------------------------------
// resizeEvent
//---------------------------------------------------------
void NScrollArea::resizeEvent(QResizeEvent* ev)
{
2013-05-08 10:54:06 +02:00
if (widget() && (ev->size().height() != ev->oldSize().height()))
2012-05-26 14:49:10 +02:00
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);
2013-07-04 21:07:38 +02:00
QPen pen(MScore::selectColor[0], 2.0);
2012-12-05 17:46:08 +01:00
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;
2013-05-08 10:54:06 +02:00
scrollArea->setWidgetResizable(true);
2012-05-26 14:49:10 +02:00
_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();
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()));
rescale();
2013-05-08 10:54:06 +02:00
updateViewRect();
2012-05-26 14:49:10 +02:00
}
else {
_score = 0;
update();
}
}
//---------------------------------------------------------
// setScore
//---------------------------------------------------------
void Navigator::setScore(Score* v)
{
2013-05-08 10:54:06 +02:00
_cv = 0;
_score = v;
rescale();
2013-05-08 10:54:06 +02:00
updateViewRect();
2012-12-05 17:46:08 +01:00
update();
2012-05-26 14:49:10 +02:00
}
//---------------------------------------------------------
// rescale
2013-05-08 10:54:06 +02:00
// recompute scale of score view
2012-05-26 14:49:10 +02:00
//---------------------------------------------------------
void Navigator::rescale()
{
2013-05-08 10:54:06 +02:00
if (!_score || _score->pages().isEmpty()) {
setFixedWidth(0);
return;
}
2013-05-08 10:54:06 +02:00
Page* lp = _score->pages().back();
2012-05-26 14:49:10 +02:00
qreal scoreWidth = lp->x() + lp->width();
qreal scoreHeight = lp->height();
2013-05-08 10:54:06 +02:00
qreal m = height() / scoreHeight;
2012-05-31 16:24:35 +02:00
2013-05-08 10:54:06 +02:00
setFixedWidth(int(scoreWidth * m));
matrix = QTransform(m, 0, 0, m, 0, 0);
2012-05-26 14:49:10 +02:00
}
//---------------------------------------------------------
// updateViewRect
//---------------------------------------------------------
void Navigator::updateViewRect()
{
2013-05-08 10:54:06 +02:00
QRect r;
if (_cv)
r = _cv->toLogical(QRect(0.0, 0.0, _cv->width(), _cv->height())).toRect();
setViewRect(r);
2012-05-26 14:49:10 +02:00
}
//---------------------------------------------------------
// 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);
2013-07-09 15:12:50 +02:00
// printf("navigator paint %d %d\n", r.width(), r.height());
2012-12-05 14:49:42 +01:00
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
}
}
2013-05-13 18:49:17 +02:00
}
2012-12-10 12:06:13 +01:00