MuseScore/mscore/fretproperties.cpp

352 lines
12 KiB
C++

//=============================================================================
// MusE Score
// Linux Music Score Editor
// $Id:$
//
// Copyright (C) 2010-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 "libmscore/fret.h"
#include "fretproperties.h"
#include "libmscore/measure.h"
#include "libmscore/system.h"
#include "libmscore/score.h"
//#include "libmscore/stringdata.h"
#include "fretcanvas.h"
#include "preferences.h"
#include "libmscore/chord.h"
#include "libmscore/note.h"
#include "libmscore/segment.h"
namespace Ms {
//---------------------------------------------------------
// FretDiagramProperties
//---------------------------------------------------------
FretDiagramProperties::FretDiagramProperties(FretDiagram* _fd, QWidget* parent)
: QDialog(parent)
{
setupUi(this);
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
fd = _fd;
frets->setValue(fd->frets());
strings->setValue(fd->strings());
diagram->setFretDiagram(fd);
diagramScrollBar->setRange(0, fd->maxFrets());
diagramScrollBar->setValue(fd->fretOffset());
connect(strings, SIGNAL(valueChanged(int)), SLOT(stringsChanged(int)));
connect(frets, SIGNAL(valueChanged(int)), SLOT(fretsChanged(int)));
connect(diagramScrollBar, SIGNAL(valueChanged(int)), SLOT(fretOffsetChanged(int)));
}
//---------------------------------------------------------
// fretsChanged
//---------------------------------------------------------
void FretDiagramProperties::fretsChanged(int val)
{
fd->setFrets(val);
diagram->update();
}
//---------------------------------------------------------
// stringsChanged
//---------------------------------------------------------
void FretDiagramProperties::stringsChanged(int val)
{
fd->setStrings(val);
diagram->update();
}
//---------------------------------------------------------
// fretOffsetChanged
//---------------------------------------------------------
void FretDiagramProperties::fretOffsetChanged(int val)
{
fd->setFretOffset(val);
diagram->update();
}
//---------------------------------------------------------
// paintEvent
//---------------------------------------------------------
void FretCanvas::paintEvent(QPaintEvent* ev)
{
double mag = 1.5;
double _spatium = 20.0 * mag;
double lw1 = _spatium * 0.08;
int fretOffset = diagram->fretOffset();
double lw2 = fretOffset ? lw1 : _spatium * 0.2;
double stringDist = _spatium * .7;
double fretDist = _spatium * .8;
int _strings = diagram->strings();
int _frets = diagram->frets();
int _barre = diagram->barre();
double w = (_strings - 1) * stringDist;
double xo = (width() - w) * .5;
double h = (_frets * fretDist) + fretDist * .5;
double yo = (height() - h) * .5;
QFont font("FreeSans");
int size = lrint(18.0 * mag);
font.setPixelSize(size);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing, preferences.antialiasedDrawing);
p.setRenderHint(QPainter::TextAntialiasing, true);
p.translate(xo, yo);
QPen pen(p.pen());
pen.setWidthF(lw2);
pen.setCapStyle(Qt::FlatCap);
p.setPen(pen);
p.setBrush(pen.color());
double x2 = (_strings-1) * stringDist;
p.drawLine(QLineF(-lw1 * .5, 0.0, x2+lw1*.5, 0.0));
pen.setWidthF(lw1);
p.setPen(pen);
double y2 = (_frets+1) * fretDist - fretDist*.5;
for (int i = 0; i < _strings; ++i) {
double x = stringDist * i;
p.drawLine(QLineF(x, fretOffset ? -_spatium*.2 : 0.0, x, y2));
}
for (int i = 1; i <= _frets; ++i) {
double y = fretDist * i;
p.drawLine(QLineF(0.0, y, x2, y));
}
for (int i = 0; i < _strings; ++i) {
p.setPen(Qt::NoPen);
if (diagram->dot(i)) {
double dotd = stringDist * .6 + lw1;
int fret = diagram->dot(i) - 1;
double x = stringDist * i - dotd * .5;
double y = fretDist * fret + fretDist * .5 - dotd * .5;
p.drawEllipse(QRectF(x, y, dotd, dotd));
}
p.setPen(pen);
if (diagram->marker(i)) {
p.setFont(font);
double x = stringDist * i;
double y = -fretDist * .1;
p.drawText(QRectF(x, y, 0.0, 0.0),
Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, QChar(diagram->marker(i)));
}
}
if (_barre) {
int string = -1;
for (int i = 0; i < _strings; ++i) {
if (diagram->dot(i) == _barre) {
string = i;
break;
}
}
if (string != -1) {
qreal x1 = stringDist * string;
qreal x2 = stringDist * (_strings-1);
qreal y = fretDist * (_barre-1) + fretDist * .5;
pen.setWidthF(stringDist * .6 * .7); // dont use style barreLineWidth
pen.setCapStyle(Qt::RoundCap);
p.setPen(pen);
p.drawLine(QLineF(x1, y, x2, y));
}
}
if ((cfret > 0) && (cfret <= _frets) && (cstring >= 0) && (cstring < _strings)) {
double dotd;
if (diagram->dot(cstring) != cfret) {
p.setPen(Qt::NoPen);
dotd = stringDist * .6 + lw1;
}
else {
p.setPen(pen);
dotd = stringDist * .6;
}
double x = stringDist * cstring - dotd * .5;
double y = fretDist * (cfret-1) + fretDist * .5 - dotd * .5;
p.setBrush(Qt::lightGray);
p.drawEllipse(QRectF(x, y, dotd, dotd));
}
if (fretOffset > 0) {
qreal fretNumMag = 2.0; // TODO: get the value from StyleIdx::fretNumMag
QFont scaledFont(font);
scaledFont.setPixelSize(font.pixelSize() * fretNumMag);
p.setFont(scaledFont);
p.setPen(pen);
// Todo: make dependant from StyleIdx::fretNumPos
p.drawText(QRectF(-stringDist * .4, 0.0, 0.0, fretDist),
Qt::AlignVCenter|Qt::AlignRight|Qt::TextDontClip,
QString("%1").arg(fretOffset+1));
p.setFont(font);
}
QFrame::paintEvent(ev);
}
//---------------------------------------------------------
// getPosition
//---------------------------------------------------------
void FretCanvas::getPosition(const QPointF& p, int* string, int* fret)
{
double mag = 1.5;
double _spatium = 20.0 * mag;
int _strings = diagram->strings();
int _frets = diagram->frets();
double stringDist = _spatium * .7;
double fretDist = _spatium * .8;
double w = (_strings - 1) * stringDist;
double xo = (width() - w) * .5;
double h = (_frets * fretDist) + fretDist * .5;
double yo = (height() - h) * .5;
*fret = (p.y() - yo + fretDist) / fretDist;
*string = (p.x() - xo + stringDist * .5) / stringDist;
}
//---------------------------------------------------------
// mousePressEvent
//---------------------------------------------------------
void FretCanvas::mousePressEvent(QMouseEvent* ev)
{
int string;
int fret;
getPosition(ev->pos(), &string, &fret);
int _strings = diagram->strings();
int _frets = diagram->frets();
if (fret < 0 || fret > _frets || string < 0 || string >= _strings)
return;
if (fret == 0) {
switch (diagram->marker(string)) {
case 'O':
diagram->setMarker(string, 'X');
break;
case 'X':
diagram->setMarker(string, 0);
break;
default:
diagram->setDot(string, 0);
diagram->setMarker(string, 'O');
break;
}
}
else {
if (diagram->dot(string) == fret) {
diagram->setDot(string, 0);
diagram->setMarker(string, 'O');
bool removeBarre = true;
if (ev->modifiers() & Qt::ShiftModifier) {
for (int i = 0; i < _strings; ++i) {
if (diagram->dot(i)) {
removeBarre = false;
break;
}
}
}
if (removeBarre)
diagram->setBarre(0);
}
else {
diagram->setDot(string, fret);
diagram->setMarker(string, 0);
if (ev->modifiers() & Qt::ShiftModifier)
diagram->setBarre(diagram->barre() == fret ? 0 : fret);
else
diagram->setBarre(0);
}
}
update();
}
//---------------------------------------------------------
// mouseMoveEvent
//---------------------------------------------------------
void FretCanvas::mouseMoveEvent(QMouseEvent* ev)
{
int string;
int fret;
getPosition(ev->pos(), &string, &fret);
if (string != cstring || cfret != fret) {
cfret = fret;
cstring = string;
update();
}
}
//---------------------------------------------------------
// mouseReleaseEvent
//---------------------------------------------------------
void FretCanvas::mouseReleaseEvent(QMouseEvent*)
{
}
//---------------------------------------------------------
// dragEnterEvent
//---------------------------------------------------------
void FretCanvas::dragEnterEvent(QDragEnterEvent*)
{
}
//---------------------------------------------------------
// dragMoveEvent
//---------------------------------------------------------
void FretCanvas::dragMoveEvent(QDragMoveEvent*)
{
}
//---------------------------------------------------------
// dropEvent
//---------------------------------------------------------
void FretCanvas::dropEvent(QDropEvent*)
{
}
//---------------------------------------------------------
// FretCanvas
//---------------------------------------------------------
FretCanvas::FretCanvas(QWidget* parent)
: QFrame(parent)
{
setAcceptDrops(true);
setFrameStyle(QFrame::Raised | QFrame::Panel);
cstring = -2;
cfret = -2;
}
//---------------------------------------------------------
// setFretDiagram
//---------------------------------------------------------
void FretCanvas::setFretDiagram(FretDiagram* fd)
{
diagram = fd;
update();
}
}