root/trunk/gui/src/PatternEditor/DrumPatternEditor.cpp @ 214

Revision 214, 19.0 KB (checked in by smoors, 5 years ago)

Bugfix for  http://hydrogen-music.org/devel/ticket/15

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                        m_pPattern->note_map.insert( std::make_pair( nPosition, pNote ) );
189
190                        // hear note
191                        Preferences *pref = Preferences::getInstance();
192                        if ( pref->getHearNewNotes() ) {
193                                Note *pNote2 = new Note( pSelectedInstrument, 0, fVelocity, fPan_L, fPan_R, nLength, fPitch);
194                                AudioEngine::get_instance()->get_sampler()->note_on(pNote2);
195                        }
196                }
197                pSong->__is_modified = true;
198                AudioEngine::get_instance()->unlock(); // unlock the audio engine
199        }
200        else if (ev->button() == Qt::RightButton ) {
201                m_bRightBtnPressed = true;
202                m_pDraggedNote = NULL;
203
204                int nRealColumn = (ev->x() - 20) /  (int)m_nGridWidth;
205
206                AudioEngine::get_instance()->lock( "DrumPatternEditor::mousePressEvent" );
207
208                std::multimap <int, Note*>::iterator pos;
209                for ( pos = m_pPattern->note_map.lower_bound( nColumn ); pos != m_pPattern->note_map.upper_bound( nColumn ); ++pos ) {
210                        Note *pNote = pos->second;
211                        assert( pNote );
212
213                        if ( pNote->get_instrument() == pSelectedInstrument ) {
214                                m_pDraggedNote = pNote;
215                                break;
216                        }
217                }
218                if ( !m_pDraggedNote ) {
219                        for ( pos = m_pPattern->note_map.lower_bound( nRealColumn ); pos != m_pPattern->note_map.upper_bound( nRealColumn ); ++pos ) {
220                                Note *pNote = pos->second;
221                                assert( pNote );
222
223                                if ( pNote->get_instrument() == pSelectedInstrument ) {
224                                        m_pDraggedNote = pNote;
225                                        break;
226                                }
227                        }
228                }
229                // potrei essere sulla coda di una nota precedente..
230                for ( int nCol = 0; nCol < nRealColumn; ++nCol ) {
231                        if ( m_pDraggedNote ) break;
232                        for ( pos = m_pPattern->note_map.lower_bound( nCol ); pos != m_pPattern->note_map.upper_bound( nCol ); ++pos ) {
233                                Note *pNote = pos->second;
234                                assert( pNote );
235
236                                if ( pNote->get_instrument() == pSelectedInstrument ) {
237                                        m_pDraggedNote = pNote;
238                                        break;
239                                }
240                        }
241                }
242                AudioEngine::get_instance()->unlock();
243        }
244
245        // update the selected line
246        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
247        if (nSelectedInstrument != row) {
248                Hydrogen::get_instance()->setSelectedInstrumentNumber( row );
249        }
250        else {
251                update( 0, 0, width(), height() );
252                m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
253                m_pPatternEditorPanel->getPanEditor()->updateEditor();
254        }
255}
256
257
258
259void DrumPatternEditor::mouseReleaseEvent(QMouseEvent *ev)
260{
261        UNUSED( ev );
262        setCursor( QCursor( Qt::ArrowCursor ) );
263
264        if (m_pPattern == NULL) {
265                return;
266        }
267}
268
269
270
271void DrumPatternEditor::mouseMoveEvent(QMouseEvent *ev)
272{
273        if (m_pPattern == NULL) {
274                return;
275        }
276
277        int row = MAX_INSTRUMENTS - 1 - (ev->y()  / (int)m_nGridHeight);
278        if (row >= MAX_INSTRUMENTS) {
279                return;
280        }
281
282        if (m_bRightBtnPressed && m_pDraggedNote ) {
283                int nTickColumn = getColumn( ev );
284
285                AudioEngine::get_instance()->lock("DrumPatternEditor::mouseMoveEvent"); // lock the audio engine
286                int nLen = nTickColumn - (int)m_pDraggedNote->get_position();
287
288                if (nLen <= 0) {
289                        nLen = -1;
290                }
291                m_pDraggedNote->set_lenght( nLen );
292
293                Hydrogen::get_instance()->getSong()->__is_modified = true;
294                AudioEngine::get_instance()->unlock(); // unlock the audio engine
295
296                //__draw_pattern();
297                update( 0, 0, width(), height() );
298                m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
299                m_pPatternEditorPanel->getPanEditor()->updateEditor();
300        }
301
302}
303
304
305
306void DrumPatternEditor::keyPressEvent (QKeyEvent *ev)
307{
308        ev->ignore();
309}
310
311
312
313///
314/// Draws a pattern
315///
316void DrumPatternEditor::__draw_pattern(QPainter& painter)
317{
318        const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
319        const QColor selectedRowColor( pStyle->m_patternEditor_selectedRowColor.getRed(), pStyle->m_patternEditor_selectedRowColor.getGreen(), pStyle->m_patternEditor_selectedRowColor.getBlue() );
320
321        __create_background( painter );
322
323        if (m_pPattern == NULL) {
324                return;
325        }
326
327        int nNotes = m_pPattern->get_lenght();
328        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
329        Song *pSong = Hydrogen::get_instance()->getSong();
330
331        InstrumentList * pInstrList = pSong->get_instrument_list();
332
333       
334
335        if ( m_nEditorHeight != (int)( m_nGridHeight * pInstrList->get_size() ) ) {
336                // the number of instruments is changed...recreate all
337                m_nEditorHeight = m_nGridHeight * pInstrList->get_size();
338                resize( width(), m_nEditorHeight );
339        }
340
341        for ( uint nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
342                uint y = m_nGridHeight * nInstr;
343                if ( nInstr == (uint)nSelectedInstrument ) {    // selected instrument
344                        painter.fillRect( 0, y + 1, (20 + nNotes * m_nGridWidth), m_nGridHeight - 1, selectedRowColor );
345                }
346        }
347
348
349        // draw the grid
350        __draw_grid( painter );
351       
352
353        /*
354                BUGFIX
355               
356                if m_pPattern is not renewed every time we draw a note,
357                hydrogen will crash after you save a song and create a new one.
358                -smoors
359        */
360        Hydrogen *pEngine = Hydrogen::get_instance();
361        PatternList *pPatternList = pEngine->getSong()->get_pattern_list();
362        int nSelectedPatternNumber = pEngine->getSelectedPatternNumber();
363        if ( (nSelectedPatternNumber != -1) && ( (uint)nSelectedPatternNumber < pPatternList->get_size() ) ) {
364                m_pPattern = pPatternList->get( nSelectedPatternNumber );
365        }
366        else {
367                m_pPattern = NULL;
368        }
369        // ~ FIX
370
371
372        cout << m_pPattern->note_map.size() << endl;
373
374        if( m_pPattern->note_map.size() == 0) return;
375
376        std::multimap <int, Note*>::iterator pos;
377        for ( pos = m_pPattern->note_map.begin(); pos != m_pPattern->note_map.end(); pos++ ) {
378                Note *note = pos->second;
379                assert( note );
380                __draw_note( note, painter );
381        }
382}
383
384
385///
386/// Draws a note
387///
388void DrumPatternEditor::__draw_note( Note *note, QPainter& p )
389{
390        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
391        static const QColor noteColor( pStyle->m_patternEditor_noteColor.getRed(), pStyle->m_patternEditor_noteColor.getGreen(), pStyle->m_patternEditor_noteColor.getBlue() );
392
393        p.setRenderHint( QPainter::Antialiasing );
394
395        int nInstrument = -1;
396        InstrumentList * pInstrList = Hydrogen::get_instance()->getSong()->get_instrument_list();
397        for ( uint nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
398                Instrument *pInstr = pInstrList->get( nInstr );
399                if ( pInstr == note->get_instrument() ) {
400                        nInstrument = nInstr;
401                        break;
402                }
403        }
404        if ( nInstrument == -1 ) {
405                ERRORLOG( "Instrument not found..skipping note" );
406                return;
407        }
408
409        uint pos = note->get_position();
410
411        p.setPen( noteColor );
412
413        if ( note->get_lenght() == -1 ) {       // trigger note
414                uint x_pos = 20 + (pos * m_nGridWidth);// - m_nGridWidth / 2.0;
415
416                uint y_pos = ( nInstrument * m_nGridHeight) + (m_nGridHeight / 2) - 3;
417
418                // draw the "dot"
419                p.drawLine(x_pos, y_pos, x_pos + 3, y_pos + 3);         // A
420                p.drawLine(x_pos, y_pos, x_pos - 3, y_pos + 3);         // B
421                p.drawLine(x_pos, y_pos + 6, x_pos + 3, y_pos + 3);     // C
422                p.drawLine(x_pos - 3, y_pos + 3, x_pos, y_pos + 6);     // D
423
424                p.drawLine(x_pos, y_pos + 1, x_pos + 2, y_pos + 3);
425                p.drawLine(x_pos, y_pos + 1, x_pos - 2, y_pos + 3);
426                p.drawLine(x_pos, y_pos + 5, x_pos + 2, y_pos + 3);
427                p.drawLine(x_pos - 2, y_pos + 3, x_pos, y_pos + 5);
428
429                p.drawLine(x_pos, y_pos + 2, x_pos + 1, y_pos + 3);
430                p.drawLine(x_pos, y_pos + 2, x_pos - 1, y_pos + 3);
431                p.drawLine(x_pos, y_pos + 4, x_pos + 1, y_pos + 3);
432                p.drawLine(x_pos - 1, y_pos + 3, x_pos, y_pos + 4);
433        }
434        else {
435                uint x = 20 + (pos * m_nGridWidth);
436                int w = m_nGridWidth * note->get_lenght();
437                w = w - 1;      // lascio un piccolo spazio tra una nota ed un altra
438
439                int y = (int) ( ( nInstrument ) * m_nGridHeight  + (m_nGridHeight / 100.0 * 30.0) );
440                int h = (int) (m_nGridHeight - ((m_nGridHeight / 100.0 * 30.0) * 2.0) );
441
442                p.fillRect( x, y + 1, w, h + 1, QColor(100, 100, 200) );        /// \todo: definire questo colore nelle preferenze
443                p.drawRect( x, y + 1, w, h + 1 );
444        }
445}
446
447
448
449
450void DrumPatternEditor::__draw_grid( QPainter& p )
451{
452        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
453        static const QColor res_1( pStyle->m_patternEditor_line1Color.getRed(), pStyle->m_patternEditor_line1Color.getGreen(), pStyle->m_patternEditor_line1Color.getBlue() );
454        static const QColor res_2( pStyle->m_patternEditor_line2Color.getRed(), pStyle->m_patternEditor_line2Color.getGreen(), pStyle->m_patternEditor_line2Color.getBlue() );
455        static const QColor res_3( pStyle->m_patternEditor_line3Color.getRed(), pStyle->m_patternEditor_line3Color.getGreen(), pStyle->m_patternEditor_line3Color.getBlue() );
456        static const QColor res_4( pStyle->m_patternEditor_line4Color.getRed(), pStyle->m_patternEditor_line4Color.getGreen(), pStyle->m_patternEditor_line4Color.getBlue() );
457        static const QColor res_5( pStyle->m_patternEditor_line5Color.getRed(), pStyle->m_patternEditor_line5Color.getGreen(), pStyle->m_patternEditor_line5Color.getBlue() );
458
459        // vertical lines
460        p.setPen( QPen( res_1, 0, Qt::DotLine ) );
461
462        int nBase;
463        if (m_bUseTriplets) {
464                nBase = 3;
465        }
466        else {
467                nBase = 4;
468        }
469
470        int n4th = 4 * MAX_NOTES / (nBase * 4);
471        int n8th = 4 * MAX_NOTES / (nBase * 8);
472        int n16th = 4 * MAX_NOTES / (nBase * 16);
473        int n32th = 4 * MAX_NOTES / (nBase * 32);
474        int n64th = 4 * MAX_NOTES / (nBase * 64);
475
476        int nNotes = MAX_NOTES;
477        if ( m_pPattern ) {
478                nNotes = m_pPattern->get_lenght();
479        }
480        if (!m_bUseTriplets) {
481                for ( int i = 0; i < nNotes + 1; i++ ) {
482                        uint x = 20 + i * m_nGridWidth;
483
484                        if ( (i % n4th) == 0 ) {
485                                if (m_nResolution >= 4) {
486                                        p.setPen( QPen( res_1, 0 ) );
487                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
488                                }
489                        }
490                        else if ( (i % n8th) == 0 ) {
491                                if (m_nResolution >= 8) {
492                                        p.setPen( QPen( res_2, 0 ) );
493                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
494                                }
495                        }
496                        else if ( (i % n16th) == 0 ) {
497                                if (m_nResolution >= 16) {
498                                        p.setPen( QPen( res_3, 0 ) );
499                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
500                                }
501                        }
502                        else if ( (i % n32th) == 0 ) {
503                                if (m_nResolution >= 32) {
504                                        p.setPen( QPen( res_4, 0 ) );
505                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
506                                }
507                        }
508                        else if ( (i % n64th) == 0 ) {
509                                if (m_nResolution >= 64) {
510                                        p.setPen( QPen( res_5, 0 ) );
511                                        p.drawLine(x, 1, x, m_nEditorHeight - 1);
512                                }
513                        }
514                }
515        }
516        else {  // Triplets
517                uint nCounter = 0;
518                int nSize = 4 * MAX_NOTES / (nBase * m_nResolution);
519
520                for ( int i = 0; i < nNotes + 1; i++ ) {
521                        uint x = 20 + i * m_nGridWidth;
522
523                        if ( (i % nSize) == 0) {
524                                if ((nCounter % 3) == 0) {
525                                        p.setPen( QPen( res_1, 0 ) );
526                                }
527                                else {
528                                        p.setPen( QPen( res_3, 0 ) );
529                                }
530                                p.drawLine(x, 1, x, m_nEditorHeight - 1);
531                                nCounter++;
532                        }
533                }
534        }
535
536
537        // fill the first half of the rect with a solid color
538        static const QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
539        static const QColor selectedRowColor( pStyle->m_patternEditor_selectedRowColor.getRed(), pStyle->m_patternEditor_selectedRowColor.getGreen(), pStyle->m_patternEditor_selectedRowColor.getBlue() );
540        int nSelectedInstrument = Hydrogen::get_instance()->getSelectedInstrumentNumber();
541        Song *pSong = Hydrogen::get_instance()->getSong();
542        int nInstruments = pSong->get_instrument_list()->get_size();
543        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
544                uint y = m_nGridHeight * i + 1;
545                if ( i == (uint)nSelectedInstrument ) {
546                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), (int)( m_nGridHeight * 0.7 ), selectedRowColor );
547                }
548                else {
549                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), (int)( m_nGridHeight * 0.7 ), backgroundColor );
550                }
551        }
552
553}
554
555
556void DrumPatternEditor::__create_background( QPainter& p)
557{
558        static const UIStyle *pStyle = Preferences::getInstance()->getDefaultUIStyle();
559        static const QColor backgroundColor( pStyle->m_patternEditor_backgroundColor.getRed(), pStyle->m_patternEditor_backgroundColor.getGreen(), pStyle->m_patternEditor_backgroundColor.getBlue() );
560        static const QColor alternateRowColor( pStyle->m_patternEditor_alternateRowColor.getRed(), pStyle->m_patternEditor_alternateRowColor.getGreen(), pStyle->m_patternEditor_alternateRowColor.getBlue() );
561        static const QColor lineColor( pStyle->m_patternEditor_lineColor.getRed(), pStyle->m_patternEditor_lineColor.getGreen(), pStyle->m_patternEditor_lineColor.getBlue() );
562
563        int nNotes = MAX_NOTES;
564        if ( m_pPattern ) {
565                nNotes = m_pPattern->get_lenght();
566        }
567
568        Song *pSong = Hydrogen::get_instance()->getSong();
569        int nInstruments = pSong->get_instrument_list()->get_size();
570
571        if ( m_nEditorHeight != (int)( m_nGridHeight * nInstruments ) ) {
572                // the number of instruments is changed...recreate all
573                m_nEditorHeight = m_nGridHeight * nInstruments;
574                resize( width(), m_nEditorHeight );
575        }
576
577        p.fillRect(0, 0, 20 + nNotes * m_nGridWidth, height(), backgroundColor);
578        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
579                uint y = m_nGridHeight * i;
580                if ( ( i % 2) != 0) {
581                        p.fillRect( 0, y, (20 + nNotes * m_nGridWidth), m_nGridHeight, alternateRowColor );
582                }
583        }
584
585        // horizontal lines
586        p.setPen( lineColor );
587        for ( uint i = 0; i < (uint)nInstruments; i++ ) {
588                uint y = m_nGridHeight * i + m_nGridHeight;
589                p.drawLine( 0, y, (20 + nNotes * m_nGridWidth), y);
590        }
591
592        p.drawLine( 0, m_nEditorHeight, (20 + nNotes * m_nGridWidth), m_nEditorHeight );
593}
594
595
596
597void DrumPatternEditor::paintEvent( QPaintEvent* /*ev*/ )
598{
599        //INFOLOG( "paint" );
600        //QWidget::paintEvent(ev);
601       
602        QPainter painter( this );
603        __draw_pattern( painter );
604}
605
606
607
608
609
610
611void DrumPatternEditor::showEvent ( QShowEvent *ev )
612{
613        UNUSED( ev );
614        updateEditor();
615}
616
617
618
619void DrumPatternEditor::hideEvent ( QHideEvent *ev )
620{
621        UNUSED( ev );
622}
623
624
625
626void DrumPatternEditor::setResolution(uint res, bool bUseTriplets)
627{
628        this->m_nResolution = res;
629        this->m_bUseTriplets = bUseTriplets;
630
631        // redraw all
632        update( 0, 0, width(), height() );
633        m_pPatternEditorPanel->getVelocityEditor()->updateEditor();
634        m_pPatternEditorPanel->getPanEditor()->updateEditor();
635        /// \todo [DrumPatternEditor::setResolution] aggiornare la risoluzione del Ruler in alto."
636}
637
638
639void DrumPatternEditor::zoom_in()
640{
641        m_nGridWidth = m_nGridWidth * 2;
642        updateEditor();
643}
644
645
646
647void DrumPatternEditor::zoom_out()
648{
649        m_nGridWidth = m_nGridWidth / 2;
650        if (m_nGridWidth < 3) {
651                m_nGridWidth = 3;
652        }
653        updateEditor();
654}
655
656
657void DrumPatternEditor::selectedInstrumentChangedEvent()
658{
659        update( 0, 0, width(), height() );
660}
661
662
663/// This method is called from another thread (audio engine)
664void DrumPatternEditor::patternModifiedEvent()
665{
666        update( 0, 0, width(), height() );
667}
668
669
670void DrumPatternEditor::patternChangedEvent()
671{
672        updateEditor();
673}
674
675void DrumPatternEditor::selectedPatternChangedEvent()
676{
677        //cout << "selected pattern changed EVENT" << endl;
678        updateEditor();
679}
680
681
682
Note: See TracBrowser for help on using the browser.