root/branches/new_fx_rack_and_sample_fun/gui/src/PatternEditor/DrumPatternEditor.cpp @ 676

Revision 676, 21.5 KB (checked in by wolke, 4 years ago)

add desktop files

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22
23#include "DrumPatternEditor.h"
24#include "PatternEditorPanel.h"
25#include "NotePropertiesRuler.h"
26
27#include <hydrogen/globals.h>
28#include <hydrogen/Song.h>
29#include <hydrogen/hydrogen.h>
30#include <hydrogen/Preferences.h>
31#include <hydrogen/event_queue.h>
32#include <hydrogen/instrument.h>
33#include <hydrogen/Pattern.h>
34#include <hydrogen/note.h>
35#include <hydrogen/audio_engine.h>
36
37#include "../HydrogenApp.h"
38#include "../Mixer/Mixer.h"
39#include "../Skin.h"
40
41#include <cassert>
42#include <algorithm>
43
44#include <QtGui>
45
46using namespace std;
47using namespace H2Core;
48
49DrumPatternEditor::DrumPatternEditor(QWidget* parent, PatternEditorPanel *panel)
50 : QWidget( parent )
51 , Object( "DrumPatternEditor" )
52 , m_nResolution( 8 )
53 , m_bUseTriplets( false )
54 , m_bRightBtnPressed( false )
55 , m_pDraggedNote( NULL )
56 , m_pPattern( NULL )
57 , m_pPatternEditorPanel( panel )
58{
59        //setAttribute(Qt::WA_NoBackground);
60        setFocusPolicy(Qt::ClickFocus);
61
62        m_nGridWidth = Preferences::getInstance()->getPatternEditorGridWidth();
63        m_nGridHeight = Preferences::getInstance()->getPatternEditorGridHeight();
64
65        unsigned nEditorWidth = 20 + m_nGridWidth * ( MAX_NOTES * 4 );
66        m_nEditorHeight = m_nGridHeight * MAX_INSTRUMENTS;
67
68        resize( nEditorWidth, m_nEditorHeight );
69
70        HydrogenApp::getInstance()->addEventListener( this );
71       
72}
73
74
75
76DrumPatternEditor::~DrumPatternEditor()
77{
78}
79
80
81
82void DrumPatternEditor::updateEditor()
83{
84        Hydrogen* engine = Hydrogen::get_instance();
85
86        // check engine state
87        int state = engine->getState();
88        if ( (state != STATE_READY) && (state != STATE_PLAYING) ) {
89                ERRORLOG( "FIXME: skipping pattern editor update (state shoud be READY or PLAYING)" );
90                return;
91        }
92
93        Hydrogen *pEngine = Hydrogen::get_instance();
94        PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
95        int nSelectedPatternNumber = pEngine->getSelectedPatternNumber();
96        if ( (nSelectedPatternNumber != -1) && ( (uint)nSelectedPatternNumber < pPatternList->get_size() ) ) {
97                m_pPattern = pPatternList->get( nSelectedPatternNumber );
98        }
99        else {
100                m_pPattern = NULL;
101        }
102
103
104        uint nEditorWidth;
105        if ( m_pPattern ) {
106                nEditorWidth = 20 + m_nGridWidth * m_pPattern->get_lenght();
107        }
108        else {
109                nEditorWidth = 20 + m_nGridWidth * MAX_NOTES;
110        }
111        resize( nEditorWidth, height() );
112
113        // redraw all
114        update( 0, 0, width(), height() );
115}
116
117
118
119int DrumPatternEditor::getColumn(QMouseEvent *ev)
120{
121        int nBase;
122        if (m_bUseTriplets) {
123                nBase = 3;
124        }
125        else {
126                nBase = 4;
127        }
128        int nWidth = (m_nGridWidth * 4 * MAX_NOTES) / (nBase * m_nResolution);
129
130        int x = ev->x();
131        int nColumn;
132        nColumn = x - 20 + (nWidth / 2);
133        nColumn = nColumn / nWidth;
134        nColumn = (nColumn * 4 * MAX_NOTES) / (nBase * m_nResolution);
135        return nColumn;
136}
137
138
139
140void DrumPatternEditor::mousePressEvent(QMouseEvent *ev)
141{
142        if ( m_pPattern == NULL ) {
143                return;
144        }
145        Song *pSong = Hydrogen::get_instance()->getSong();
146        int nInstruments = pSong->get_instrument_list()->get_size();
147
148        int row = (int)( ev->y()  / (float)m_nGridHeight);
149        if (row >= nInstruments) {
150                return;
151        }
152
153        int nColumn = getColumn( ev );
154
155        if ( nColumn >= (int)m_pPattern->get_lenght() ) {
156                update( 0, 0, width(), height() );
157                return;
158        }
159        Instrument *pSelectedInstrument = pSong->get_instrument_list()->get( row );
160
161        if (ev->button() == Qt::LeftButton ) {
162                m_bRightBtnPressed = false;
163                AudioEngine::get_instance()->lock( "DrumPatternEditor::mousePressEvent" );      // lock the audio engine
164
165                bool bNoteAlreadyExist = false;
166                std::multimap <int, Note*>::iterator pos;
167                for ( pos = m_pPattern->note_map.lower_bound( nColumn ); pos != m_pPattern->note_map.upper_bound( nColumn ); ++pos ) {
168                        Note *pNote = pos->second;
169                        assert( pNote );
170                        if ( pNote->get_instrument() == pSelectedInstrument ) {
171                                // the note exists...remove it!
172                                bNoteAlreadyExist = true;
173                                delete pNote;
174                                m_pPattern->note_map.erase( pos );
175                                break;
176                        }
177                }
178
179                if ( bNoteAlreadyExist == false ) {
180                        // create the new note
181                        const unsigned nPosition = nColumn;
182                        const float fVelocity = 0.8f;
183                        const float fPan_L = 0.5f;
184                        const float fPan_R = 0.5f;
185                        const int nLength = -1;
186                        const float fPitch = 0.0f;
187                        Note *pNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch );
188                        pNote->set_noteoff( false );
189                        m_pPattern->note_map.insert( std::make_pair( nPosition, pNote ) );
190
191                        // hear note
192                        Preferences *pref = Preferences::getInstance();
193                        if ( pref->getHearNewNotes() ) {
194                                Note *pNote2 = new Note( pSelectedInstrument, 0, fVelocity, fPan_L, fPan_R, nLength, fPitch);
195                                AudioEngine::get_instance()->get_sampler()->note_on(pNote2);
196                        }
197                }
198                pSong->__is_modified = true;
199                AudioEngine::get_instance()->unlock(); // unlock the audio engine
200        }
201        else if (ev->button() == Qt::RightButton ) {
202                m_bRightBtnPressed = true;
203                m_pDraggedNote = NULL;
204
205                int nRealColumn = (ev->x() - 20) / static_cast<float>(m_nGridWidth);
206
207                AudioEngine::get_instance()->lock( "DrumPatternEditor::mousePressEvent" );
208
209                std::multimap <int, Note*>::iterator pos;
210                for ( pos = m_pPattern->note_map.lower_bound( nColumn ); pos != m_pPattern->note_map.upper_bound( nColumn ); ++pos ) {
211                        Note *pNote = pos->second;
212                        assert( pNote );
213
214                        if ( pNote->get_instrument() == pSelectedInstrument ) {
215                                m_pDraggedNote = pNote;
216                                break;
217                        }
218                }
219                if ( !m_pDraggedNote ) {
220                        for ( pos = m_pPattern->note_map.lower_bound( nRealColumn ); pos != m_pPattern->note_map.upper_bound( nRealColumn ); ++pos ) {
221                                Note *pNote = pos->second;
222                                assert( pNote );
223
224                                if ( pNote->get_instrument() == pSelectedInstrument ) {
225                                        m_pDraggedNote = pNote;
226                                        break;
227                                }
228                        }       
229///
230                        if ( Preferences::getInstance()->__rightclickedpattereditor ){
231                                // create the new note
232                                const unsigned nPosition = nColumn;
233                                const float fVelocity = 0.0f;
234                                const float fPan_L = 0.5f;
235                                const float fPan_R = 0.5f;
236                                const int nLength = 1;
237                                const float fPitch = 0.0f;
238                                Note *poffNote = new Note( pSelectedInstrument, nPosition, fVelocity, fPan_L, fPan_R, nLength, fPitch);
239                                poffNote->set_noteoff( true );
240       
241                               
242                                m_pPattern->note_map.insert( std::make_pair( nPosition, poffNote ) );
243       
244                                pSong->__is_modified = true;
245                        }
246///
247                }
248                // potrei essere sulla coda di una nota precedente..
249                for ( int nCol = 0; nCol < nRealColumn; ++nCol ) {
250                        if ( m_pDraggedNote ) break;
251                        for ( pos = m_pPattern->note_map.lower_bound( nCol ); pos != m_pPattern->note_map.upper_bound( nCol ); ++pos ) {
252                                Note *pNote = pos->second;
253                                assert( pNote );
254
255                                if ( pNote->get_instrument() == pSelectedInstrument ) {
256                                        m_pDraggedNote = pNote;
257                                        break;
258                                }
259                        }
260                }
261                AudioEngine::get_instance()->unlock();
262        }
263
264        // update the selected line
265        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
266        if (nSelectedInstrument != row) {
267                Hydrogen::get_instance()->setSelectedInstrumentNumber( row );
268        }
269        else {
270                update( 0, 0, width(), height() );
271                m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
272                m_pPatternEditorPanel->getPanEditor()->updateEditor();
273                m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
274                m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
275        }
276}
277
278
279
280void DrumPatternEditor::mouseReleaseEvent(QMouseEvent *ev)
281{
282        UNUSED( ev );
283        setCursor( QCursor( Qt::ArrowCursor ) );
284
285        if (m_pPattern == NULL) {
286                return;
287        }
288}
289
290
291
292void DrumPatternEditor::mouseMoveEvent(QMouseEvent *ev)
293{
294        if (m_pPattern == NULL) {
295                return;
296        }
297
298        int row = MAX_INSTRUMENTS - 1 - (ev->y()  / (int)m_nGridHeight);
299        if (row >= MAX_INSTRUMENTS) {
300                return;
301        }
302
303        if ( Preferences::getInstance()->__rightclickedpattereditor )
304                return;
305
306        if (m_bRightBtnPressed && m_pDraggedNote ) {
307                if ( m_pDraggedNote->get_noteoff() ) return;
308                int nTickColumn = getColumn( ev );
309
310                AudioEngine::get_instance()->lock("DrumPatternEditor::mouseMoveEvent"); // lock the audio engine
311                int nLen = nTickColumn - (int)m_pDraggedNote->get_position();
312
313                if (nLen <= 0) {
314                        nLen = -1;
315                }
316
317                float fNotePitch = m_pDraggedNote->m_noteKey.m_nOctave * 12 + m_pDraggedNote->m_noteKey.m_key;
318                float fStep = pow( 1.0594630943593, ( double )fNotePitch );
319
320                m_pDraggedNote->set_lenght( nLen * fStep);
321
322                Hydrogen::get_instance()->getSong()->__is_modified = true;
323                AudioEngine::get_instance()->unlock(); // unlock the audio engine
324
325                //__draw_pattern();
326                update( 0, 0, width(), height() );
327                m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
328                m_pPatternEditorPanel->getPanEditor()->updateEditor();
329                m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
330                m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
331        }
332
333}
334
335
336
337void DrumPatternEditor::keyPressEvent (QKeyEvent *ev)
338{
339        ev->ignore();
340}
341
342
343
344///
345/// Draws a pattern
346///
347void DrumPatternEditor::__draw_pattern(QPainter& painter)
348{
349        const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
350        const QColor selectedRowColor( pStyle->m_patternEditor_selectedRowColor.getRed(), pStyle->m_patternEditor_selectedRowColor.getGreen(), pStyle->m_patternEditor_selectedRowColor.getBlue() );
351
352        __create_background( painter );
353
354        if (m_pPattern == NULL) {
355                return;
356        }
357
358        int nNotes = m_pPattern->get_lenght();
359        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
360        Song *pSong = Hydrogen::get_instance()->getSong();
361
362        InstrumentList * pInstrList = pSong->get_instrument_list();
363
364       
365
366        if ( m_nEditorHeight != (int)( m_nGridHeight * pInstrList->get_size() ) ) {
367                // the number of instruments is changed...recreate all
368                m_nEditorHeight = m_nGridHeight * pInstrList->get_size();
369                resize( width(), m_nEditorHeight );
370        }
371
372        for ( uint nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
373                uint y = m_nGridHeight * nInstr;
374                if ( nInstr == (uint)nSelectedInstrument ) {    // selected instrument
375                        painter.fillRect( 0, y + 1, ( 20 + nNotes * m_nGridWidth ), m_nGridHeight - 1, selectedRowColor );
376                }
377        }
378
379
380        // draw the grid
381        __draw_grid( painter );
382       
383
384        /*
385                BUGFIX
386               
387                if m_pPattern is not renewed every time we draw a note,
388                hydrogen will crash after you save a song and create a new one.
389                -smoors
390        */
391        Hydrogen *pEngine = Hydrogen::get_instance();
392        PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
393        int nSelectedPatternNumber = pEngine->getSelectedPatternNumber();
394        if ( (nSelectedPatternNumber != -1) && ( (uint)nSelectedPatternNumber < pPatternList->get_size() ) ) {
395                m_pPattern = pPatternList->get( nSelectedPatternNumber );
396        }
397        else {
398                m_pPattern = NULL;
399        }
400        // ~ FIX
401
402
403
404        if( m_pPattern->note_map.size() == 0) return;
405
406        std::multimap <int, Note*>::iterator pos;
407        for ( pos = m_pPattern->note_map.begin(); pos != m_pPattern->note_map.end(); pos++ ) {
408                Note *note = pos->second;
409                assert( note );
410                __draw_note( note, painter );
411        }
412}
413
414
415///
416/// Draws a note
417///
418void DrumPatternEditor::__draw_note( Note *note, QPainter& p )
419{
420        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
421        static const QColor noteColor( pStyle->m_patternEditor_noteColor.getRed(), pStyle->m_patternEditor_noteColor.getGreen(), pStyle->m_patternEditor_noteColor.getBlue() );
422        static const QColor noteoffColor( pStyle->m_patternEditor_noteoffColor.getRed(), pStyle->m_patternEditor_noteoffColor.getGreen(), pStyle->m_patternEditor_noteoffColor.getBlue() );
423
424        p.setRenderHint( QPainter::Antialiasing );
425
426        int nInstrument = -1;
427        InstrumentList * pInstrList = Hydrogen::get_instance()->getSong()->get_instrument_list();
428        for ( uint nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
429                Instrument *pInstr = pInstrList->get( nInstr );
430                if ( pInstr == note->get_instrument() ) {
431                        nInstrument = nInstr;
432                        break;
433                }
434        }
435        if ( nInstrument == -1 ) {
436                ERRORLOG( "Instrument not found..skipping note" );
437                return;
438        }
439
440        uint pos = note->get_position();
441
442        p.setPen( noteColor );
443
444        if ( note->get_lenght() == -1 && note->get_noteoff() == false ) {       // trigger note
445                uint x_pos = 20 + (pos * m_nGridWidth);// - m_nGridWidth / 2.0;
446
447                uint y_pos = ( nInstrument * m_nGridHeight) + (m_nGridHeight / 2) - 3;
448
449                // draw the "dot"
450                p.drawLine(x_pos, y_pos, x_pos + 3, y_pos + 3);         // A
451                p.drawLine(x_pos, y_pos, x_pos - 3, y_pos + 3);         // B
452                p.drawLine(x_pos, y_pos + 6, x_pos + 3, y_pos + 3);     // C
453                p.drawLine(x_pos - 3, y_pos + 3, x_pos, y_pos + 6);     // D
454
455                p.drawLine(x_pos, y_pos + 1, x_pos + 2, y_pos + 3);
456                p.drawLine(x_pos, y_pos + 1, x_pos - 2, y_pos + 3);
457                p.drawLine(x_pos, y_pos + 5, x_pos + 2, y_pos + 3);
458                p.drawLine(x_pos - 2, y_pos + 3, x_pos, y_pos + 5);
459
460                p.drawLine(x_pos, y_pos + 2, x_pos + 1, y_pos + 3);
461                p.drawLine(x_pos, y_pos + 2, x_pos - 1, y_pos + 3);
462                p.drawLine(x_pos, y_pos + 4, x_pos + 1, y_pos + 3);
463                p.drawLine(x_pos - 1, y_pos + 3, x_pos, y_pos + 4);
464        }
465        else if ( note->get_lenght() == 1 && note->get_noteoff() == true ){
466                p.setPen( noteoffColor );
467                uint x_pos = 20 + ( pos * m_nGridWidth );// - m_nGridWidth / 2.0;
468
469                uint y_pos = ( nInstrument * m_nGridHeight ) + (m_nGridHeight / 2) - 3;
470       
471                // draw the "dot"
472                p.drawLine(x_pos, y_pos, x_pos + 3, y_pos + 3);         // A
473                p.drawLine(x_pos, y_pos, x_pos - 3, y_pos + 3);         // B
474                p.drawLine(x_pos, y_pos + 6, x_pos + 3, y_pos + 3);     // C
475                p.drawLine(x_pos - 3, y_pos + 3, x_pos, y_pos + 6);     // D
476
477                p.drawLine(x_pos, y_pos + 1, x_pos + 2, y_pos + 3);
478                p.drawLine(x_pos, y_pos + 1, x_pos - 2, y_pos + 3);
479                p.drawLine(x_pos, y_pos + 5, x_pos + 2, y_pos + 3);
480                p.drawLine(x_pos - 2, y_pos + 3, x_pos, y_pos + 5);
481
482                p.drawLine(x_pos, y_pos + 2, x_pos + 1, y_pos + 3);
483                p.drawLine(x_pos, y_pos + 2, x_pos - 1, y_pos + 3);
484                p.drawLine(x_pos, y_pos + 4, x_pos + 1, y_pos + 3);
485                p.drawLine(x_pos - 1, y_pos + 3, x_pos, y_pos + 4);     
486
487
488        }               
489        else {
490                float fNotePitch = note->m_noteKey.m_nOctave * 12 + note->m_noteKey.m_key;
491                float fStep = pow( 1.0594630943593, ( double )fNotePitch );
492
493                uint x = 20 + (pos * m_nGridWidth);
494                int w = m_nGridWidth * note->get_lenght() / fStep;
495                w = w - 1;      // lascio un piccolo spazio tra una nota ed un altra
496
497                int y = (int) ( ( nInstrument ) * m_nGridHeight  + (m_nGridHeight / 100.0 * 30.0) );
498                int h = (int) (m_nGridHeight - ((m_nGridHeight / 100.0 * 30.0) * 2.0) );
499
500                p.fillRect( x, y + 1, w, h + 1, QColor(100, 100, 200) );        /// \todo: definire questo colore nelle preferenze
501                p.drawRect( x, y + 1, w, h + 1 );
502        }
503}
504
505
506
507
508void DrumPatternEditor::__draw_grid( QPainter& p )
509{
510        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
511        static const QColor res_1( pStyle->m_patternEditor_line1Color.getRed(), pStyle->m_patternEditor_line1Color.getGreen(), pStyle->m_patternEditor_line1Color.getBlue() );
512        static const QColor res_2( pStyle->m_patternEditor_line2Color.getRed(), pStyle->m_patternEditor_line2Color.getGreen(), pStyle->m_patternEditor_line2Color.getBlue() );
513        static const QColor res_3( pStyle->m_patternEditor_line3Color.getRed(), pStyle->m_patternEditor_line3Color.getGreen(), pStyle->m_patternEditor_line3Color.getBlue() );
514        static const QColor res_4( pStyle->m_patternEditor_line4Color.getRed(), pStyle->m_patternEditor_line4Color.getGreen(), pStyle->m_patternEditor_line4Color.getBlue() );
515        static const QColor res_5( pStyle->m_patternEditor_line5Color.getRed(), pStyle->m_patternEditor_line5Color.getGreen(), pStyle->m_patternEditor_line5Color.getBlue() );
516
517        // vertical lines
518        p.setPen( QPen( res_1, 0, Qt::DotLine ) );
519
520        int nBase;
521        if (m_bUseTriplets) {
522                nBase = 3;
523        }
524        else {
525                nBase = 4;
526        }
527
528        int n4th = 4 * MAX_NOTES / (nBase * 4);
529        int n8th = 4 * MAX_NOTES / (nBase * 8);
530        int n16th = 4 * MAX_NOTES / (nBase * 16);
531        int n32th = 4 * MAX_NOTES / (nBase * 32);
532        int n64th = 4 * MAX_NOTES / (nBase * 64);
533
534        int nNotes = MAX_NOTES;
535        if ( m_pPattern ) {
536                nNotes = m_pPattern->get_lenght();
537        }
538        if (!m_bUseTriplets) {
539                for ( int i = 0; i < nNotes + 1; i++ ) {
540                        uint x = 20 + i * m_nGridWidth;
541
542                        if ( (i % n4th) == 0 ) {
543                                if (m_nResolution >= 4) {
544                                        p.setPen( QPen( res_1, 0 ) );
545                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
546                                }
547                        }
548                        else if ( (i % n8th) == 0 ) {
549                                if (m_nResolution >= 8) {
550                                        p.setPen( QPen( res_2, 0 ) );
551                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
552                                }
553                        }
554                        else if ( (i % n16th) == 0 ) {
555                                if (m_nResolution >= 16) {
556                                        p.setPen( QPen( res_3, 0 ) );
557                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
558                                }
559                        }
560                        else if ( (i % n32th) == 0 ) {
561                                if (m_nResolution >= 32) {
562                                        p.setPen( QPen( res_4, 0 ) );
563                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
564                                }
565                        }
566                        else if ( (i % n64th) == 0 ) {
567                                if (m_nResolution >= 64) {
568                                        p.setPen( QPen( res_5, 0 ) );
569                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
570                                }
571                        }
572                }
573        }
574        else {  // Triplets
575                uint nCounter = 0;
576                int nSize = 4 * MAX_NOTES / (nBase * m_nResolution);
577
578                for ( int i = 0; i < nNotes + 1; i++ ) {
579                        uint x = 20 + i * m_nGridWidth;
580
581                        if ( (i % nSize) == 0) {
582                                if ((nCounter % 3) == 0) {
583                                        p.setPen( QPen( res_1, 0 ) );
584                                }
585                                else {
586                                        p.setPen( QPen( res_3, 0 ) );
587                                }
588                                p.drawLine(x, 1, x, m_nEditorHeight - 1);
589                                nCounter++;
590                        }
591                }
592        }
593
594
595        // fill the first half of the rect with a solid color
596        static const QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
597        static const QColor selectedRowColor( pStyle->m_patternEditor_selectedRowColor.getRed(), pStyle->m_patternEditor_selectedRowColor.getGreen(), pStyle->m_patternEditor_selectedRowColor.getBlue() );
598        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
599        Song *pSong = Hydrogen::get_instance()->getSong();
600        int nInstruments = pSong->get_instrument_list()->get_size();
601        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
602                uint y = m_nGridHeight * i + 1;
603                if ( i == (uint)nSelectedInstrument ) {
604                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), (int)( m_nGridHeight * 0.7 ), selectedRowColor );
605                }
606                else {
607                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), (int)( m_nGridHeight * 0.7 ), backgroundColor );
608                }
609        }
610
611}
612
613
614void DrumPatternEditor::__create_background( QPainter& p)
615{
616        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
617        static const QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
618        static const QColor alternateRowColor( pStyle->m_patternEditor_alternateRowColor.getRed(), pStyle->m_patternEditor_alternateRowColor.getGreen(), pStyle->m_patternEditor_alternateRowColor.getBlue() );
619        static const QColor lineColor( pStyle->m_patternEditor_lineColor.getRed(), pStyle->m_patternEditor_lineColor.getGreen(), pStyle->m_patternEditor_lineColor.getBlue() );
620
621        int nNotes = MAX_NOTES;
622        if ( m_pPattern ) {
623                nNotes = m_pPattern->get_lenght();
624        }
625
626        Song *pSong = Hydrogen::get_instance()->getSong();
627        int nInstruments = pSong->get_instrument_list()->get_size();
628
629        if ( m_nEditorHeight != (int)( m_nGridHeight * nInstruments ) ) {
630                // the number of instruments is changed...recreate all
631                m_nEditorHeight = m_nGridHeight * nInstruments;
632                resize( width(), m_nEditorHeight );
633        }
634
635        p.fillRect(0, 0, 20 + nNotes * m_nGridWidth, height(), backgroundColor);
636        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
637                uint y = m_nGridHeight * i;
638                if ( ( i % 2) != 0) {
639                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), m_nGridHeight, alternateRowColor );
640                }
641        }
642
643        // horizontal lines
644        p.setPen( lineColor );
645        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
646                uint y = m_nGridHeight * i + m_nGridHeight;
647                p.drawLine( 0, y, (20 + nNotes * m_nGridWidth), y);
648        }
649
650        p.drawLine( 0, m_nEditorHeight, (20 + nNotes * m_nGridWidth), m_nEditorHeight );
651}
652
653
654
655void DrumPatternEditor::paintEvent( QPaintEvent* /*ev*/ )
656{
657        //INFOLOG( "paint" );
658        //QWidget::paintEvent(ev);
659       
660        QPainter painter( this );
661        __draw_pattern( painter );
662}
663
664
665
666
667
668
669void DrumPatternEditor::showEvent ( QShowEvent *ev )
670{
671        UNUSED( ev );
672        updateEditor();
673}
674
675
676
677void DrumPatternEditor::hideEvent ( QHideEvent *ev )
678{
679        UNUSED( ev );
680}
681
682
683
684void DrumPatternEditor::setResolution(uint res, bool bUseTriplets)
685{
686        this->m_nResolution = res;
687        this->m_bUseTriplets = bUseTriplets;
688
689        // redraw all
690        update( 0, 0, width(), height() );
691        m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
692        m_pPatternEditorPanel->getPanEditor()->updateEditor();
693        m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
694        m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
695        /// \todo [DrumPatternEditor::setResolution] aggiornare la risoluzione del Ruler in alto."
696}
697
698
699
700void DrumPatternEditor::zoom_in()
701{
702        if (m_nGridWidth >= 3){
703                m_nGridWidth *= 2;
704        }else
705        {
706                m_nGridWidth *= 1.5;
707        }
708        updateEditor();
709}
710
711
712
713void DrumPatternEditor::zoom_out()
714{
715        if ( m_nGridWidth > 1.5 ) {
716                if (m_nGridWidth > 3){
717                        m_nGridWidth /= 2;
718                }else
719                {
720                        m_nGridWidth /= 1.5;
721                }
722                updateEditor();
723        }
724}
725
726void DrumPatternEditor::selectedInstrumentChangedEvent()
727{
728        update( 0, 0, width(), height() );
729}
730
731
732/// This method is called from another thread (audio engine)
733void DrumPatternEditor::patternModifiedEvent()
734{
735        update( 0, 0, width(), height() );
736}
737
738
739void DrumPatternEditor::patternChangedEvent()
740{
741        updateEditor();
742}
743
744void DrumPatternEditor::selectedPatternChangedEvent()
745{
746        //cout << "selected pattern changed EVENT" << endl;
747        updateEditor();
748}
749
750
751
Note: See TracBrowser for help on using the browser.