2012-05-26 14:26:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
|
|
|
// Music Composition & Notation
|
|
|
|
//
|
|
|
|
// Copyright (C) 2010-2011 Werner Schweer
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// 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
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "tremolobar.h"
|
|
|
|
#include "score.h"
|
|
|
|
#include "undo.h"
|
|
|
|
#include "staff.h"
|
|
|
|
#include "chord.h"
|
|
|
|
#include "note.h"
|
2014-04-09 16:09:21 +02:00
|
|
|
#include "xml.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
namespace Ms {
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// TremoloBar
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
TremoloBar::TremoloBar(Score* s)
|
|
|
|
: Element(s)
|
|
|
|
{
|
2014-10-13 18:06:51 +02:00
|
|
|
setFlag(ElementFlag::ON_STAFF, true);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void TremoloBar::layout()
|
|
|
|
{
|
|
|
|
qreal _spatium = spatium();
|
|
|
|
|
2012-08-16 11:09:36 +02:00
|
|
|
if (staff() && !staff()->isTabStaff()) {
|
2012-05-26 14:26:10 +02:00
|
|
|
setbbox(QRectF());
|
|
|
|
if (!parent()) {
|
|
|
|
noteWidth = -_spatium*2;
|
|
|
|
notePos = QPointF(0.0, _spatium*3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_lw = _spatium * 0.1;
|
|
|
|
Note* note = 0;
|
|
|
|
if (note == 0) {
|
|
|
|
noteWidth = 0.0;
|
|
|
|
notePos = QPointF();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
noteWidth = note->width();
|
|
|
|
notePos = note->pos();
|
|
|
|
}
|
|
|
|
// int n = _points.size();
|
|
|
|
// int pt = 0;
|
|
|
|
// qreal x = noteWidth * .5;
|
|
|
|
// qreal y = notePos.y() - _spatium;
|
|
|
|
// qreal x2, y2;
|
|
|
|
|
2014-08-06 14:45:09 +02:00
|
|
|
QRectF bb (0, 0, _spatium, -_spatium * 5);
|
2012-05-26 14:26:10 +02:00
|
|
|
#if 0
|
|
|
|
for (int pt = 0; pt < n; ++pt) {
|
|
|
|
if (pt == (n-1))
|
|
|
|
break;
|
|
|
|
x = x2;
|
|
|
|
y = y2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
bb.adjust(-_lw, -_lw, _lw, _lw);
|
|
|
|
setbbox(bb);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// draw
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void TremoloBar::draw(QPainter* painter) const
|
|
|
|
{
|
|
|
|
QPen pen(curColor(), _lw, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
|
|
|
painter->setPen(pen);
|
|
|
|
painter->setBrush(QBrush(Qt::black));
|
|
|
|
|
|
|
|
qreal _spatium = spatium();
|
2014-05-30 10:13:29 +02:00
|
|
|
const TextStyle* st = &score()->textStyle(TextStyleType::BENCH);
|
2012-05-26 14:26:10 +02:00
|
|
|
QFont f = st->fontPx(_spatium);
|
|
|
|
painter->setFont(f);
|
|
|
|
|
|
|
|
int n = _points.size();
|
2014-08-06 10:49:16 +02:00
|
|
|
|
|
|
|
int previousTime = _points[0].time;
|
|
|
|
int previousPitch = _points[0].pitch;
|
2014-08-14 13:40:24 +02:00
|
|
|
/* we place the tremolo bars starting slightly before the
|
|
|
|
* notehead, and end it slightly after, drawing above the
|
|
|
|
* note. The values specified in Guitar Pro are very large, too
|
|
|
|
* large for the scale used in Musescore. We used the
|
|
|
|
* timeFactor and pitchFactor below to reduce these values down
|
|
|
|
* consistently to values that make sense to draw with the
|
|
|
|
* Musescore scale. */
|
|
|
|
int timeFactor = 10;
|
|
|
|
int pitchFactor = 25;
|
2014-08-06 10:49:16 +02:00
|
|
|
for (int pt = 1; pt < n; ++pt) {
|
2014-08-14 13:40:24 +02:00
|
|
|
painter->drawLine(QLineF(previousTime/timeFactor, -previousPitch/pitchFactor-_spatium*3,
|
|
|
|
_points[pt].time/timeFactor, -_points[pt].pitch/pitchFactor-_spatium*3));
|
2014-08-06 10:49:16 +02:00
|
|
|
previousTime = _points[pt].time;
|
|
|
|
previousPitch = _points[pt].pitch;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// write
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void TremoloBar::write(Xml& xml) const
|
|
|
|
{
|
|
|
|
xml.stag("TremoloBar");
|
|
|
|
foreach(const PitchValue& v, _points) {
|
|
|
|
xml.tagE(QString("point time=\"%1\" pitch=\"%2\" vibrato=\"%3\"")
|
|
|
|
.arg(v.time).arg(v.pitch).arg(v.vibrato));
|
|
|
|
}
|
|
|
|
xml.etag();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// read
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-01-11 18:10:18 +01:00
|
|
|
void TremoloBar::read(XmlReader& e)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2013-01-11 18:10:18 +01:00
|
|
|
while (e.readNextStartElement()) {
|
|
|
|
if (e.name() == "point") {
|
2012-05-26 14:26:10 +02:00
|
|
|
PitchValue pv;
|
2013-01-11 18:10:18 +01:00
|
|
|
pv.time = e.intAttribute("time");
|
|
|
|
pv.pitch = e.intAttribute("pitch");
|
|
|
|
pv.vibrato = e.intAttribute("vibrato");
|
2012-05-26 14:26:10 +02:00
|
|
|
_points.append(pv);
|
2013-01-20 19:03:20 +01:00
|
|
|
e.readNext();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
else
|
2013-01-11 18:10:18 +01:00
|
|
|
e.unknown();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
}
|
|
|
|
|