~ubuntu-branches/ubuntu/precise/lmms/precise-updates

« back to all changes in this revision

Viewing changes to src/gui/piano_roll.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Артём Попов
  • Date: 2011-02-14 20:58:36 UTC
  • mfrom: (1.1.10 upstream) (3.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110214205836-2u41xus1d2mj8nfz
Tags: 0.4.10-1ubuntu1
* Merge from debian unstable (LP: #718801).  Remaining changes:
  - Replace build-dep on libwine-dev with wine1.2-dev to build
    against the newer Wine.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * piano_roll.cpp - implementation of piano-roll which is used for actual
3
3
 *                  writing of melodies
4
4
 *
5
 
 * Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
 
5
 * Copyright (c) 2004-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6
6
 * Copyright (c) 2008 Andrew Kelley <superjoe30/at/gmail/dot/com>
7
7
 *
8
8
 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
49
49
#include "Clipboard.h"
50
50
#include "combobox.h"
51
51
#include "debug.h"
52
 
#include "detuning_helper.h"
 
52
#include "DetuningHelper.h"
53
53
#include "embed.h"
54
54
#include "gui_templates.h"
55
55
#include "InstrumentTrack.h"
68
68
#include "tooltip.h"
69
69
 
70
70
 
71
 
typedef automationPattern::timeMap timeMap;
 
71
typedef AutomationPattern::timeMap timeMap;
72
72
 
73
73
 
74
74
extern Keys whiteKeys[];        // defined in piano_widget.cpp
721
721
        int middle_y = _y + KEY_LINE_HEIGHT / 2;
722
722
        _p.setPen( QColor( 0xFF, 0xDF, 0x20 ) );
723
723
 
724
 
        timeMap & map = _n->detuning()->getAutomationPattern()->getTimeMap();
 
724
        timeMap & map = _n->detuning()->automationPattern()->getTimeMap();
725
725
        for( timeMap::ConstIterator it = map.begin(); it != map.end(); ++it )
726
726
        {
727
727
                Sint32 pos_ticks = it.key();
898
898
 
899
899
                if( _ke->isAutoRepeat() == false && key_num > -1 )
900
900
                {
901
 
                        m_pattern->instrumentTrack()->
902
 
                                getPiano()->handleKeyPress( key_num );
 
901
                        m_pattern->instrumentTrack()->pianoModel()->
 
902
                                                                                                        handleKeyPress( key_num );
 
903
                        _ke->accept();
903
904
                }
904
905
        }
905
906
 
930
931
                                                        Qt::AltModifier );
931
932
                                }
932
933
                        }
 
934
                        _ke->accept();
933
935
                        break;
 
936
 
934
937
                case Qt::Key_Down:
935
938
                        if( _ke->modifiers() & Qt::ControlModifier 
936
939
                           && m_action == ActionNone )
956
959
                                                        Qt::AltModifier );
957
960
                                }
958
961
                        }
 
962
                        _ke->accept();
959
963
                        break;
960
964
 
961
965
                case Qt::Key_Left:
962
 
                {
963
966
                        if( _ke->modifiers() & Qt::ControlModifier &&
964
967
                                                        m_action == ActionNone )
965
968
                        {
997
1000
                                }                               
998
1001
                                
999
1002
                        }
 
1003
                        _ke->accept();
1000
1004
                        break;
1001
 
                }
 
1005
 
1002
1006
                case Qt::Key_Right:
1003
 
                {
1004
1007
                        if( _ke->modifiers() & Qt::ControlModifier 
1005
1008
                           && m_action == ActionNone)
1006
1009
                        {
1035
1038
                                }                               
1036
1039
                                
1037
1040
                        }
1038
 
                        
1039
 
                        
 
1041
                        _ke->accept();
1040
1042
                        break;
1041
 
                }
1042
1043
 
1043
1044
                case Qt::Key_C:
1044
1045
                        if( _ke->modifiers() & Qt::ControlModifier )
1045
1046
                        {
 
1047
                                _ke->accept();
1046
1048
                                copySelectedNotes();
1047
1049
                        }
1048
 
                        else
1049
 
                        {
1050
 
                                _ke->ignore();
1051
 
                        }
1052
1050
                        break;
1053
1051
 
1054
1052
                case Qt::Key_X:
1055
1053
                        if( _ke->modifiers() & Qt::ControlModifier )
1056
1054
                        {
 
1055
                                _ke->accept();
1057
1056
                                cutSelectedNotes();
1058
1057
                        }
