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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1507 - (hide annotations) (download)
Wed Nov 21 23:22:18 2007 UTC (16 years, 5 months ago) by capela
File size: 12675 byte(s)
- Qt4 migration: more tiny-fixes, specially on the sampler channel
strip appearence and channels menu content.

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     #include <math.h>
32    
33     // Channel status/usage usage limit control.
34     #define QSAMPLER_ERROR_LIMIT 3
35    
36     namespace QSampler {
37    
38     ChannelStrip::ChannelStrip(QWidget* parent, Qt::WFlags f) : QWidget(parent, f) {
39     ui.setupUi(this);
40    
41     // Initialize locals.
42     m_pChannel = NULL;
43     m_iDirtyChange = 0;
44     m_iErrorCount = 0;
45    
46     // Try to restore normal window positioning.
47     adjustSize();
48 capela 1466
49     QObject::connect(ui.ChannelSetupPushButton,
50     SIGNAL(clicked()),
51     SLOT(channelSetup()));
52     QObject::connect(ui.ChannelMutePushButton,
53     SIGNAL(toggled(bool)),
54     SLOT(channelMute(bool)));
55     QObject::connect(ui.ChannelSoloPushButton,
56     SIGNAL(toggled(bool)),
57     SLOT(channelSolo(bool)));
58     QObject::connect(ui.VolumeSlider,
59     SIGNAL(valueChanged(int)),
60     SLOT(volumeChanged(int)));
61     QObject::connect(ui.VolumeSpinBox,
62     SIGNAL(valueChanged(int)),
63     SLOT(volumeChanged(int)));
64     QObject::connect(ui.ChannelEditPushButton,
65     SIGNAL(clicked()),
66     SLOT(channelEdit()));
67 schoenebeck 1461 }
68    
69     ChannelStrip::~ChannelStrip() {
70     // Destroy existing channel descriptor.
71     if (m_pChannel)
72     delete m_pChannel;
73     m_pChannel = NULL;
74     }
75    
76    
77 capela 1499 // Window drag-n-drop event handlers.
78     void ChannelStrip::dragEnterEvent ( QDragEnterEvent* pDragEnterEvent )
79 schoenebeck 1461 {
80     if (m_pChannel == NULL)
81 capela 1499 return;
82    
83     bool bAccept = false;
84    
85     if (pDragEnterEvent->source() == NULL) {
86     const QMimeData *pMimeData = pDragEnterEvent->mimeData();
87     if (pMimeData && pMimeData->hasUrls()) {
88     QListIterator<QUrl> iter(pMimeData->urls());
89     while (iter.hasNext()) {
90     const QString& sFilename = iter.next().toLocalFile();
91     if (!sFilename.isEmpty()) {
92     bAccept = qsamplerChannel::isInstrumentFile(sFilename);
93     break;
94 schoenebeck 1461 }
95     }
96     }
97     }
98    
99 capela 1499 if (bAccept)
100     pDragEnterEvent->accept();
101     else
102     pDragEnterEvent->ignore();
103 schoenebeck 1461 }
104    
105    
106     void ChannelStrip::dropEvent ( QDropEvent* pDropEvent )
107     {
108 capela 1499 if (m_pChannel == NULL)
109     return;
110 schoenebeck 1461
111 capela 1499 if (pDropEvent->source())
112     return;
113    
114     const QMimeData *pMimeData = pDropEvent->mimeData();
115     if (pMimeData && pMimeData->hasUrls()) {
116     QStringList files;
117     QListIterator<QUrl> iter(pMimeData->urls());
118     while (iter.hasNext()) {
119     const QString& sFilename = iter.next().toLocalFile();
120     if (!sFilename.isEmpty()) {
121     // Go and set the dropped instrument filename...
122     m_pChannel->setInstrument(sFilename, 0);
123     // Open up the channel dialog.
124     channelSetup();
125     break;
126     }
127     }
128 schoenebeck 1461 }
129     }
130    
131    
132     // Channel strip setup formal initializer.
133     void ChannelStrip::setup ( qsamplerChannel *pChannel )
134     {
135     // Destroy any previous channel descriptor;
136     // (remember that once setup we own it!)
137     if (m_pChannel)
138     delete m_pChannel;
139    
140     // Set the new one...
141     m_pChannel = pChannel;
142    
143     // Stabilize this around.
144     updateChannelInfo();
145    
146     // We'll accept drops from now on...
147     if (m_pChannel)
148     setAcceptDrops(true);
149     }
150    
151     // Channel secriptor accessor.
152     qsamplerChannel *ChannelStrip::channel (void)
153     {
154     return m_pChannel;
155     }
156    
157    
158     // Messages view font accessors.
159     QFont ChannelStrip::displayFont (void)
160     {
161     return ui.EngineNameTextLabel->font();
162     }
163    
164     void ChannelStrip::setDisplayFont ( const QFont & font )
165     {
166     ui.EngineNameTextLabel->setFont(font);
167     ui.MidiPortChannelTextLabel->setFont(font);
168     ui.InstrumentNameTextLabel->setFont(font);
169     ui.InstrumentStatusTextLabel->setFont(font);
170     }
171    
172    
173     // Channel display background effect.
174     void ChannelStrip::setDisplayEffect ( bool bDisplayEffect )
175     {
176 capela 1499 QPalette pal;
177 capela 1507 pal.setColor(QPalette::Foreground, Qt::yellow);
178     ui.EngineNameTextLabel->setPalette(pal);
179     ui.MidiPortChannelTextLabel->setPalette(pal);
180 capela 1499 pal.setColor(QPalette::Foreground, Qt::green);
181     if (bDisplayEffect) {
182     QPixmap pm(":/icons/displaybg1.png");
183     pal.setBrush(QPalette::Background, QBrush(pm));
184     } else {
185     pal.setColor(QPalette::Background, Qt::black);
186     }
187     ui.ChannelInfoFrame->setPalette(pal);
188     ui.StreamVoiceCountTextLabel->setPalette(pal);
189 schoenebeck 1461 }
190    
191    
192     // Maximum volume slider accessors.
193     void ChannelStrip::setMaxVolume ( int iMaxVolume )
194     {
195     m_iDirtyChange++;
196     ui.VolumeSlider->setRange(0, iMaxVolume);
197     ui.VolumeSpinBox->setRange(0, iMaxVolume);
198     m_iDirtyChange--;
199     }
200    
201    
202     // Channel setup dialog slot.
203     bool ChannelStrip::channelSetup (void)
204     {
205     if (m_pChannel == NULL)
206     return false;
207    
208     // Invoke the channel setup dialog.
209     bool bResult = m_pChannel->channelSetup(this);
210     // Notify that this channel has changed.
211     if (bResult)
212     emit channelChanged(this);
213    
214     return bResult;
215     }
216    
217    
218     // Channel mute slot.
219     bool ChannelStrip::channelMute ( bool bMute )
220     {
221     if (m_pChannel == NULL)
222     return false;
223    
224     // Invoke the channel mute method.
225     bool bResult = m_pChannel->setChannelMute(bMute);
226     // Notify that this channel has changed.
227     if (bResult)
228     emit channelChanged(this);
229    
230     return bResult;
231     }
232    
233    
234     // Channel solo slot.
235     bool ChannelStrip::channelSolo ( bool bSolo )
236     {
237     if (m_pChannel == NULL)
238     return false;
239    
240     // Invoke the channel solo method.
241     bool bResult = m_pChannel->setChannelSolo(bSolo);
242     // Notify that this channel has changed.
243     if (bResult)
244     emit channelChanged(this);
245    
246     return bResult;
247     }
248    
249    
250     // Channel edit slot.
251     void ChannelStrip::channelEdit (void)
252     {
253     if (m_pChannel == NULL)
254     return;
255    
256     m_pChannel->editChannel();
257     }
258    
259    
260     // Channel reset slot.
261     bool ChannelStrip::channelReset (void)
262     {
263     if (m_pChannel == NULL)
264     return false;
265    
266     // Invoke the channel reset method.
267     bool bResult = m_pChannel->channelReset();
268     // Notify that this channel has changed.
269     if (bResult)
270     emit channelChanged(this);
271    
272     return bResult;
273     }
274    
275    
276     // Update the channel instrument name.
277     bool ChannelStrip::updateInstrumentName ( bool bForce )
278     {
279     if (m_pChannel == NULL)
280     return false;
281    
282     // Do we refresh the actual name?
283     if (bForce)
284     m_pChannel->updateInstrumentName();
285    
286     // Instrument name...
287     if (m_pChannel->instrumentName().isEmpty()) {
288     if (m_pChannel->instrumentStatus() >= 0)
289     ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::loadingInstrument());
290     else
291     ui.InstrumentNameTextLabel->setText(' ' + qsamplerChannel::noInstrumentName());
292     } else
293     ui.InstrumentNameTextLabel->setText(' ' + m_pChannel->instrumentName());
294    
295     return true;
296     }
297    
298    
299     // Do the dirty volume change.
300     bool ChannelStrip::updateChannelVolume (void)
301     {
302     if (m_pChannel == NULL)
303     return false;
304    
305     // Convert...
306     #ifdef CONFIG_ROUND
307     int iVolume = (int) ::round(100.0 * m_pChannel->volume());
308     #else
309     double fIPart = 0.0;
310     double fFPart = ::modf(100.0 * m_pChannel->volume(), &fIPart);
311     int iVolume = (int) fIPart;
312     if (fFPart >= +0.5)
313     iVolume++;
314     else
315     if (fFPart <= -0.5)
316     iVolume--;
317     #endif
318    
319     // And clip...
320     if (iVolume < 0)
321     iVolume = 0;
322    
323     // Flag it here, to avoid infinite recursion.
324     m_iDirtyChange++;
325     ui.VolumeSlider->setValue(iVolume);
326     ui.VolumeSpinBox->setValue(iVolume);
327     m_iDirtyChange--;
328    
329     return true;
330     }
331    
332    
333     // Update whole channel info state.
334     bool ChannelStrip::updateChannelInfo (void)
335     {
336     if (m_pChannel == NULL)
337     return false;
338    
339     // Check for error limit/recycle...
340     if (m_iErrorCount > QSAMPLER_ERROR_LIMIT)
341     return true;
342    
343     // Update strip caption.
344     QString sText = m_pChannel->channelName();
345 capela 1499 setWindowTitle(sText);
346 schoenebeck 1461 ui.ChannelSetupPushButton->setText(sText);
347    
348     // Check if we're up and connected.
349     MainForm* pMainForm = MainForm::getInstance();
350     if (pMainForm->client() == NULL)
351     return false;
352    
353     // Read actual channel information.
354     m_pChannel->updateChannelInfo();
355    
356     // Engine name...
357     if (m_pChannel->engineName().isEmpty())
358     ui.EngineNameTextLabel->setText(' ' + qsamplerChannel::noEngineName());
359     else
360     ui.EngineNameTextLabel->setText(' ' + m_pChannel->engineName());
361    
362     // Instrument name...
363     updateInstrumentName(false);
364    
365     // MIDI Port/Channel...
366     QString sMidiPortChannel = QString::number(m_pChannel->midiPort()) + " / ";
367     if (m_pChannel->midiChannel() == LSCP_MIDI_CHANNEL_ALL)
368     sMidiPortChannel += tr("All");
369     else
370     sMidiPortChannel += QString::number(m_pChannel->midiChannel() + 1);
371     ui.MidiPortChannelTextLabel->setText(sMidiPortChannel);
372    
373 capela 1499 // Common palette...
374     QPalette pal;
375     const QColor& rgbFore = pal.color(QPalette::Foreground);
376    
377 schoenebeck 1461 // Instrument status...
378     int iInstrumentStatus = m_pChannel->instrumentStatus();
379     if (iInstrumentStatus < 0) {
380 capela 1499 pal.setColor(QPalette::Foreground, Qt::red);
381     ui.InstrumentStatusTextLabel->setPalette(pal);
382 schoenebeck 1461 ui.InstrumentStatusTextLabel->setText(tr("ERR%1").arg(iInstrumentStatus));
383     m_iErrorCount++;
384     return false;
385     }
386     // All seems normal...
387 capela 1499 pal.setColor(QPalette::Foreground,
388     iInstrumentStatus < 100 ? Qt::yellow : Qt::green);
389     ui.InstrumentStatusTextLabel->setPalette(pal);
390 schoenebeck 1461 ui.InstrumentStatusTextLabel->setText(QString::number(iInstrumentStatus) + '%');
391     m_iErrorCount = 0;
392    
393     #ifdef CONFIG_MUTE_SOLO
394     // Mute/Solo button state coloring...
395     bool bMute = m_pChannel->channelMute();
396 capela 1499 const QColor& rgbButton = pal.color(QPalette::Button);
397     pal.setColor(QPalette::Foreground, rgbFore);
398     pal.setColor(QPalette::Button, bMute ? Qt::yellow : rgbButton);
399     ui.ChannelMutePushButton->setPalette(pal);
400     ui.ChannelMutePushButton->setDown(bMute);
401 schoenebeck 1461 bool bSolo = m_pChannel->channelSolo();
402 capela 1499 pal.setColor(QPalette::Button, bSolo ? Qt::cyan : rgbButton);
403     ui.ChannelSoloPushButton->setPalette(pal);
404     ui.ChannelSoloPushButton->setDown(bSolo);
405 schoenebeck 1461 #else
406     ui.ChannelMutePushButton->setEnabled(false);
407     ui.ChannelSoloPushButton->setEnabled(false);
408     #endif
409    
410     // And update the both GUI volume elements;
411     // return success if, and only if, intrument is fully loaded...
412     return updateChannelVolume() && (iInstrumentStatus == 100);
413     }
414    
415    
416     // Update whole channel usage state.
417     bool ChannelStrip::updateChannelUsage (void)
418     {
419     if (m_pChannel == NULL)
420     return false;
421    
422     MainForm *pMainForm = MainForm::getInstance();
423     if (pMainForm->client() == NULL)
424     return false;
425    
426     // This only makes sense on fully loaded channels...
427     if (m_pChannel->instrumentStatus() < 100)
428     return false;
429    
430     // Get current channel voice count.
431     int iVoiceCount = ::lscp_get_channel_voice_count(pMainForm->client(), m_pChannel->channelID());
432 capela 1499 // Get current stream count.
433 schoenebeck 1461 int iStreamCount = ::lscp_get_channel_stream_count(pMainForm->client(), m_pChannel->channelID());
434     // Get current channel buffer fill usage.
435     // As benno has suggested this is the percentage usage
436     // of the least filled buffer stream...
437     int iStreamUsage = ::lscp_get_channel_stream_usage(pMainForm->client(), m_pChannel->channelID());;
438    
439     // Update the GUI elements...
440     ui.StreamUsageProgressBar->setValue(iStreamUsage);
441     ui.StreamVoiceCountTextLabel->setText(QString("%1 / %2").arg(iStreamCount).arg(iVoiceCount));
442    
443     // We're clean.
444     return true;
445     }
446    
447    
448     // Volume change slot.
449     void ChannelStrip::volumeChanged ( int iVolume )
450     {
451     if (m_pChannel == NULL)
452     return;
453    
454     // Avoid recursion.
455     if (m_iDirtyChange > 0)
456     return;
457    
458     // Convert and clip.
459     float fVolume = (float) iVolume / 100.0;
460     if (fVolume < 0.001)
461     fVolume = 0.0;
462    
463     // Update the GUI elements.
464     if (m_pChannel->setVolume(fVolume)) {
465     updateChannelVolume();
466     emit channelChanged(this);
467     }
468     }
469    
470    
471     // Context menu event handler.
472     void ChannelStrip::contextMenuEvent( QContextMenuEvent *pEvent )
473     {
474     if (m_pChannel == NULL)
475     return;
476    
477     // We'll just show up the main form's edit menu (thru qsamplerChannel).
478     m_pChannel->contextMenuEvent(pEvent);
479     }
480    
481    
482     // Error count hackish accessors.
483     void ChannelStrip::resetErrorCount (void)
484     {
485     m_iErrorCount = 0;
486     }
487    
488     } // namespace QSampler
489 capela 1464
490    
491     // end of qsamplerChannelStrip.cpp

  ViewVC Help
Powered by ViewVC