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 "inspectorBend.h"
14 #include "bendcanvas.h"
15 #include "libmscore/bend.h"
16 #include "libmscore/score.h"
17 #include "libmscore/undo.h"
18 
19 namespace Ms {
20 
21 //---------------------------------------------------------
22 //   BendType
23 //---------------------------------------------------------
24 
25 enum class BendType : char {
26       BEND, BEND_RELEASE, BEND_RELEASE_BEND, PREBEND, PREBEND_RELEASE, CUSTOM
27       };
28 
29 static const QList<PitchValue> bend
30    = { PitchValue(0, 0),   PitchValue(15, 100), PitchValue(60, 100) };
31 static const QList<PitchValue> bendRelease
32    = { PitchValue(0, 0),   PitchValue(10, 100), PitchValue(20, 100), PitchValue(30, 0), PitchValue(60, 0) };
33 static const QList<PitchValue> bendReleaseBend
34    = { PitchValue(0, 0),   PitchValue(10, 100), PitchValue(20, 100), PitchValue(30, 0), PitchValue(40, 0), PitchValue(50, 100), PitchValue(60, 100) };
35 static const QList<PitchValue> prebend
36    = { PitchValue(0, 100), PitchValue(60, 100) };
37 static const QList<PitchValue> prebendRelease
38    = { PitchValue(0, 100), PitchValue(15, 100), PitchValue(30, 0),   PitchValue(60, 0) };
39 
40 //---------------------------------------------------------
41 //   InspectorBend
42 //---------------------------------------------------------
43 
InspectorBend(QWidget * parent)44 InspectorBend::InspectorBend(QWidget* parent)
45    : InspectorElementBase(parent)
46       {
47       g.setupUi(addWidget());
48 
49       const std::vector<InspectorItem> iiList = {
50             { Pid::LINE_WIDTH,     0, g.lineWidth,   g.resetLineWidth   },
51             { Pid::PLAY,           0, g.playBend,    g.resetPlayBend    },
52             { Pid::FONT_FACE,      0, g.fontFace,    g.resetFontFace    },
53             { Pid::FONT_SIZE,      0, g.fontSize,    g.resetFontSize    },
54             { Pid::FONT_STYLE,     0, g.fontStyle,   g.resetFontStyle   },
55             };
56       const std::vector<InspectorPanel> ppList = { {g.title, g.panel} };
57 
58       mapSignals(iiList, ppList);
59 
60       g.bendType->clear();
61       g.bendType->addItem(tr("Bend"),              int(BendType::BEND)              );
62       g.bendType->addItem(tr("Bend/Release"),      int(BendType::BEND_RELEASE)      );
63       g.bendType->addItem(tr("Bend/Release/Bend"), int(BendType::BEND_RELEASE_BEND) );
64       g.bendType->addItem(tr("Prebend"),           int(BendType::PREBEND)           );
65       g.bendType->addItem(tr("Prebend/Release"),   int(BendType::PREBEND_RELEASE)   );
66       g.bendType->addItem(tr("Custom"),            int(BendType::CUSTOM)            );
67 
68       Bend* b = toBend(inspector->element());
69       g.bendCanvas->setPoints(b->points());
70       connect(g.bendType,    SIGNAL(currentIndexChanged(int)),  SLOT(bendTypeChanged(int)));
71       connect(g.bendCanvas,  SIGNAL(canvasChanged()),           SLOT(updateBend())        );
72       }
73 
74 //---------------------------------------------------------
75 //   setElement
76 //---------------------------------------------------------
77 
setElement()78 void InspectorBend::setElement()
79       {
80       InspectorElementBase::setElement();
81 
82       QList<PitchValue> points = g.bendCanvas->points();
83       if (!(g.bendType->currentIndex() == int(BendType::CUSTOM))) {  // custom bend
84             if (points == bend)
85                   g.bendType->setCurrentIndex(int(BendType::BEND));
86             else if (points == bendRelease)
87                   g.bendType->setCurrentIndex(int(BendType::BEND_RELEASE));
88             else if (points == bendReleaseBend)
89                   g.bendType->setCurrentIndex(int(BendType::BEND_RELEASE_BEND));
90             else if (points == prebend)
91                   g.bendType->setCurrentIndex(int(BendType::PREBEND));
92             else if (points == prebendRelease)
93                   g.bendType->setCurrentIndex(int(BendType::PREBEND_RELEASE));
94             else
95                   g.bendType->setCurrentIndex(int(BendType::CUSTOM));
96             }
97       }
98 
99 //---------------------------------------------------------
100 //   bendTypeChanged
101 //---------------------------------------------------------
102 
bendTypeChanged(int n)103 void InspectorBend::bendTypeChanged(int n)
104       {
105       switch (n) {
106          case 0:
107             g.bendCanvas->setPoints(bend);
108             break;
109          case 1:
110             g.bendCanvas->setPoints(bendRelease);
111             break;
112          case 2:
113             g.bendCanvas->setPoints(bendReleaseBend);
114             break;
115          case 3:
116             g.bendCanvas->setPoints(prebend);
117             break;
118          case 4:
119             g.bendCanvas->setPoints(prebendRelease);
120             break;
121          case 5:
122          default:
123             break;
124             }
125 
126       updateBend();
127       update();
128       }
129 
130 //---------------------------------------------------------
131 //   updateBend
132 //---------------------------------------------------------
133 
updateBend()134 void InspectorBend::updateBend()
135       {
136       Bend* b = toBend(inspector->element());
137       Score* sc = b->score();
138       sc->startCmd();
139       for (ScoreElement* el : b->linkList()) {
140             sc->undo(new ChangeBend(toBend(el), g.bendCanvas->points()));
141             toBend(el)->triggerLayout();
142             }
143       sc->endCmd();
144       }
145 
146 } // namespace Ms
147