1 //=============================================================================
2 //  MuseScore
3 //  Linux Music Score Editor
4 //
5 //  Copyright (C) 2002-2016 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 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //=============================================================================
19 
20 #include "mixertrackchannel.h"
21 
22 #include "musescore.h"
23 
24 #include "libmscore/score.h"
25 #include "libmscore/part.h"
26 #include "mixer.h"
27 #include "mixertrackitem.h"
28 #include "seq.h"
29 #include "libmscore/undo.h"
30 #include "synthcontrol.h"
31 #include "audio/midi/msynthesizer.h"
32 #include "preferences.h"
33 
34 namespace Ms {
35 
36 const QString MixerTrackChannel::unselStyleLight = "#controlWidget {"
37                                        "      background: #aaa;"
38                                        "      border-left: 2px solid #ddd;"
39                                        "      border-top: 2px solid #ddd;"
40                                        "      border-right: 2px solid #777;"
41                                        "      border-bottom: 2px solid #777;"
42                                        "}";
43 
44 const QString MixerTrackChannel::selStyleLight = "#controlWidget {"
45                                      "      background: #ccc;"
46                                      "      border-left: 2px solid #eee;"
47                                      "      border-top: 2px solid #eee;"
48                                      "      border-right: 2px solid #777;"
49                                      "      border-bottom: 2px solid #777;"
50                                      "}";
51 
52 
53 const QString MixerTrackChannel::unselStyleDark = "#controlWidget {"
54                                        "      background: #444;"
55                                        "      border-left: 2px solid #888;"
56                                        "      border-top: 2px solid #888;"
57                                        "      border-right: 2px solid #000;"
58                                        "      border-bottom: 2px solid #000;"
59                                        "}"
60                                        ".expandBn {"
61                                        "     background-color: #aaa;"
62                                        "}";
63 
64 const QString MixerTrackChannel::selStyleDark = "#controlWidget {"
65                                      "      background: #666;"
66                                      "      border-left: 2px solid #888;"
67                                      "      border-top: 2px solid #888;"
68                                      "      border-right: 2px solid #000;"
69                                      "      border-bottom: 2px solid #000;"
70                                      "}"
71                                      ".expandBn {"
72                                      "     background-color: #aaa;"
73                                      "}";
74 
75 
76 //---------------------------------------------------------
77 //   MixerTrack
78 //---------------------------------------------------------
79 
MixerTrackChannel(QWidget * parent,MixerTrackItemPtr mti)80 MixerTrackChannel::MixerTrackChannel(QWidget *parent, MixerTrackItemPtr mti) :
81       QWidget(parent), _mti(mti), _selected(false), _group(0)
82       {
83       setupUi(this);
84 
85       connect(soloBn, SIGNAL(toggled(bool)), SLOT(updateSolo(bool)));
86       connect(muteBn, SIGNAL(toggled(bool)), SLOT(updateMute(bool)));
87 
88       updateNameLabel();
89 
90       //set up rest
91       Channel* chan = mti->chan();
92       soloBn->setChecked(chan->solo());
93       muteBn->setChecked(chan->mute());
94 
95       chan->addListener(this);
96       volumeSlider->setValue(chan->volume());
97       volumeSlider->setToolTip(tr("Volume: %1").arg(QString::number(chan->volume())));
98       volumeSlider->setMaxValue(127);
99       volumeSlider->setMinValue(0);
100       volumeSlider->setDoubleClickValue(Channel::defaultVolume);
101       volumeSlider->setNumMajorTicks(10);
102       volumeSlider->setNumMinorTicks(5);
103 
104       QIcon iconSliderHead;
105       iconSliderHead.addFile(QStringLiteral(":/data/icons/mixer-slider-handle-vertical.svg"), QSize(), QIcon::Normal, QIcon::Off);
106       volumeSlider->setSliderHeadIcon(iconSliderHead);
107 
108       panSlider->setValue(chan->pan());
109       panSlider->setToolTip(tr("Pan: %1").arg(QString::number(chan->pan())));
110       panSlider->setMaxValue(127);
111       panSlider->setMinValue(0);
112 
113       connect(volumeSlider, SIGNAL(valueChanged(double)),      SLOT(volumeChanged(double)));
114       connect(panSlider,    SIGNAL(valueChanged(double, int)), SLOT(panChanged(double)));
115 
116       connect(volumeSlider, SIGNAL(sliderPressed()),    SLOT(controlSelected()));
117       connect(panSlider,    SIGNAL(sliderPressed(int)), SLOT(controlSelected()));
118 
119       applyStyle();
120       }
121 
122 //---------------------------------------------------------
123 //   expandToggled
124 //---------------------------------------------------------
125 
applyStyle()126 void MixerTrackChannel::applyStyle()
127       {
128       QString style;
129       switch (preferences.effectiveGlobalStyle()){
130             case MuseScoreEffectiveStyleType::DARK_FUSION:
131                   style = _selected ? selStyleDark : unselStyleDark;
132                   break;
133             case MuseScoreEffectiveStyleType::LIGHT_FUSION:
134                   style = _selected ? selStyleLight : unselStyleLight;
135                   break;
136             }
137 
138       setStyleSheet(style);
139       }
140 
141 //---------------------------------------------------------
142 //   updateNameLabel
143 //---------------------------------------------------------
144 
updateNameLabel()145 void MixerTrackChannel::updateNameLabel()
146       {
147       Part* part = _mti->part();
148       Instrument* instr = _mti->instrument();
149       Channel* chan = _mti->chan();
150 
151       QString shortName;
152       if (instr->shortNames().count())
153             shortName = instr->shortNames().first().name() + "-";
154       else
155             shortName = "";
156       QString text = QString("%1%2").arg(shortName, qApp->translate("InstrumentsXML", chan->name().toUtf8().data()));
157       trackLabel->setText(text);
158 
159       MidiPatch* mp = synti->getPatchInfo(chan->synti(), chan->bank(), chan->program());
160 
161       QString tooltip = tr("Part Name: %1\n"
162                            "Instrument: %2\n"
163                            "Channel: %3\n"
164                            "Bank: %4\n"
165                            "Program: %5\n"
166                            "Sound: %6")
167                   .arg(part->partName(),
168                        instr->trackName(),
169                        qApp->translate("InstrumentsXML", chan->name().toUtf8().data()),
170                        QString::number(chan->bank()),
171                        QString::number(chan->program()),
172                        mp ? mp->name : tr("~no sound~"));
173 
174       trackLabel->setToolTip(tooltip);
175 
176       QColor bgCol((QRgb)chan->color());
177       QString trackColorName = bgCol.name();
178       int val = bgCol.value();
179 
180       QString trackStyle = QString(".QLabel {"
181                  "border: 2px solid black;"
182                  "background: %1;"
183                  "color: %2;"
184                  "padding: 6px 0px;"
185              "}").arg(trackColorName, val > 128 ? "black" : "white");
186 
187       trackLabel->setStyleSheet(trackStyle);
188 
189       QColor bgPartCol((QRgb)part->color());
190       QString partColorName = bgPartCol.name();
191       val = bgPartCol.value();
192 
193       //Part header
194       partLabel->setText(part->partName());
195 
196       QString partStyle = QString(".QLabel {"
197                  "border: 2px solid black;"
198                  "background: %1;"
199                  "color: %2;"
200                  "padding: 6px 0px;"
201              "}").arg(partColorName, val > 128 ? "black" : "white");
202 
203       partLabel->setStyleSheet(partStyle);
204       partLabel->setToolTip(tr("This channel is a child of part %1").arg(part->partName()));
205 
206 
207 
208       //Update component colors
209       qreal h, s, v;
210       bgCol.getHsvF(&h, &s, &v);
211       QColor brightCol = QColor::fromHsvF(h, s, 1);
212       panSlider->setScaleValueColor(brightCol);
213       volumeSlider->setHilightColor(brightCol);
214       }
215 
216 //---------------------------------------------------------
217 //   paintEvent
218 //---------------------------------------------------------
219 
paintEvent(QPaintEvent *)220 void MixerTrackChannel::paintEvent(QPaintEvent*)
221       {
222       applyStyle();
223       }
224 
225 //---------------------------------------------------------
226 //   propertyChanged
227 //---------------------------------------------------------
228 
propertyChanged(Channel::Prop property)229 void MixerTrackChannel::propertyChanged(Channel::Prop property)
230       {
231       Channel* chan = _mti->chan();
232 
233       switch (property) {
234             case Channel::Prop::VOLUME: {
235                   volumeSlider->blockSignals(true);
236                   volumeSlider->setValue(chan->volume());
237                   volumeSlider->setToolTip(tr("Volume: %1").arg(QString::number(chan->volume())));
238                   volumeSlider->blockSignals(false);
239                   break;
240                   }
241             case Channel::Prop::PAN: {
242                   panSlider->blockSignals(true);
243                   panSlider->setValue(chan->pan());
244                   panSlider->setToolTip(tr("Pan: %1").arg(QString::number(chan->pan())));
245                   panSlider->blockSignals(false);
246                   break;
247                   }
248             case Channel::Prop::MUTE: {
249                   muteBn->blockSignals(true);
250                   muteBn->setChecked(chan->mute());
251                   muteBn->blockSignals(false);
252                   break;
253                   }
254             case Channel::Prop::SOLO: {
255                   soloBn->blockSignals(true);
256                   soloBn->setChecked(chan->solo());
257                   soloBn->blockSignals(false);
258                   break;
259                   }
260             case Channel::Prop::COLOR: {
261                   updateNameLabel();
262                   break;
263                   }
264             default:
265                   break;
266             }
267       }
268 
269 //---------------------------------------------------------
270 //   volumeChanged
271 //---------------------------------------------------------
272 
volumeChanged(double value)273 void MixerTrackChannel::volumeChanged(double value)
274       {
275       _mti->setVolume(value);
276       volumeSlider->setToolTip(tr("Volume: %1").arg(QString::number(value)));
277       }
278 
279 //---------------------------------------------------------
280 //   panChanged
281 //---------------------------------------------------------
282 
panChanged(double value)283 void MixerTrackChannel::panChanged(double value)
284       {
285       _mti->setPan(value);
286       panSlider->setToolTip(tr("Pan: %1").arg(QString::number(value)));
287       }
288 
289 //---------------------------------------------------------
290 //   updateSolo
291 //---------------------------------------------------------
292 
updateSolo(bool val)293 void MixerTrackChannel::updateSolo(bool val)
294       {
295       _mti->setSolo(val);
296       }
297 
298 //---------------------------------------------------------
299 //   udpateMute
300 //---------------------------------------------------------
301 
updateMute(bool val)302 void MixerTrackChannel::updateMute(bool val)
303       {
304       _mti->setMute(val);
305       }
306 
307 //---------------------------------------------------------
308 //   controlSelected
309 //---------------------------------------------------------
310 
controlSelected()311 void MixerTrackChannel::controlSelected()
312       {
313       setSelected(true);
314       }
315 
316 //---------------------------------------------------------
317 //   mouseReleaseEvent
318 //---------------------------------------------------------
319 
mouseReleaseEvent(QMouseEvent *)320 void MixerTrackChannel::mouseReleaseEvent(QMouseEvent*)
321       {
322       setSelected(true);
323       }
324 
325 //---------------------------------------------------------
326 //   setSelected
327 //---------------------------------------------------------
328 
setSelected(bool sel)329 void MixerTrackChannel::setSelected(bool sel)
330       {
331       if (_selected == sel)
332             return;
333 
334       _selected = sel;
335       applyStyle();
336 
337       emit(selectedChanged(sel));
338 
339       if (_selected && _group)
340             _group->notifyTrackSelected(this);
341 
342       applyStyle();
343       }
344 
345 }
346