/[svn]/qsampler/trunk/src/qsamplerChannelStrip.cpp
ViewVC logotype

Annotation of /qsampler/trunk/src/qsamplerChannelStrip.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1637 - (hide annotations) (download)
Mon Jan 7 20:00:13 2008 UTC (16 years, 3 months ago) by capela
File size: 13316 byte(s)
* Color pallete fix for the instrument name display in channel strip,
  particularly notorious on Mac OS X builds.

1 capela 1464 // qsamplerChannelStrip.cpp
2     //
3     /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 2
10     of the License, or (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21     *****************************************************************************/
22    
23 capela 1499 #include "qsamplerAbout.h"
24 schoenebeck 1461 #include "qsamplerChannelStrip.h"
25    
26     #include "qsamplerMainForm.h"
27    
28 capela 1499 #include <QDragEnterEvent>
29 schoenebeck 1461 #include <QUrl>
30    
31     // Channel status/usage usage limit control.
32     #define QSAMPLER_ERROR_LIMIT 3
33    
34 capela 1510 // Needed for lroundf()
35     #include <math.h>
36    
37     #ifndef CONFIG_ROUND
38     static inline long lroundf ( float x )
39     {
40     if (x >= 0.0f)
41     return long(x + 0.5f);
42     else
43     return long(x - 0.5f);
44     }
45     #endif
46    
47 capela 1514
48     namespace QSampler {
49    
50 capela 1558 //-------------------------------------------------------------------------
51     // QSampler::ChannelStrip -- Channel strip form implementation.
52     //
53    
54 capela 1514 // Channel strip activation/selection.
55     ChannelStrip *ChannelStrip::g_pSelectedStrip = NULL;
56    
57 capela 1509 ChannelStrip::ChannelStrip ( QWidget* pParent, Qt::WindowFlags wflags )
58     : QWidget(pParent, wflags)
59     {
60 capela 1510 m_ui.setupUi(this);
61 schoenebeck 1461
62 capela 1510 // Initialize locals.
63     m_pChannel = NULL;
64     m_iDirtyChange = 0;
65     m_iErrorCount = 0;
66 schoenebeck 1461
67 capela 1510 // Try to restore normal window positioning.
68     adjustSize();
69 capela 1466
70 capela 1509 QObject::connect(m_ui.ChannelSetupPushButton,
71 capela 1466 SIGNAL(clicked()),
72     SLOT(channelSetup()));
73 capela 1509 QObject::connect(m_ui.ChannelMutePushButton,
74 capela 1466 SIGNAL(toggled(bool)),
75     SLOT(channelMute(bool)));
76 capela 1509 QObject::connect(m_ui.ChannelSoloPushButton,
77 capela 1466 SIGNAL(toggled(bool)),
78     SLOT(channelSolo(bool)));
79 capela 1509 QObject::connect(m_ui.VolumeSlider,
80 capela 1466 SIGNAL(valueChanged(int)),
81     SLOT(volumeChanged(int)));
82 capela 1509 QObject::connect(m_ui.VolumeSpinBox,
83 capela 1466 SIGNAL(valueChanged(int)),
84     SLOT(volumeChanged(int)));
85 capela 1509 QObject::connect(m_ui.ChannelEditPushButton,
86 capela 1466 SIGNAL(clicked()),
87     SLOT(channelEdit()));
88 capela 1515
89     setSelected(false);
90 schoenebeck 1461 }
91    
92 capela 1513
93     ChannelStrip::~ChannelStrip (void)
94     {
95 capela 1515 setSelected(false);
96    
97 capela 1510 // Destroy existing channel descriptor.
98     if (m_pChannel)
99     delete m_pChannel;
100     m_pChannel = NULL;
101 schoenebeck 1461 }
102    
103    
104 capela 1499 // Window drag-n-drop event handlers.
105     void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
106 schoenebeck 1461 {
107     if (m_pChannel == NULL)
108 capela 1499 return;
109    
110     bool bAccept = false;
111    
112     if (pDragEnterEvent->source() == NULL) {
113     const QMimeData *pMimeData = pDragEnterEvent->mimeData();
114     if (pMimeData && pMimeData->hasUrls()) {
115     QListIterator<QUrl> iter(pMimeData->urls());
116     while (iter.hasNext()) {
117     const QString& sFilename = iter.next().toLocalFile();
118     if (!sFilename.isEmpty()) {
119 capela 1558 bAccept = Channel::isInstrumentFile(sFilename);
120 capela 1499 break;
121 schoenebeck 1461 }
122     }
123     }
124     }
125    
126 capela 1499 if (bAccept)
127     pDragEnterEvent->accept();
128     else
129     pDragEnterEvent->ignore();
130 schoenebeck 1461 }
131    
132    
133     void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
134     {
135 capela 1499 if (m_pChannel == NULL)
136     return;
137 schoenebeck 1461
138 capela 1499 if (pDropEvent->source())
139     return;
140    
141     const QMimeData *pMimeData = pDropEvent->mimeData();
142     if (pMimeData && pMimeData->hasUrls()) {
143     QStringList files;
144     QListIterator<QUrl> iter(pMimeData->urls());
145     while (iter.hasNext()) {
146     const QString& sFilename = iter.next().toLocalFile();
147     if (!sFilename.isEmpty()) {
148     // Go and set the dropped instrument filename...
149     m_pChannel->setInstrument(sFilename, 0);
150     // Open up the channel dialog.
151     channelSetup();
152     break;
153     }
154     }
155 schoenebeck 1461 }
156     }
157    
158    
159     // Channel strip setup formal initializer.
160 capela 1558 void ChannelStrip::setup ( Channel *pChannel )
161 schoenebeck 1461 {
162 capela 1510 // Destroy any previous channel descriptor;
163     // (remember that once setup we own it!)
164     if (m_pChannel)
165     delete m_pChannel;
166 schoenebeck 1461
167 capela 1510 // Set the new one...
168     m_pChannel = pChannel;
169 schoenebeck 1461
170 capela 1510 // Stabilize this around.
171     updateChannelInfo();
172 schoenebeck 1461
173     // We'll accept drops from now on...
174     if (m_pChannel)
175     setAcceptDrops(true);
176     }
177    
178 capela 1513
179 schoenebeck 1461 // Channel secriptor accessor.
180 capela 1558 Channel *ChannelStrip::channel (void) const
181 schoenebeck 1461 {
182 capela 1510 return m_pChannel;
183 schoenebeck 1461 }
184    
185    
186     // Messages view font accessors.
187 capela 1509 QFont ChannelStrip::displayFont (void) const
188 schoenebeck 1461 {
189 capela 1510 return m_ui.EngineNameTextLabel->font();
190 schoenebeck 1461 }
191    
192     void ChannelStrip::setDisplayFont ( const QFont & font )
193     {
194 capela 1510 m_ui.EngineNameTextLabel->setFont(font);
195     m_ui.MidiPortChannelTextLabel->setFont(font);
196     m_ui.InstrumentNameTextLabel->setFont(font);
197     m_ui.InstrumentStatusTextLabel->setFont(font);
198 schoenebeck 1461 }
199    
200    
201     // Channel display background effect.
202     void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
203     {
204 capela 1499 QPalette pal;
205 capela 1507 pal.setColor(QPalette::Foreground, Qt::yellow);
206 capela 1509 m_ui.EngineNameTextLabel->setPalette(pal);
207     m_ui.MidiPortChannelTextLabel->setPalette(pal);
208 capela 1499 pal.setColor(QPalette::Foreground, Qt::green);
209     if (bDisplayEffect) {
210     QPixmap pm(":/icons/displaybg1.png");
211     pal.setBrush(QPalette::Background, QBrush(pm));
212     } else {
213     pal.setColor(QPalette::Background, Qt::black);
214     }
215 capela 1509 m_ui.ChannelInfoFrame->setPalette(pal);
216 capela 1637 m_ui.InstrumentNameTextLabel->setPalette(pal);
217 capela 1509 m_ui.StreamVoiceCountTextLabel->setPalette(pal);
218 schoenebeck 1461 }
219    
220    
221     // Maximum volume slider accessors.
222     void ChannelStrip::setMaxVolume ( int iMaxVolume )
223     {
224 capela 1510 m_iDirtyChange++;
225     m_ui.VolumeSlider->setRange(0, iMaxVolume);
226     m_ui.VolumeSpinBox->setRange(0, iMaxVolume);
227     m_iDirtyChange--;
228 schoenebeck 1461 }
229    
230    
231     // Channel setup dialog slot.
232     bool ChannelStrip::channelSetup (void)
233     {
234     if (m_pChannel == NULL)
235     return false;
236    
237     // Invoke the channel setup dialog.
238     bool bResult = m_pChannel->channelSetup(this);
239     // Notify that this channel has changed.
240     if (bResult)
241     emit channelChanged(this);
242    
243     return bResult;
244     }
245    
246    
247     // Channel mute slot.
248     bool ChannelStrip::channelMute ( bool bMute )
249     {
250     if (m_pChannel == NULL)
251     return false;
252    
253     // Invoke the channel mute method.
254     bool bResult = m_pChannel->setChannelMute(bMute);
255     // Notify that this channel has changed.
256     if (bResult)
257     emit channelChanged(this);
258    
259     return bResult;
260     }
261    
262    
263     // Channel solo slot.
264     bool ChannelStrip::channelSolo ( bool bSolo )
265     {
266     if (m_pChannel == NULL)
267     return false;
268    
269     // Invoke the channel solo method.
270     bool bResult = m_pChannel->setChannelSolo(bSolo);
271     // Notify that this channel has changed.
272     if (bResult)
273     emit channelChanged(this);
274    
275     return bResult;
276     }
277    
278    
279     // Channel edit slot.
280     void ChannelStrip::channelEdit (void)
281     {
282     if (m_pChannel == NULL)
283     return;
284    
285     m_pChannel->editChannel();
286     }
287    
288    
289     // Channel reset slot.
290     bool ChannelStrip::channelReset (void)
291     {
292     if (m_pChannel == NULL)
293     return false;
294    
295     // Invoke the channel reset method.
296     bool bResult = m_pChannel->channelReset();
297     // Notify that this channel has changed.
298     if (bResult)
299     emit channelChanged(this);
300    
301     return bResult;
302     }
303    
304    
305     // Update the channel instrument name.
306     bool ChannelStrip::updateInstrumentName ( bool bForce )
307     {
308     if (m_pChannel == NULL)
309     return false;
310    
311     // Do we refresh the actual name?
312     if (bForce)
313     m_pChannel->updateInstrumentName();
314    
315     // Instrument name...
316     if (m_pChannel->instrumentName().isEmpty()) {
317 capela 1513 if (m_pChannel->instrumentStatus() >= 0) {
318     m_ui.InstrumentNameTextLabel->setText(
319 capela 1558 ' ' + Channel::loadingInstrument());
320 capela 1513 } else {
321     m_ui.InstrumentNameTextLabel->setText(
322 capela 1558 ' ' + Channel::noInstrumentName());
323 capela 1513 }
324     } else {
325     m_ui.InstrumentNameTextLabel->setText(
326     ' ' + m_pChannel->instrumentName());
327     }
328 schoenebeck 1461
329     return true;
330     }
331    
332    
333     // Do the dirty volume change.
334     bool ChannelStrip::updateChannelVolume (void)
335     {
336 capela 1510 if (m_pChannel == NULL)
337     return false;
338 schoenebeck 1461
339 capela 1510 // Convert...
340     int iVolume = ::lroundf(100.0f * m_pChannel->volume());
341     // And clip...
342     if (iVolume < 0)
343     iVolume = 0;
344 schoenebeck 1461
345 capela 1510 // Flag it here, to avoid infinite recursion.
346     m_iDirtyChange++;
347     m_ui.VolumeSlider->setValue(iVolume);
348     m_ui.VolumeSpinBox->setValue(iVolume);
349     m_iDirtyChange--;
350 schoenebeck 1461
351 capela 1510 return true;
352 schoenebeck 1461 }
353    
354    
355     // Update whole channel info state.
356     bool ChannelStrip::updateChannelInfo (void)
357     {
358 capela 1510 if (m_pChannel == NULL)
359     return false;
360 schoenebeck 1461
361     // Check for error limit/recycle...
362     if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
363     return true;
364    
365 capela 1510 // Update strip caption.
366     QString sText = m_pChannel->channelName();
367     setWindowTitle(sText);
368 capela 1513 m_ui.ChannelSetupPushButton->setText('&' + sText);
369 schoenebeck 1461
370 capela 1510 // Check if we're up and connected.
371 schoenebeck 1461 MainForm* pMainForm = MainForm::getInstance();
372     if (pMainForm->client() == NULL)
373     return false;
374    
375 capela 1510 // Read actual channel information.
376     m_pChannel->updateChannelInfo();
377 schoenebeck 1461
378 capela 1510 // Engine name...
379 capela 1513 if (m_pChannel->engineName().isEmpty()) {
380     m_ui.EngineNameTextLabel->setText(
381 capela 1558 ' ' + Channel::noEngineName());
382 capela 1513 } else {
383     m_ui.EngineNameTextLabel->setText(
384     ' ' + m_pChannel->engineName());
385     }
386 schoenebeck 1461
387     // Instrument name...
388     updateInstrumentName(false);
389    
390 capela 1510 // MIDI Port/Channel...
391 schoenebeck 1461 QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";
392     if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
393     sMidiPortChannel += tr("All");
394     else
395     sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);
396 capela 1509 m_ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
397 schoenebeck 1461
398 capela 1499 // Common palette...
399     QPalette pal;
400     const QColor& rgbFore = pal.color(QPalette::Foreground);
401    
402 capela 1510 // Instrument status...
403     int iInstrumentStatus = m_pChannel->instrumentStatus();
404     if (iInstrumentStatus < 0) {
405 capela 1499 pal.setColor(QPalette::Foreground, Qt::red);
406 capela 1509 m_ui.InstrumentStatusTextLabel->setPalette(pal);
407 capela 1513 m_ui.InstrumentStatusTextLabel->setText(
408     tr("ERR%1").arg(iInstrumentStatus));
409 capela 1510 m_iErrorCount++;
410     return false;
411     }
412     // All seems normal...
413 capela 1499 pal.setColor(QPalette::Foreground,
414     iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
415 capela 1510 m_ui.InstrumentStatusTextLabel->setPalette(pal);
416 capela 1513 m_ui.InstrumentStatusTextLabel->setText(
417     QString::number(iInstrumentStatus) + '%');
418 capela 1510 m_iErrorCount = 0;
419 schoenebeck 1461
420     #ifdef CONFIG_MUTE_SOLO
421 capela 1510 // Mute/Solo button state coloring...
422     bool bMute = m_pChannel->channelMute();
423 capela 1499 const QColor& rgbButton = pal.color(QPalette::Button);
424     pal.setColor(QPalette::Foreground, rgbFore);
425     pal.setColor(QPalette::Button, bMute ? Qt::yellow : rgbButton);
426 capela 1509 m_ui.ChannelMutePushButton->setPalette(pal);
427     m_ui.ChannelMutePushButton->setDown(bMute);
428 capela 1510 bool bSolo = m_pChannel->channelSolo();
429 capela 1499 pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);
430 capela 1509 m_ui.ChannelSoloPushButton->setPalette(pal);
431     m_ui.ChannelSoloPushButton->setDown(bSolo);
432 schoenebeck 1461 #else
433 capela 1509 m_ui.ChannelMutePushButton->setEnabled(false);
434     m_ui.ChannelSoloPushButton->setEnabled(false);
435 schoenebeck 1461 #endif
436    
437 capela 1510 // And update the both GUI volume elements;
438     // return success if, and only if, intrument is fully loaded...
439     return updateChannelVolume() && (iInstrumentStatus == 100);
440 schoenebeck 1461 }
441    
442    
443     // Update whole channel usage state.
444     bool ChannelStrip::updateChannelUsage (void)
445     {
446 capela 1510 if (m_pChannel == NULL)
447     return false;
448 schoenebeck 1461
449     MainForm *pMainForm = MainForm::getInstance();
450     if (pMainForm->client() == NULL)
451     return false;
452    
453     // This only makes sense on fully loaded channels...
454     if (m_pChannel->instrumentStatus() < 100)
455 capela 1510 return false;
456 schoenebeck 1461
457 capela 1510 // Get current channel voice count.
458 capela 1513 int iVoiceCount = ::lscp_get_channel_voice_count(
459     pMainForm->client(), m_pChannel->channelID());
460 capela 1510 // Get current stream count.
461 capela 1513 int iStreamCount = ::lscp_get_channel_stream_count(
462     pMainForm->client(), m_pChannel->channelID());
463 capela 1510 // Get current channel buffer fill usage.
464     // As benno has suggested this is the percentage usage
465     // of the least filled buffer stream...
466 capela 1513 int iStreamUsage = ::lscp_get_channel_stream_usage(
467     pMainForm->client(), m_pChannel->channelID());;
468 schoenebeck 1461
469 capela 1510 // Update the GUI elements...
470     m_ui.StreamUsageProgressBar->setValue(iStreamUsage);
471 capela 1513 m_ui.StreamVoiceCountTextLabel->setText(
472     QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
473 schoenebeck 1461
474 capela 1510 // We're clean.
475     return true;
476 schoenebeck 1461 }
477    
478    
479     // Volume change slot.
480     void ChannelStrip::volumeChanged ( int iVolume )
481     {
482 capela 1510 if (m_pChannel == NULL)
483     return;
484 schoenebeck 1461
485 capela 1510 // Avoid recursion.
486     if (m_iDirtyChange > 0)
487     return;
488 schoenebeck 1461
489 capela 1510 // Convert and clip.
490     float fVolume = (float) iVolume / 100.0f;
491     if (fVolume < 0.001f)
492     fVolume = 0.0f;
493 schoenebeck 1461
494 capela 1510 // Update the GUI elements.
495     if (m_pChannel->setVolume(fVolume)) {
496     updateChannelVolume();
497     emit channelChanged(this);
498     }
499 schoenebeck 1461 }
500    
501    
502     // Context menu event handler.
503     void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
504     {
505 capela 1510 if (m_pChannel == NULL)
506     return;
507 schoenebeck 1461
508 capela 1510 // We'll just show up the main form's edit menu (thru qsamplerChannel).
509     m_pChannel->contextMenuEvent(pEvent);
510 schoenebeck 1461 }
511    
512    
513     // Error count hackish accessors.
514     void ChannelStrip::resetErrorCount (void)
515     {
516     m_iErrorCount = 0;
517     }
518    
519 capela 1514
520     // Channel strip activation/selection.
521     void ChannelStrip::setSelected ( bool bSelected )
522     {
523     if (bSelected) {
524     if (g_pSelectedStrip == this)
525     return;
526     if (g_pSelectedStrip)
527     g_pSelectedStrip->setSelected(false);
528     g_pSelectedStrip = this;
529     } else {
530     if (g_pSelectedStrip == this)
531     g_pSelectedStrip = NULL;
532     }
533    
534     QPalette pal;
535     if (bSelected) {
536     const QColor& color = pal.midlight().color();
537     pal.setColor(QPalette::Background, color.dark(150));
538     pal.setColor(QPalette::Foreground, color.light(150));
539     }
540     QWidget::setPalette(pal);
541     }
542    
543    
544     bool ChannelStrip::isSelected (void) const
545     {
546     return (this == g_pSelectedStrip);
547     }
548    
549    
550 schoenebeck 1461 } // namespace QSampler
551 capela 1464
552    
553     // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC