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

Revision 677, 21.6 KB (checked in by wolke, 5 years ago)

small note_lenght fix

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 = 0;
319                if(nLen > -1){
320                        fStep = pow( 1.0594630943593, ( double )fNotePitch );
321                }else
322                {
323                        fStep = 1.0;
324                }
325                m_pDraggedNote->set_lenght( nLen * fStep);
326
327                Hydrogen::get_instance()->getSong()->__is_modified = true;
328                AudioEngine::get_instance()->unlock(); // unlock the audio engine
329
330                //__draw_pattern();
331                update( 0, 0, width(), height() );
332                m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
333                m_pPatternEditorPanel->getPanEditor()->updateEditor();
334                m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
335                m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
336        }
337
338}
339
340
341
342void DrumPatternEditor::keyPressEvent (QKeyEvent *ev)
343{
344        ev->ignore();
345}
346
347
348
349///
350/// Draws a pattern
351///
352void DrumPatternEditor::__draw_pattern(QPainter& painter)
353{
354        const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
355        const QColor selectedRowColor( pStyle->m_patternEditor_selectedRowColor.getRed(), pStyle->m_patternEditor_selectedRowColor.getGreen(), pStyle->m_patternEditor_selectedRowColor.getBlue() );
356
357        __create_background( painter );
358
359        if (m_pPattern == NULL) {
360                return;
361        }
362
363        int nNotes = m_pPattern->get_lenght();
364        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
365        Song *pSong = Hydrogen::get_instance()->getSong();
366
367        InstrumentList * pInstrList = pSong->get_instrument_list();
368
369       
370
371        if ( m_nEditorHeight != (int)( m_nGridHeight * pInstrList->get_size() ) ) {
372                // the number of instruments is changed...recreate all
373                m_nEditorHeight = m_nGridHeight * pInstrList->get_size();
374                resize( width(), m_nEditorHeight );
375        }
376
377        for ( uint nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
378                uint y = m_nGridHeight * nInstr;
379                if ( nInstr == (uint)nSelectedInstrument ) {    // selected instrument
380                        painter.fillRect( 0, y + 1, ( 20 + nNotes * m_nGridWidth ), m_nGridHeight - 1, selectedRowColor );
381                }
382        }
383
384
385        // draw the grid
386        __draw_grid( painter );
387       
388
389        /*
390                BUGFIX
391               
392                if m_pPattern is not renewed every time we draw a note,
393                hydrogen will crash after you save a song and create a new one.
394                -smoors
395        */
396        Hydrogen *pEngine = Hydrogen::get_instance();
397        PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
398        int nSelectedPatternNumber = pEngine->getSelectedPatternNumber();
399        if ( (nSelectedPatternNumber != -1) && ( (uint)nSelectedPatternNumber < pPatternList->get_size() ) ) {
400                m_pPattern = pPatternList->get( nSelectedPatternNumber );
401        }
402        else {
403                m_pPattern = NULL;
404        }
405        // ~ FIX
406
407
408
409        if( m_pPattern->note_map.size() == 0) return;
410
411        std::multimap <int, Note*>::iterator pos;
412        for ( pos = m_pPattern->note_map.begin(); pos != m_pPattern->note_map.end(); pos++ ) {
413                Note *note = pos->second;
414                assert( note );
415                __draw_note( note, painter );
416        }
417}
418
419
420///
421/// Draws a note
422///
423void DrumPatternEditor::__draw_note( Note *note, QPainter& p )
424{
425        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
426        static const QColor noteColor( pStyle->m_patternEditor_noteColor.getRed(), pStyle->m_patternEditor_noteColor.getGreen(), pStyle->m_patternEditor_noteColor.getBlue() );
427        static const QColor noteoffColor( pStyle->m_patternEditor_noteoffColor.getRed(), pStyle->m_patternEditor_noteoffColor.getGreen(), pStyle->m_patternEditor_noteoffColor.getBlue() );
428
429        p.setRenderHint( QPainter::Antialiasing );
430
431        int nInstrument = -1;
432        InstrumentList * pInstrList = Hydrogen::get_instance()->getSong()->get_instrument_list();
433        for ( uint nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
434                Instrument *pInstr = pInstrList->get( nInstr );
435                if ( pInstr == note->get_instrument() ) {
436                        nInstrument = nInstr;
437                        break;
438                }
439        }
440        if ( nInstrument == -1 ) {
441                ERRORLOG( "Instrument not found..skipping note" );
442                return;
443        }
444
445        uint pos = note->get_position();
446
447        p.setPen( noteColor );
448
449        if ( note->get_lenght() == -1 && note->get_noteoff() == false ) {       // trigger note
450                uint x_pos = 20 + (pos * m_nGridWidth);// - m_nGridWidth / 2.0;
451
452                uint y_pos = ( nInstrument * m_nGridHeight) + (m_nGridHeight / 2) - 3;
453
454                // draw the "dot"
455                p.drawLine(x_pos, y_pos, x_pos + 3, y_pos + 3);         // A
456                p.drawLine(x_pos, y_pos, x_pos - 3, y_pos + 3);         // B
457                p.drawLine(x_pos, y_pos + 6, x_pos + 3, y_pos + 3);     // C
458                p.drawLine(x_pos - 3, y_pos + 3, x_pos, y_pos + 6);     // D
459
460                p.drawLine(x_pos, y_pos + 1, x_pos + 2, y_pos + 3);
461                p.drawLine(x_pos, y_pos + 1, x_pos - 2, y_pos + 3);
462                p.drawLine(x_pos, y_pos + 5, x_pos + 2, y_pos + 3);
463                p.drawLine(x_pos - 2, y_pos + 3, x_pos, y_pos + 5);
464
465                p.drawLine(x_pos, y_pos + 2, x_pos + 1, y_pos + 3);
466                p.drawLine(x_pos, y_pos + 2, x_pos - 1, y_pos + 3);
467                p.drawLine(x_pos, y_pos + 4, x_pos + 1, y_pos + 3);
468                p.drawLine(x_pos - 1, y_pos + 3, x_pos, y_pos + 4);
469        }
470        else if ( note->get_lenght() == 1 && note->get_noteoff() == true ){
471                p.setPen( noteoffColor );
472                uint x_pos = 20 + ( pos * m_nGridWidth );// - m_nGridWidth / 2.0;
473
474                uint y_pos = ( nInstrument * m_nGridHeight ) + (m_nGridHeight / 2) - 3;
475       
476                // draw the "dot"
477                p.drawLine(x_pos, y_pos, x_pos + 3, y_pos + 3);         // A
478                p.drawLine(x_pos, y_pos, x_pos - 3, y_pos + 3);         // B
479                p.drawLine(x_pos, y_pos + 6, x_pos + 3, y_pos + 3);     // C
480                p.drawLine(x_pos - 3, y_pos + 3, x_pos, y_pos + 6);     // D
481
482                p.drawLine(x_pos, y_pos + 1, x_pos + 2, y_pos + 3);
483                p.drawLine(x_pos, y_pos + 1, x_pos - 2, y_pos + 3);
484                p.drawLine(x_pos, y_pos + 5, x_pos + 2, y_pos + 3);
485                p.drawLine(x_pos - 2, y_pos + 3, x_pos, y_pos + 5);
486
487                p.drawLine(x_pos, y_pos + 2, x_pos + 1, y_pos + 3);
488                p.drawLine(x_pos, y_pos + 2, x_pos - 1, y_pos + 3);
489                p.drawLine(x_pos, y_pos + 4, x_pos + 1, y_pos + 3);
490                p.drawLine(x_pos - 1, y_pos + 3, x_pos, y_pos + 4);     
491
492
493        }               
494        else {
495                float fNotePitch = note->m_noteKey.m_nOctave * 12 + note->m_noteKey.m_key;
496                float fStep = pow( 1.0594630943593, ( double )fNotePitch );
497
498                uint x = 20 + (pos * m_nGridWidth);
499                int w = m_nGridWidth * note->get_lenght() / fStep;
500                w = w - 1;      // lascio un piccolo spazio tra una nota ed un altra
501
502                int y = (int) ( ( nInstrument ) * m_nGridHeight  + (m_nGridHeight / 100.0 * 30.0) );
503                int h = (int) (m_nGridHeight - ((m_nGridHeight / 100.0 * 30.0) * 2.0) );
504
505                p.fillRect( x, y + 1, w, h + 1, QColor(100, 100, 200) );        /// \todo: definire questo colore nelle preferenze
506                p.drawRect( x, y + 1, w, h + 1 );
507        }
508}
509
510
511
512
513void DrumPatternEditor::__draw_grid( QPainter& p )
514{
515        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
516        static const QColor res_1( pStyle->m_patternEditor_line1Color.getRed(), pStyle->m_patternEditor_line1Color.getGreen(), pStyle->m_patternEditor_line1Color.getBlue() );
517        static const QColor res_2( pStyle->m_patternEditor_line2Color.getRed(), pStyle->m_patternEditor_line2Color.getGreen(), pStyle->m_patternEditor_line2Color.getBlue() );
518        static const QColor res_3( pStyle->m_patternEditor_line3Color.getRed(), pStyle->m_patternEditor_line3Color.getGreen(), pStyle->m_patternEditor_line3Color.getBlue() );
519        static const QColor res_4( pStyle->m_patternEditor_line4Color.getRed(), pStyle->m_patternEditor_line4Color.getGreen(), pStyle->m_patternEditor_line4Color.getBlue() );
520        static const QColor res_5( pStyle->m_patternEditor_line5Color.getRed(), pStyle->m_patternEditor_line5Color.getGreen(), pStyle->m_patternEditor_line5Color.getBlue() );
521
522        // vertical lines
523        p.setPen( QPen( res_1, 0, Qt::DotLine ) );
524
525        int nBase;
526        if (m_bUseTriplets) {
527                nBase = 3;
528        }
529        else {
530                nBase = 4;
531        }
532
533        int n4th = 4 * MAX_NOTES / (nBase * 4);
534        int n8th = 4 * MAX_NOTES / (nBase * 8);
535        int n16th = 4 * MAX_NOTES / (nBase * 16);
536        int n32th = 4 * MAX_NOTES / (nBase * 32);
537        int n64th = 4 * MAX_NOTES / (nBase * 64);
538
539        int nNotes = MAX_NOTES;
540        if ( m_pPattern ) {
541                nNotes = m_pPattern->get_lenght();
542        }
543        if (!m_bUseTriplets) {
544                for ( int i = 0; i < nNotes + 1; i++ ) {
545                        uint x = 20 + i * m_nGridWidth;
546
547                        if ( (i % n4th) == 0 ) {
548                                if (m_nResolution >= 4) {
549                                        p.setPen( QPen( res_1, 0 ) );
550                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
551                                }
552                        }
553                        else if ( (i % n8th) == 0 ) {
554                                if (m_nResolution >= 8) {
555                                        p.setPen( QPen( res_2, 0 ) );
556                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
557                                }
558                        }
559                        else if ( (i % n16th) == 0 ) {
560                                if (m_nResolution >= 16) {
561                                        p.setPen( QPen( res_3, 0 ) );
562                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
563                                }
564                        }
565                        else if ( (i % n32th) == 0 ) {
566                                if (m_nResolution >= 32) {
567                                        p.setPen( QPen( res_4, 0 ) );
568                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
569                                }
570                        }
571                        else if ( (i % n64th) == 0 ) {
572                                if (m_nResolution >= 64) {
573                                        p.setPen( QPen( res_5, 0 ) );
574                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
575                                }
576                        }
577                }
578        }
579        else {  // Triplets
580                uint nCounter = 0;
581                int nSize = 4 * MAX_NOTES / (nBase * m_nResolution);
582
583                for ( int i = 0; i < nNotes + 1; i++ ) {
584                        uint x = 20 + i * m_nGridWidth;
585
586                        if ( (i % nSize) == 0) {
587                                if ((nCounter % 3) == 0) {
588                                        p.setPen( QPen( res_1, 0 ) );
589                                }
590                                else {
591                                        p.setPen( QPen( res_3, 0 ) );
592                                }
593                                p.drawLine(x, 1, x, m_nEditorHeight - 1);
594                                nCounter++;
595                        }
596                }
597        }
598
599
600        // fill the first half of the rect with a solid color
601        static const QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
602        static const QColor selectedRowColor( pStyle->m_patternEditor_selectedRowColor.getRed(), pStyle->m_patternEditor_selectedRowColor.getGreen(), pStyle->m_patternEditor_selectedRowColor.getBlue() );
603        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
604        Song *pSong = Hydrogen::get_instance()->getSong();
605        int nInstruments = pSong->get_instrument_list()->get_size();
606        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
607                uint y = m_nGridHeight * i + 1;
608                if ( i == (uint)nSelectedInstrument ) {
609                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), (int)( m_nGridHeight * 0.7 ), selectedRowColor );
610                }
611                else {
612                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), (int)( m_nGridHeight * 0.7 ), backgroundColor );
613                }
614        }
615
616}
617
618
619void DrumPatternEditor::__create_background( QPainter& p)
620{
621        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
622        static const QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
623        static const QColor alternateRowColor( pStyle->m_patternEditor_alternateRowColor.getRed(), pStyle->m_patternEditor_alternateRowColor.getGreen(), pStyle->m_patternEditor_alternateRowColor.getBlue() );
624        static const QColor lineColor( pStyle->m_patternEditor_lineColor.getRed(), pStyle->m_patternEditor_lineColor.getGreen(), pStyle->m_patternEditor_lineColor.getBlue() );
625
626        int nNotes = MAX_NOTES;
627        if ( m_pPattern ) {
628                nNotes = m_pPattern->get_lenght();
629        }
630
631        Song *pSong = Hydrogen::get_instance()->getSong();
632        int nInstruments = pSong->get_instrument_list()->get_size();
633
634        if ( m_nEditorHeight != (int)( m_nGridHeight * nInstruments ) ) {
635                // the number of instruments is changed...recreate all
636                m_nEditorHeight = m_nGridHeight * nInstruments;
637                resize( width(), m_nEditorHeight );
638        }
639
640        p.fillRect(0, 0, 20 + nNotes * m_nGridWidth, height(), backgroundColor);
641        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
642                uint y = m_nGridHeight * i;
643                if ( ( i % 2) != 0) {
644                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), m_nGridHeight, alternateRowColor );
645                }
646        }
647
648        // horizontal lines
649        p.setPen( lineColor );
650        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
651                uint y = m_nGridHeight * i + m_nGridHeight;
652                p.drawLine( 0, y, (20 + nNotes * m_nGridWidth), y);
653        }
654
655        p.drawLine( 0, m_nEditorHeight, (20 + nNotes * m_nGridWidth), m_nEditorHeight );
656}
657
658
659
660void DrumPatternEditor::paintEvent( QPaintEvent* /*ev*/ )
661{
662        //INFOLOG( "paint" );
663        //QWidget::paintEvent(ev);
664       
665        QPainter painter( this );
666        __draw_pattern( painter );
667}
668
669
670
671
672
673
674void DrumPatternEditor::showEvent ( QShowEvent *ev )
675{
676        UNUSED( ev );
677        updateEditor();
678}
679
680
681
682void DrumPatternEditor::hideEvent ( QHideEvent *ev )
683{
684        UNUSED( ev );
685}
686
687
688
689void DrumPatternEditor::setResolution(uint res, bool bUseTriplets)
690{
691        this->m_nResolution = res;
692        this->m_bUseTriplets = bUseTriplets;
693
694        // redraw all
695        update( 0, 0, width(), height() );
696        m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
697        m_pPatternEditorPanel->getPanEditor()->updateEditor();
698        m_pPatternEditorPanel->getLeadLagEditor()->updateEditor();
699        m_pPatternEditorPanel->getNoteKeyEditor()->updateEditor();
700        /// \todo [DrumPatternEditor::setResolution] aggiornare la risoluzione del Ruler in alto."
701}
702
703
704
705void DrumPatternEditor::zoom_in()
706{
707        if (m_nGridWidth >= 3){
708                m_nGridWidth *= 2;
709        }else
710        {
711                m_nGridWidth *= 1.5;
712        }
713        updateEditor();
714}
715
716
717
718void DrumPatternEditor::zoom_out()
719{
720        if ( m_nGridWidth > 1.5 ) {
721                if (m_nGridWidth > 3){
722                        m_nGridWidth /= 2;
723                }else
724                {
725                        m_nGridWidth /= 1.5;
726                }
727                updateEditor();
728        }
729}
730
731void DrumPatternEditor::selectedInstrumentChangedEvent()
732{
733        update( 0, 0, width(), height() );
734}
735
736
737/// This method is called from another thread (audio engine)
738void DrumPatternEditor::patternModifiedEvent()
739{
740        update( 0, 0, width(), height() );
741}
742
743
744void DrumPatternEditor::patternChangedEvent()
745{
746        updateEditor();
747}
748
749
750void DrumPatternEditor::selectedPatternChangedEvent()
751{
752        //cout << "selected pattern changed EVENT" << endl;
753        updateEditor();
754}
755
756
757
Note: See TracBrowser for help on using the browser.