1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2010-2019 Werner Schweer and others
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENSE.GPL
11 //=============================================================================
12 
13 #include "inspectorTremoloBar.h"
14 #include "tremolobarcanvas.h"
15 #include "musescore.h"
16 #include "libmscore/tremolobar.h"
17 #include "libmscore/undo.h"
18 
19 namespace Ms {
20 
21 //---------------------------------------------------------
22 //   TremoloBarType
23 //---------------------------------------------------------
24 
25 enum class TremoloBarType : char {
26       DIP, DIVE, RELEASE_UP, INVERTED_DIP, RETURN, RELEASE_DOWN, CUSTOM
27       };
28 
29 static const QList<PitchValue> Dip
30    = { PitchValue(0, 0),    PitchValue(30, -100), PitchValue(60, 0) };
31 static const QList<PitchValue> Dive
32    = { PitchValue(0, 0),    PitchValue(60, -150) };
33 static const QList<PitchValue> ReleaseUp
34    = { PitchValue(0, -150), PitchValue(60, 0)    };
35 static const QList<PitchValue> InvertedDip
36    = { PitchValue(0, 0),    PitchValue(30, 100),  PitchValue(60, 0) };
37 static const QList<PitchValue> Return
38    = { PitchValue(0, 0),    PitchValue(60, 150)  };
39 static const QList<PitchValue> ReleaseDown
40    = { PitchValue(0, 150),  PitchValue(60, 0)    };
41 
42 //---------------------------------------------------------
43 //   InspectorTremoloBar
44 //---------------------------------------------------------
45 
InspectorTremoloBar(QWidget * parent)46 InspectorTremoloBar::InspectorTremoloBar(QWidget* parent)
47    : InspectorElementBase(parent)
48       {
49       g.setupUi(addWidget());
50 
51       const std::vector<InspectorItem> iiList = {
52             { Pid::PLAY,       0, g.play,        g.resetPlay        },
53             { Pid::LINE_WIDTH, 0, g.lineWidth,   g.resetLineWidth   },
54             { Pid::MAG,        0, g.mag,         g.resetMag         }
55             };
56       const std::vector<InspectorPanel> ppList = { { g.title, g.panel } };
57 
58       mapSignals(iiList, ppList);
59 
60       g.tremoloBarType->clear();
61       g.tremoloBarType->addItem(tr("Dip"),            int(TremoloBarType::DIP)          );
62       g.tremoloBarType->addItem(tr("Dive"),           int(TremoloBarType::DIVE)         );
63       g.tremoloBarType->addItem(tr("Release (Up)"),   int(TremoloBarType::RELEASE_UP)   );
64       g.tremoloBarType->addItem(tr("Inverted Dip"),   int(TremoloBarType::INVERTED_DIP) );
65       g.tremoloBarType->addItem(tr("Return"),         int(TremoloBarType::RETURN)       );
66       g.tremoloBarType->addItem(tr("Release (Down)"), int(TremoloBarType::RELEASE_DOWN) );
67       g.tremoloBarType->addItem(tr("Custom"),         int(TremoloBarType::CUSTOM)       );
68 
69       TremoloBar* tb = toTremoloBar(inspector->element());
70       g.tremoloBarCanvas->setPoints(tb->points());
71       connect(g.tremoloBarType,   SIGNAL(currentIndexChanged(int)),  SLOT(tremoloBarTypeChanged(int)));
72       connect(g.tremoloBarCanvas, SIGNAL(canvasChanged()), SLOT(updateTremoloBar())        );
73       }
74 
75 //---------------------------------------------------------
76 //   setElement
77 //---------------------------------------------------------
78 
setElement()79 void InspectorTremoloBar::setElement()
80       {
81       InspectorElementBase::setElement();
82 
83       QList<PitchValue> points = g.tremoloBarCanvas->points();
84       if (!(g.tremoloBarType->currentIndex() == int(TremoloBarType::CUSTOM))) { // custom tremolo bar
85             if (points == Dip)
86                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::DIP));
87             else if (points == Dive)
88                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::DIVE));
89             else if (points == ReleaseUp)
90                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::RELEASE_UP));
91             else if (points == InvertedDip)
92                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::INVERTED_DIP));
93             else if (points == Return)
94                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::RETURN));
95             else if (points == ReleaseDown)
96                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::RELEASE_DOWN));
97             else
98                   g.tremoloBarType->setCurrentIndex(int(TremoloBarType::CUSTOM));
99             }
100       }
101 
102 //---------------------------------------------------------
103 //   tremoloBarTypeChange
104 //---------------------------------------------------------
105 
tremoloBarTypeChanged(int n)106 void InspectorTremoloBar::tremoloBarTypeChanged(int n)
107       {
108       switch (n) {
109          case 0:
110             g.tremoloBarCanvas->setPoints(Dip);
111             break;
112          case 1:
113             g.tremoloBarCanvas->setPoints(Dive);
114             break;
115          case 2:
116             g.tremoloBarCanvas->setPoints(ReleaseUp);
117             break;
118          case 3:
119             g.tremoloBarCanvas->setPoints(InvertedDip);
120             break;
121          case 4:
122             g.tremoloBarCanvas->setPoints(Return);
123             break;
124          case 5:
125             g.tremoloBarCanvas->setPoints(ReleaseDown);
126             break;
127          case 6:
128          default:
129             break;
130             }
131 
132       updateTremoloBar();
133       update();
134       }
135 
136 //---------------------------------------------------------
137 //   updateTremoloBar
138 //---------------------------------------------------------
139 
updateTremoloBar()140 void InspectorTremoloBar::updateTremoloBar()
141       {
142       TremoloBar* tb = toTremoloBar(inspector->element());
143       Score* sc = tb->score();
144       sc->startCmd();
145       for (ScoreElement* el : tb->linkList()) {
146             sc->undo(new ChangeTremoloBar(toTremoloBar(el), g.tremoloBarCanvas->points()));
147             toTremoloBar(el)->triggerLayout();
148             }
149       sc->endCmd();
150       }
151 
152 } // namespace Ms
153