MuseScore/mscore/drumtools.cpp

210 lines
7.1 KiB
C++

//=============================================================================
// MuseScore
// Linux Music Score Editor
// $Id:$
//
// Copyright (C) 2010 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 "drumtools.h"
#include "musescore.h"
#include "palette.h"
#include "libmscore/chord.h"
#include "libmscore/note.h"
#include "libmscore/drumset.h"
#include "libmscore/score.h"
#include "preferences.h"
#include "seq.h"
#include "editdrumset.h"
#include "libmscore/staff.h"
#include "libmscore/part.h"
#include "libmscore/stem.h"
#include "libmscore/mscore.h"
#include "libmscore/undo.h"
namespace Ms {
//---------------------------------------------------------
// DrumTools
//---------------------------------------------------------
DrumTools::DrumTools(QWidget* parent)
: QDockWidget(parent)
{
drumset = 0;
_score = 0;
setObjectName("drum-tools");
setWindowTitle(tr("Drum Tools"));
setAllowedAreas(Qt::DockWidgetAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea));
QWidget* w = new QWidget(this);
w->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
QHBoxLayout* layout = new QHBoxLayout;
w->setLayout(layout);
QVBoxLayout* layout1 = new QVBoxLayout;
QToolButton* tb = new QToolButton;
tb->setText(tr("Edit Drumset"));
layout1->addWidget(tb);
layout1->addStretch();
layout->addLayout(layout1);
drumPalette = new Palette;
drumPalette->setName(tr("Drums"));
drumPalette->setMag(0.8);
drumPalette->setSelectable(true);
drumPalette->setGrid(28, 60);
PaletteScrollArea* sa = new PaletteScrollArea(drumPalette);
sa->setFocusPolicy(Qt::NoFocus);
layout->addWidget(sa);
setWidget(w);
// setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
w = new QWidget(this);
setTitleBarWidget(w);
titleBarWidget()->hide();
connect(tb, SIGNAL(clicked()), SLOT(editDrumset()));
void boxClicked(int);
connect(drumPalette, SIGNAL(boxClicked(int)), SLOT(drumNoteSelected(int)));
}
//---------------------------------------------------------
// updateDrumset
//---------------------------------------------------------
void DrumTools::updateDrumset(const Drumset* ds)
{
drumPalette->clear();
drumset = ds;
if (!drumset)
return;
double _spatium = gscore->spatium();
for (int pitch = 0; pitch < 128; ++pitch) {
if (!drumset->isValid(pitch))
continue;
bool up;
int line = drumset->line(pitch);
NoteHead::Group noteHead = drumset->noteHead(pitch);
int voice = drumset->voice(pitch);
Direction dir = drumset->stemDirection(pitch);
if (dir == Direction::UP)
up = true;
else if (dir == Direction::DOWN)
up = false;
else
up = line > 4;
Chord* chord = new Chord(gscore);
chord->setDurationType(TDuration::DurationType::V_QUARTER);
chord->setStemDirection(dir);
chord->setUp(up);
chord->setTrack(voice);
Note* note = new Note(gscore);
note->setParent(chord);
note->setTrack(voice);
note->setPitch(pitch);
note->setTpcFromPitch();
note->setLine(line);
note->setPos(0.0, _spatium * .5 * line);
note->setHeadGroup(noteHead);
chord->add(note);
Stem* stem = new Stem(gscore);
stem->setLen((up ? -3.0 : 3.0) * _spatium);
chord->add(stem);
stem->setPos(chord->stemPos());
int sc = drumset->shortcut(pitch);
QString shortcut;
if (sc)
shortcut = QChar(sc);
drumPalette->append(chord, qApp->translate("drumset", drumset->name(pitch).toLatin1().data()), shortcut);
}
}
//---------------------------------------------------------
// setDrumset
//---------------------------------------------------------
void DrumTools::setDrumset(Score* s, Staff* st, const Drumset* ds)
{
if (s == _score && staff == st && drumset == ds)
return;
_score = s;
staff = st;
//drumset = ds;
updateDrumset(ds);
}
//---------------------------------------------------------
// editDrumset
//---------------------------------------------------------
void DrumTools::editDrumset()
{
EditDrumset eds(drumset, this);
if (eds.exec()) {
_score->startCmd();
_score->undo(new ChangeDrumset(staff->part()->instrument(), eds.drumset()));
mscore->updateDrumTools(eds.drumset());
if (_score->undoStack()->active()) {
_score->setLayoutAll();
_score->endCmd();
}
}
}
//---------------------------------------------------------
// drumNoteSelected
//---------------------------------------------------------
void DrumTools::drumNoteSelected(int val)
{
Element* element = drumPalette->element(val);
if (element && element->type() == Element::Type::CHORD) {
Chord* ch = static_cast<Chord*>(element);
Note* note = ch->downNote();
int ticks = MScore::defaultPlayDuration;
int pitch = note->pitch();
seq->startNote(staff->part()->instrument()->channel(0)->channel, pitch, 80, ticks, 0.0);
int track = (_score->inputState().track() / VOICES) * VOICES + element->track();
_score->inputState().setTrack(track);
_score->inputState().setDrumNote(pitch);
getAction("voice-1")->setChecked(element->voice() == 0);
getAction("voice-2")->setChecked(element->voice() == 1);
getAction("voice-3")->setChecked(element->voice() == 2);
getAction("voice-4")->setChecked(element->voice() == 3);
}
}
int DrumTools::selectedDrumNote()
{
int idx = drumPalette->getSelectedIdx();
if (idx < 0)
return -1;
Element* element = drumPalette->element(idx);
if (element && element->type() == Element::Type::CHORD) {
Chord* ch = static_cast<Chord*>(element);
Note* note = ch->downNote();
return note->pitch();
}
else {
return -1;
}
}
}