1059
 
                        else
1060
 
                        {
1061
 
                                _ke->ignore();
1062
 
                        }
1063
1058
                        break;
1064
1059
 
1065
1060
                case Qt::Key_V:
1066
1061
                        if( _ke->modifiers() & Qt::ControlModifier )
1067
1062
                        {
 
1063
                                _ke->accept();
1068
1064
                                pasteNotes();
1069
1065
                        }
1070
 
                        else
1071
 
                        {
1072
 
                                _ke->ignore();
1073
 
                        }
1074
1066
                        break;
1075
1067
 
1076
1068
                case Qt::Key_A:
1077
1069
                        if( _ke->modifiers() & Qt::ControlModifier )
1078
1070
                        {
 
1071
                                _ke->accept();
1079
1072
                                m_selectButton->setChecked( true );
1080
1073
                                selectAll();
1081
1074
                                update();
1082
1075
                        }
1083
 
                        else
1084
 
                        {
1085
 
                                _ke->ignore();
1086
 
                        }
1087
1076
                        break;
1088
1077
 
1089
1078
                case Qt::Key_D:
1090
1079
                        if( _ke->modifiers() & Qt::ShiftModifier )
1091
1080
                        {
 
1081
                                _ke->accept();
1092
1082
                                m_drawButton->setChecked( true );
1093
1083
                        }
1094
 
                        else
1095
 
                        {
1096
 
                                _ke->ignore();
1097
 
                        }
1098
1084
                        break;
1099
1085
 
1100
1086
                case Qt::Key_E:
1101
1087
                        if( _ke->modifiers() & Qt::ShiftModifier )
1102
1088
                        {
 
1089
                                _ke->accept();
1103
1090
                                m_eraseButton->setChecked( true );
1104
1091
                        }
1105
 
                        else
1106
 
                        {
1107
 
                                _ke->ignore();
1108
 
                        }
1109
1092
                        break;
1110
1093
 
1111
1094
                case Qt::Key_S:
1112
1095
                        if( _ke->modifiers() & Qt::ShiftModifier )
1113
1096
                        {
 
1097
                                _ke->accept();
1114
1098
                                m_selectButton->setChecked( true );
1115
1099
                        }
1116
 
                        else
1117
 
                        {
1118
 
                                _ke->ignore();
1119
 
                        }
1120
1100
                        break;
1121
1101
                        
1122
1102
                case Qt::Key_T:
1123
1103
                        if( _ke->modifiers() & Qt::ShiftModifier )
1124
1104
                        {
 
1105
                                _ke->accept();
1125
1106
                                m_detuneButton->setChecked( true );
1126
1107
                        }
1127
 
                        else
1128
 
                        {
1129
 
                                _ke->ignore();
1130
 
                        }
1131
1108
                        break;
1132
1109
                        
1133
1110
                case Qt::Key_Delete:
1134
1111
                        deleteSelectedNotes();
 
1112
                        _ke->accept();
1135
1113
                        break;
1136
1114
 
1137
1115
                case Qt::Key_Space:
1143
1121
                        {
1144
1122
                                play();
1145
1123
                        }
 
1124
                        _ke->accept();
1146
1125
                        break;
1147
1126
 
1148
1127
                case Qt::Key_Home:
1149
1128
                        m_timeLine->pos().setTicks( 0 );
1150
1129
                        m_timeLine->updatePosition();
 
1130
                        _ke->accept();
1151
1131
                        break;
1152
1132
 
1153
1133
                case Qt::Key_0:
1167
1147
                        if( _ke->modifiers() & 
1168
1148
                                ( Qt::ControlModifier | Qt::KeypadModifier ) )
1169
1149
                        {
1170
 
                                        m_noteLenModel.setValue( len );
 
1150
                                m_noteLenModel.setValue( len );
 
1151
                                _ke->accept();
1171
1152
                        }
1172
1153
                        else if( _ke->modifiers() & Qt::AltModifier )
1173
1154
                        {
1174
 
                                        m_quantizeModel.setValue( len );
 
1155
                                m_quantizeModel.setValue( len );
 
1156
                                _ke->accept();
1175
1157
                        }
1176
1158
                        break;
1177
1159
                }
1178
1160
 
1179
1161
                case Qt::Key_Control:
1180
 
                        if( m_editMode != ModeSelect )
1181
 
                        {
1182
 
                                m_ctrlMode = m_editMode;
1183
 
                                m_editMode = ModeSelect;
1184
 
                                QApplication::changeOverrideCursor(
1185
 
                                                                                                   QCursor( Qt::ArrowCursor ) );
1186
 
                                update();
1187
 
                        }
 
