1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2011-2013 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
// as published by the Free Software Foundation and appearing in
// the file LICENSE.GPL
//=============================================================================
#include "inspector.h"
#include "inspectorAmbitus.h"
#include "libmscore/ambitus.h"
#include "libmscore/score.h"
namespace Ms {
enum AmbitusControl : char {
COLOR, VISIBLE, OFF_X, OFF_Y, // Element controls
HEADGROUP, HEADTYPE, DIRECTION, // Range controls
HASLINE,
LINEWIDTH,
TOPTPC, BOTTOMTPC, TOPOCTAVE, BOTTOMOCTAVE,
LEADINGSPACE // Segment controls
};
//---------------------------------------------------------
// InspectorAmbitus
//---------------------------------------------------------
InspectorAmbitus::InspectorAmbitus(QWidget* parent)
: InspectorElementBase(parent)
{
r.setupUi(addWidget());
s.setupUi(addWidget());
static const NoteHead::Group heads[] = {
NoteHead::Group::HEAD_NORMAL,
NoteHead::Group::HEAD_CROSS,
NoteHead::Group::HEAD_DIAMOND,
NoteHead::Group::HEAD_TRIANGLE_DOWN,
NoteHead::Group::HEAD_SLASH,
NoteHead::Group::HEAD_XCIRCLE,
NoteHead::Group::HEAD_DO,
NoteHead::Group::HEAD_RE,
NoteHead::Group::HEAD_MI,
NoteHead::Group::HEAD_FA,
NoteHead::Group::HEAD_SOL,
NoteHead::Group::HEAD_LA,
NoteHead::Group::HEAD_TI,
NoteHead::Group::HEAD_BREVIS_ALT
};
static const Tpc tpcs[] = {
Tpc::TPC_INVALID,
Tpc::TPC_C_BB, Tpc::TPC_C_B, Tpc::TPC_C, Tpc::TPC_C_S, Tpc::TPC_C_SS,
Tpc::TPC_D_BB, Tpc::TPC_D_B, Tpc::TPC_D, Tpc::TPC_D_S, Tpc::TPC_D_SS,
Tpc::TPC_E_BB, Tpc::TPC_E_B, Tpc::TPC_E, Tpc::TPC_E_S, Tpc::TPC_E_SS,
Tpc::TPC_F_BB, Tpc::TPC_F_B, Tpc::TPC_F, Tpc::TPC_F_S, Tpc::TPC_F_SS,
Tpc::TPC_G_BB, Tpc::TPC_G_B, Tpc::TPC_G, Tpc::TPC_G_S, Tpc::TPC_G_SS,
Tpc::TPC_A_BB, Tpc::TPC_A_B, Tpc::TPC_A, Tpc::TPC_A_S, Tpc::TPC_A_SS,
Tpc::TPC_B_BB, Tpc::TPC_B_B, Tpc::TPC_B, Tpc::TPC_B_S, Tpc::TPC_B_SS,
};
//
// fix order of noteheads and tpc's
//
for (int i = 0; i < int(sizeof(heads)/sizeof(*heads)); ++i)
r.noteHeadGroup->setItemData(i, int(heads[i]));
// noteHeadType starts at -1
for (int i = 0; i < 5; ++i)
r.noteHeadType->setItemData(i, i-1);
// set proper itemdata for TPC combos
for (int i = 0; i < int(sizeof(tpcs)/sizeof(*tpcs)); ++i) {
r.topTpc-> setItemData(i, tpcs[i]);
r.bottomTpc->setItemData(i, tpcs[i]);
}
// make first item of each TPC combo ("[undefined]") unselectable
const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(r.topTpc->model());
QStandardItem* item = model->item(0);
item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
model = qobject_cast<const QStandardItemModel*>(r.bottomTpc->model());
item = model->item(0);
item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
const std::vector<InspectorItem> iiList = {
{ Pid::HEAD_GROUP, 0, r.noteHeadGroup, r.resetNoteHeadGroup },
{ Pid::HEAD_TYPE, 0, r.noteHeadType, r.resetNoteHeadType },
{ Pid::MIRROR_HEAD, 0, r.direction, r.resetDirection },
{ Pid::GHOST, 0, r.hasLine, r.resetHasLine }, // recycled property
{ Pid::LINE_WIDTH, 0, r.lineWidth, r.resetLineWidth },
{ Pid::TPC1, 0, r.topTpc, nullptr },
{ Pid::FBPARENTHESIS1, 0, r.bottomTpc, nullptr }, // recycled property
{ Pid::FBPARENTHESIS3, 0, r.topOctave, nullptr }, // recycled property
{ Pid::FBPARENTHESIS4, 0, r.bottomOctave, nullptr }, // recycled property
{ Pid::LEADING_SPACE, 1, s.leadingSpace, s.resetLeadingSpace },
};
const std::vector<InspectorPanel> ppList = { { r.title, r.panel }, { s.title, s.panel } };
mapSignals(iiList, ppList);
connect(r.updateRange, SIGNAL(clicked()), this, SLOT(updateRange()) );
}
//---------------------------------------------------------
// setElement
//---------------------------------------------------------
/*
void InspectorAmbitus::setElement()
{
Ambitus* range = toRange(inspector->element());
// int octave = range->topPitch() / 12;
// static_cast<QSpinBox*>(iList[AmbitusControl::TOPOCTAVE].w)->setValue(octave);
// octave = range->bottomPitch() / 12;
// static_cast<QSpinBox*>(iList[AmbitusControl::BOTTOMOCTAVE].w)->setValue(octave);
// InspectorBase::setElement();
}
*/
//---------------------------------------------------------
// valueChanged
//---------------------------------------------------------
void InspectorAmbitus::valueChanged(int idx)
{
InspectorBase::valueChanged(idx);
// if either tpc or octave is changed, notes can have been swapped
// (to keep top above bottom): reload data
if (idx >= AmbitusControl::TOPTPC && idx <= AmbitusControl::BOTTOMOCTAVE) {
setElement();
}
}
//---------------------------------------------------------
// updateRange
// Automatically adjust range based on the score
//---------------------------------------------------------
void Ms::InspectorAmbitus::updateRange()
{
Ambitus* range = toAmbitus(inspector->element());
range->updateRange();
range->score()->startCmd();
range->triggerLayout();
range->score()->endCmd();
setElement(); // set Inspector values to range properties
valueChanged(AmbitusControl::TOPTPC); // force score to notice new range properties
}
}
|