1162
                        m_ctrlMode = m_editMode;
 
1163
                        m_editMode = ModeSelect;
 
1164
                        QApplication::changeOverrideCursor( Qt::ArrowCursor );
 
1165
                        update();
 
1166
                        _ke->accept();
1188
1167
                        break;
1189
1168
                default:
1190
 
                        _ke->ignore();
1191
1169
                        break;
1192
1170
        }
1193
1171
}
1204
1182
 
1205
1183
                if( _ke->isAutoRepeat() == false && key_num > -1 )
1206
1184
                {
1207
 
                        m_pattern->instrumentTrack()->
1208
 
                                getPiano()->handleKeyRelease( key_num );
 
1185
                        m_pattern->instrumentTrack()->pianoModel()->
 
1186
                                                                                                        handleKeyRelease( key_num );
 
1187
                        _ke->accept();
1209
1188
                }
1210
1189
        }
1211
1190
        switch( _ke->key() )
1217
1196
                        update();
1218
1197
                        break;
1219
1198
        }
1220
 
        _ke->ignore();
1221
1199
}
1222
1200
 
1223
1201
 
1347
1325
                        const NoteVector & notes = m_pattern->notes();
1348
1326
 
1349
1327
                        // will be our iterator in the following loop
1350
 
                        NoteVector::ConstIterator it = notes.begin();
 
1328
                        NoteVector::ConstIterator it = notes.begin()+notes.size()-1;
1351
1329
 
1352
1330
                        // loop through whole note-vector...
1353
 
                        while( it != notes.end() )
 
1331
                        for( int i = 0; i < notes.size(); ++i )
1354
1332
                        {
1355
1333
                                midiTime len = ( *it )->length();
1356
1334
                                if( len < 0 )
1376
1354
                                {
1377
1355
                                        break;
1378
1356
                                }
1379
 
                                ++it;
 
1357
                                --it;
1380
1358
                        }
1381
1359
 
1382
1360
                        // first check whether the user clicked in note-edit-
1394
1372
                                note * created_new_note = NULL;
1395
1373
                                // did it reach end of vector because
1396
1374
                                // there's no note??
1397
 
                                if( it == notes.end() )
 
1375
                                if( it == notes.begin()-1 )
1398
1376
                                {
1399
 
                                        m_pattern->setType(
1400
 
                                                pattern::MelodyPattern );
 
1377
                                        m_pattern->setType( pattern::MelodyPattern );
1401
1378
 
1402
1379
                                        // then set new note
1403
1380
                                        
1553
1530
                                        // play the note
1554
1531
                                        testPlayNote( m_currentNote );
1555
1532
                                }
1556
 
                                
1557
 
                                
1558
 
                                
1559
 
                                
 
1533
 
1560
1534
                                engine::getSong()->setModified();
1561
1535
                        }
1562
1536
                        else if( ( _me->buttons() == Qt::RightButton &&
1565
1539
                        {
1566
1540
                                // erase single note
1567
1541
                                m_mouseDownRight = true;
1568
 
                                if( it != notes.end() )
 
1542
                                if( it != notes.begin()-1 )
1569
1543
                                {
1570
1544
                                        if( ( *it )->length() > 0 )
1571
1545
                                        {
2013
1987
                        
2014
1988
                        // loop through vector
2015
1989
                        bool use_selection = isSelection();
2016
 
                        NoteVector::ConstIterator it = notes.begin();
2017
 
                        while( it != notes.end() )
 
1990
                        NoteVector::ConstIterator it = notes.begin()+notes.size()-1;
 
1991
                        for( int i = 0; i < notes.size(); ++i )
2018
1992
                        {
2019
 
                                if( ( *it )->pos().getTicks() >= ticks_start 
2020
 
                                        && ( *it )->pos().getTicks() <= ticks_end
2021
 
                                        && ( *it )->length().getTicks() > 0
2022
 
                                        && ( ( *it )->selected() || ! use_selection ) )
 
1993
                                note * n = *it;
 
1994
                                if( n->pos().getTicks() >= ticks_start 
 
1995
                                        && n->pos().getTicks() <= ticks_end
 
1996
                                        && n->length().getTicks() != 0
 
1997
                                        && ( n->selected() || ! use_selection ) )
2023
1998
                                {
2024
1999
                                        m_pattern->dataChanged();
2025
2000
                                        
2026
2001
                                        // play the note so that the user can tell how loud it is
2027
2002
                                        // and where it is panned
2028
 
                                        testPlayNote( *it );
 
2003
                                        testPlayNote( n );
2029
2004
                                        
2030
2005
                                        if( m_noteEditMode == NoteEditVolume )
2031
2006
                                        {
2032
 
                                                ( *it )->setVolume( vol );
 
2007
                                                n->setVolume( vol );
2033
2008
                                                m_pattern->instrumentTrack()->processInEvent(
2034
2009
                                                        midiEvent( 
2035
2010
                                                          MidiKeyPressure, 
2036
2011
                                                          0, 
2037
 
                                                          ( *it )->key(), 
 
2012
                                                          n->key(), 
2038
2013
                                                          vol * 127 / 100),
2039
2014
                                                                        midiTime() );
2040
2015
                                        }
2041
2016
                                        else if( m_noteEditMode == NoteEditPanning )
2042
2017
                                        {
2043
 
                                                ( *it )->setPanning( pan );
 
2018
                                                n->setPanning( pan );
2044
2019
                                                midiEvent evt( MidiMetaEvent, 0, 
2045
 
                                                                          ( *it )->key(), panningToMidi( pan ) );
 
2020
                                                                                  n->key(), panningToMidi( pan ) );
2046
2021
                                                evt.m_metaEvent = MidiNotePanning;
2047
2022
                                                m_pattern->instrumentTrack()->processInEvent(
2048
2023
                                                                        evt, midiTime() );
2050
2025
                                }
2051
2026
                                else
2052
2027
                                {
2053
 
                                        if( ( *it )->isPlaying() )
 
2028
                                        if( n->isPlaying() )
2054
2029
                                        {
2055
2030
                                                // mouse not over this note, stop playing it.
2056
2031
                                                m_pattern->instrumentTrack()->processInEvent(
2057
2032
                                                        midiEvent( MidiNoteOff, 0,
2058
 
                                                        ( *it )->key(), 0 ), midiTime() );
 
2033
                                                                                n->key(), 0 ), midiTime() );
2059
2034
                                                
2060
 
                                                ( *it )->setIsPlaying( false );
 
2035
                                                n->setIsPlaying( false );
2061
2036
                                        }
2062
2037
                                }
2063
2038
                                
2064
 
                                ++it;
 
2039
                                --it;
2065
2040
 
2066
2041
                        }
2067
2042
                }
2077
2052
                        const NoteVector & notes = m_pattern->notes();
2078
2053
 
2079
2054
                        // will be our iterator in the following loop
2080
 
                        NoteVector::ConstIterator it = notes.begin();
 
2055
                        NoteVector::ConstIterator it = notes.begin()+notes.size()-1;
2081
2056
 
2082
2057
                        // loop through whole note-vector...
2083
 
                        while( it != notes.end() )
 
2058
                        for( int i = 0; i < notes.size(); ++i )
2084
2059
                        {
2085
2060
                                // and check whether the cursor is over an
2086
2061
                                // existing note
2092
2067
                                {
2093
2068
                                        break;
2094
2069
                                }
2095
 
                                ++it;
 
2070
                                --it;
2096
2071
                        }
2097
2072
 
2098
2073
                        // did it reach end of vector because there's
2099
2074
                        // no note??
2100
 
                        if( it != notes.end() )
 
2075
                        if( it != notes.begin()-1 )
2101
2076
                        {
2102
2077
                                // cursor at the "tail" of the note?
2103
2078
                                if( ( *it )->length() > 0 &&
3591
3566
                        midiTime::ticksPerTact() / m_ppt + m_currentPosition;
3592
3567
 
3593
3568
        // will be our iterator in the following loop
3594
 
        NoteVector::ConstIterator it = notes.begin();
 
3569
        NoteVector::ConstIterator it = notes.begin()+notes.size()-1;
3595
3570
 
3596
3571
        // loop through whole note-vector...
3597
 
        while( it != notes.end() )
 
3572
        int i;
 
3573
        for( i = 0; i < notes.size(); ++i )
3598
3574
        {
3599
3575
                // and check whether the cursor is over an
3600
3576
                // existing note
3604
3580
                {
3605
3581
                        break;
3606
3582
                }
3607
 
                ++it;
 
3583
                --it;
 
3584
        }
 
3585
 
 
3586
        if( i == notes.size() )
 
3587
        {
 
3588
                return NULL;
3608
3589
        }
3609
3590
 
3610
3591
        return *it;