diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 8d328c88351..6d9c1c712a5 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -12,15 +12,19 @@ QMdiArea { } AutomationEditor { - background-color: #040506; color: #ffffff; + background-color: #141616; + qproperty-backgroundShade: rgba(255, 255, 255, 15); qproperty-vertexColor: #6749C2; - qproperty-gridColor: #190F38; - qproperty-crossColor: #9875FF; + qproperty-crossColor: rgba(215, 210, 254, 150); + /* Grid colors */ + qproperty-lineColor: #292929; + qproperty-beatLineColor: #4a3bba; + qproperty-barLineColor: #8173fe; qproperty-graphColor: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, - stop:0 rgba(69,42,153,255), stop:1 rgba(81,48,179,50)); - qproperty-scaleColor: #262b30; + stop:0 rgba(69,42,153,180), stop:1 rgba(69,42,153,100)); + qproperty-scaleColor: #262b30; } /* text box */ @@ -113,8 +117,8 @@ QMenu::indicator:selected { } PianoRoll { - background-color: #040506; - qproperty-gridColor: #2d3339; + background-color: #141616; + qproperty-backgroundShade: rgba(255, 255, 255, 10); qproperty-noteModeColor: #0bd556; qproperty-noteColor: #0bd556; qproperty-noteOpacity: 165; @@ -122,6 +126,11 @@ PianoRoll { qproperty-selectedNoteColor: #006b65; qproperty-barColor: #078f3a; qproperty-markedSemitoneColor: #06170E; + /* Grid colors */ + qproperty-lineColor: #292929; + qproperty-beatLineColor: #2d6b45; + qproperty-barLineColor: #42a065; + /* Text on the white piano keys */ qproperty-textColor: #000; qproperty-textColorLight: #0bd556; @@ -145,37 +154,37 @@ CPULoadWidget { /* scrollbar: trough */ QScrollBar:horizontal { - border-top: 3px solid #262b30; - background: #262b30; - height: 12px; - margin: 0px 12px; + border-top: 3px solid #262b30; + background: #262b30; + height: 12px; + margin: 0px 12px; } QScrollBar:vertical { - border-left: 3px solid #262b30; - background: #262b30; - width: 12px; - margin: 12px 0px; + border-left: 3px solid #262b30; + background: #262b30; + width: 12px; + margin: 12px 0px; } /* scrollbar: trough clicky things */ QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - background: none; + background: none; } QScrollBar::add-page:horizontal:pressed, QScrollBar::sub-page:horizontal:pressed, QScrollBar::add-page:vertical:pressed, QScrollBar::sub-page:vertical:pressed { - background: rgba(0,0,0,50); + background: rgba(0,0,0,50); } /* scrollbar: handles (sliders) */ QScrollBar::handle:horizontal { - background: #3f4750; - border: none; - border-radius: 4px; - min-width: 24px; + background: #3f4750; + border: none; + border-radius: 4px; + min-width: 24px; } QScrollBar::handle:horizontal:hover { @@ -187,10 +196,10 @@ QScrollBar::handle:horizontal:pressed { } QScrollBar::handle:vertical { - background: #3f4750; - border: none; - border-radius: 4px; - min-height: 24px; + background: #3f4750; + border: none; + border-radius: 4px; + min-height: 24px; } QScrollBar::handle:vertical:hover { @@ -210,10 +219,10 @@ QScrollBar::handle:horizontal:disabled, QScrollBar::handle:vertical:disabled { /* arrow buttons */ QScrollBar::add-line, QScrollBar::sub-line { - background: #262b30; - border-radius: 0px; - border: none; - subcontrol-origin: margin; + background: #262b30; + border-radius: 0px; + border: none; + subcontrol-origin: margin; } QScrollBar::add-line:horizontal { subcontrol-position: right; width: 12px;} @@ -237,10 +246,10 @@ QScrollBar::add-line:disabled, QScrollBar::sub-line:disabled { QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal, QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { - border: none; - background-color: none; - width: 5px; - height: 5px; + border: none; + background-color: none; + width: 5px; + height: 5px; } QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal { @@ -262,12 +271,12 @@ QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarr /* background for song editor and bb-editor */ -TrackContainerView QFrame{ +TrackContainerView QFrame { background-color: #262b30; } /* background for track controls */ -TrackView > QWidget{ +TrackView > QWidget { background-color: #3B424A; } @@ -415,7 +424,7 @@ QToolButton:pressed { background: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 #636c7a, stop:1 #262b30); } -QToolButton:checked { +QToolButton:checked { border-top: 1px solid #1b1f22; border-bottom: 1px solid #4a515e; background: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 #1b1f22, stop:1 #13161a); diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index eddafe53b2d..b926b2613bd 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -52,11 +52,14 @@ class TimeLineWidget; class AutomationEditor : public QWidget, public JournallingObject { Q_OBJECT - Q_PROPERTY(QColor gridColor READ gridColor WRITE setGridColor) + Q_PROPERTY(QColor barLineColor READ barLineColor WRITE setBarLineColor) + Q_PROPERTY(QColor beatLineColor READ beatLineColor WRITE setBeatLineColor) + Q_PROPERTY(QColor lineColor READ lineColor WRITE setLineColor) Q_PROPERTY(QColor vertexColor READ vertexColor WRITE setVertexColor) Q_PROPERTY(QBrush scaleColor READ scaleColor WRITE setScaleColor) Q_PROPERTY(QBrush graphColor READ graphColor WRITE setGraphColor) Q_PROPERTY(QColor crossColor READ crossColor WRITE setCrossColor) + Q_PROPERTY(QColor backgroundShade READ backgroundShade WRITE setBackgroundShade) public: void setCurrentPattern(AutomationPattern * new_pattern); @@ -78,16 +81,22 @@ class AutomationEditor : public QWidget, public JournallingObject } // qproperty access methods - QColor gridColor() const; + QColor barLineColor() const; + void setBarLineColor(const QColor & c); + QColor beatLineColor() const; + void setBeatLineColor(const QColor & c); + QColor lineColor() const; + void setLineColor(const QColor & c); QBrush graphColor() const; + void setGraphColor(const QBrush & c); QColor vertexColor() const; + void setVertexColor(const QColor & c); QBrush scaleColor() const; + void setScaleColor(const QBrush & c); QColor crossColor() const; - void setGridColor(const QColor& c); - void setGraphColor(const QBrush& c); - void setVertexColor(const QColor& c); - void setScaleColor(const QBrush& c); - void setCrossColor(const QColor& c); + void setCrossColor(const QColor & c); + QColor backgroundShade() const; + void setBackgroundShade(const QColor & c); enum EditModes { @@ -239,11 +248,14 @@ protected slots: void drawAutomationPoint( QPainter & p, timeMap::iterator it ); bool inBBEditor(); - QColor m_gridColor; + QColor m_barLineColor; + QColor m_beatLineColor; + QColor m_lineColor; QBrush m_graphColor; QColor m_vertexColor; QBrush m_scaleColor; QColor m_crossColor; + QColor m_backgroundShade; friend class AutomationEditorWindow; diff --git a/include/PianoRoll.h b/include/PianoRoll.h index f58345f6365..43400cbf3d3 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -54,7 +54,9 @@ class TimeLineWidget; class PianoRoll : public QWidget { Q_OBJECT - Q_PROPERTY( QColor gridColor READ gridColor WRITE setGridColor ) + Q_PROPERTY( QColor barLineColor READ barLineColor WRITE setBarLineColor ) + Q_PROPERTY( QColor beatLineColor READ beatLineColor WRITE setBeatLineColor ) + Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor ) Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor ) Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor ) Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor ) @@ -65,6 +67,7 @@ class PianoRoll : public QWidget Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor ) Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity ) Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders ) + Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade ) public: enum EditModes { @@ -107,10 +110,14 @@ class PianoRoll : public QWidget Song::PlayModes desiredPlayModeForAccompany() const; int quantization() const; - - // qproperty acces functions - QColor gridColor() const; - void setGridColor( const QColor & c ); + + // qproperty access functions + QColor barLineColor() const; + void setBarLineColor( const QColor & c ); + QColor beatLineColor() const; + void setBeatLineColor( const QColor & c ); + QColor lineColor() const; + void setLineColor( const QColor & c ); QColor noteModeColor() const; void setNoteModeColor( const QColor & c ); QColor noteColor() const; @@ -131,6 +138,8 @@ class PianoRoll : public QWidget void setNoteOpacity( const int i ); bool noteBorders() const; void setNoteBorders( const bool b ); + QColor backgroundShade() const; + void setBackgroundShade( const QColor & c ); protected: @@ -154,6 +163,7 @@ class PianoRoll : public QWidget void selectAll(); NoteVector getSelectedNotes(); void selectNotesOnKey(); + int xCoordOfTick( int tick ); // for entering values with dblclick in the vol/pan bars void enterValue( NoteVector* nv ); @@ -370,7 +380,9 @@ protected slots: friend class PianoRollWindow; // qproperty fields - QColor m_gridColor; + QColor m_barLineColor; + QColor m_beatLineColor; + QColor m_lineColor; QColor m_noteModeColor; QColor m_noteColor; QColor m_barColor; @@ -381,6 +393,7 @@ protected slots: QColor m_markedSemitoneColor; int m_noteOpacity; bool m_noteBorders; + QColor m_backgroundShade; signals: void positionChanged( const MidiTime & ); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index b56b6d0b80a..09bdf012c2c 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -104,11 +104,14 @@ AutomationEditor::AutomationEditor() : m_y_auto( true ), m_editMode( DRAW ), m_scrollBack( false ), - m_gridColor( 0,0,0 ), + m_barLineColor( 0, 0, 0 ), + m_beatLineColor( 0, 0, 0 ), + m_lineColor( 0, 0, 0 ), m_graphColor( Qt::SolidPattern ), m_vertexColor( 0,0,0 ), m_scaleColor( Qt::SolidPattern ), - m_crossColor( 0, 0, 0 ) + m_crossColor( 0, 0, 0 ), + m_backgroundShade( 0, 0, 0 ) { connect( this, SIGNAL( currentPatternChanged() ), this, SLOT( updateAfterPatternChange() ), @@ -249,27 +252,55 @@ void AutomationEditor::loadSettings( const QDomElement & dom_parent) // qproperty access methods -QColor AutomationEditor::gridColor() const -{ return m_gridColor; } +QColor AutomationEditor::barLineColor() const +{ return m_barLineColor; } + +void AutomationEditor::setBarLineColor( const QColor & c ) +{ m_barLineColor = c; } + +QColor AutomationEditor::beatLineColor() const +{ return m_beatLineColor; } + +void AutomationEditor::setBeatLineColor( const QColor & c ) +{ m_beatLineColor = c; } + +QColor AutomationEditor::lineColor() const +{ return m_lineColor; } + +void AutomationEditor::setLineColor( const QColor & c ) +{ m_lineColor = c; } + QBrush AutomationEditor::graphColor() const { return m_graphColor; } -QColor AutomationEditor::vertexColor() const -{ return m_vertexColor; } -QBrush AutomationEditor::scaleColor() const -{ return m_scaleColor; } -QColor AutomationEditor::crossColor() const -{ return m_crossColor; } -void AutomationEditor::setGridColor( const QColor & c ) -{ m_gridColor = c; } + void AutomationEditor::setGraphColor( const QBrush & c ) { m_graphColor = c; } + +QColor AutomationEditor::vertexColor() const +{ return m_vertexColor; } + void AutomationEditor::setVertexColor( const QColor & c ) { m_vertexColor = c; } + +QBrush AutomationEditor::scaleColor() const +{ return m_scaleColor; } + void AutomationEditor::setScaleColor( const QBrush & c ) { m_scaleColor = c; } + +QColor AutomationEditor::crossColor() const +{ return m_crossColor; } + void AutomationEditor::setCrossColor( const QColor & c ) { m_crossColor = c; } +QColor AutomationEditor::backgroundShade() const +{ return m_backgroundShade; } + +void AutomationEditor::setBackgroundShade( const QColor & c ) +{ m_backgroundShade = c; } + + void AutomationEditor::updateAfterPatternChange() @@ -1098,57 +1129,46 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) grid_height ); // draw vertical raster - QColor lineColor = QColor( gridColor() ); + if( m_pattern ) { - int tick, x; + int tick, x, q; int x_line_end = (int)( m_y_auto || m_topLevel < m_maxLevel ? TOP_MARGIN : - grid_bottom - ( m_topLevel - m_bottomLevel ) - * m_y_delta ); - // 3 independent loops, because quantization might not divide evenly into - // exotic denominators (e.g. 7/11 time), which are allowed ATM. - // First quantization grid... - for( tick = m_currentPosition - m_currentPosition % AutomationPattern::quantization(), - x = xCoordOfTick( tick ); - x<=width(); - tick += AutomationPattern::quantization(), x = xCoordOfTick( tick ) ) + grid_bottom - ( m_topLevel - m_bottomLevel ) * m_y_delta ); + + if( m_zoomingXModel.value() > 3 ) { - lineColor.setAlpha( 80 ); - p.setPen( lineColor ); - p.drawLine( x, grid_bottom, x, x_line_end ); + // If we're over 100% zoom, we allow all quantization level grids + q = AutomationPattern::quantization(); } - // Then beat grid - int ticksPerBeat = DefaultTicksPerTact / - Engine::getSong()->getTimeSigModel().getDenominator(); - for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, - x = xCoordOfTick( tick ); - x<=width(); - tick += ticksPerBeat, x = xCoordOfTick( tick ) ) + else if( AutomationPattern::quantization() % 3 != 0 ) { - lineColor.setAlpha( 160 ); - p.setPen( lineColor ); - p.drawLine( x, grid_bottom, x, x_line_end ); + // If we're under 100% zoom, we allow quantization grid up to 1/24 for triplets + // to ensure a dense doesn't fill out the background + q = AutomationPattern::quantization() < 8 ? 8 : AutomationPattern::quantization(); } - // and finally bars - for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerTact(), + else { + // If we're under 100% zoom, we allow quantization grid up to 1/32 for normal notes + q = AutomationPattern::quantization() < 6 ? 6 : AutomationPattern::quantization(); + } + + // 3 independent loops, because quantization might not divide evenly into + // exotic denominators (e.g. 7/11 time), which are allowed ATM. + // First quantization grid... + for( tick = m_currentPosition - m_currentPosition % q, x = xCoordOfTick( tick ); x<=width(); - tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) + tick += q, x = xCoordOfTick( tick ) ) { - lineColor.setAlpha( 255 ); - p.setPen( lineColor ); + p.setPen( lineColor() ); p.drawLine( x, grid_bottom, x, x_line_end ); } /// \todo move this horizontal line drawing code into the same loop as the value ticks? if( m_y_auto ) { - lineColor.setAlpha( 160 ); - QPen pen( lineColor ); - p.setPen( pen ); - p.drawLine( VALUES_WIDTH, grid_bottom, width(), - grid_bottom ); + QPen pen( beatLineColor() ); pen.setStyle( Qt::DotLine ); p.setPen( pen ); float y_delta = ( grid_bottom - TOP_MARGIN ) / 8.0f; @@ -1164,22 +1184,62 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) for( int level = (int)m_bottomLevel; level <= m_topLevel; level++) { y = yCoordOfLevel( (float)level ); - if( level % 5 == 0 ) + if( level % 10 == 0 ) { - lineColor.setAlpha( 160 ); - p.setPen( lineColor ); + p.setPen( beatLineColor() ); } else { - lineColor.setAlpha( 80 ); - p.setPen( lineColor ); + p.setPen( lineColor() ); } - // draw level line - p.drawLine( VALUES_WIDTH, (int) y, width(), - (int) y ); + p.drawLine( VALUES_WIDTH, (int) y, width(), (int) y ); } } + + // alternating shades for better contrast + // count the bars which disappear on left by scrolling + int barCount = m_currentPosition / MidiTime::ticksPerTact(); + int leftBars = m_currentPosition / m_ppt; + + for( int x = VALUES_WIDTH; x < width() + m_currentPosition; x += m_ppt, ++barCount ) + { + if( ( barCount + leftBars ) % 2 != 0 ) + { + p.fillRect( x - m_currentPosition, TOP_MARGIN, m_ppt, + height() - ( SCROLLBAR_SIZE + TOP_MARGIN ), backgroundShade() ); + } + } + + // Draw the beat grid + int ticksPerBeat = DefaultTicksPerTact / + Engine::getSong()->getTimeSigModel().getDenominator(); + + // triplet mode occurs if the note quantization isn't a multiple of 3 + // note that the automation editor does not support triplets yet + if( AutomationPattern::quantization() % 3 != 0 ) + { + ticksPerBeat = static_cast( ticksPerBeat * 2.0/3.0 ); + } + + for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, + x = xCoordOfTick( tick ); + x<=width(); + tick += ticksPerBeat, x = xCoordOfTick( tick ) ) + { + p.setPen( beatLineColor() ); + p.drawLine( x, grid_bottom, x, x_line_end ); + } + + // and finally bars + for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerTact(), + x = xCoordOfTick( tick ); + x<=width(); + tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) + { + p.setPen( barLineColor() ); + p.drawLine( x, grid_bottom, x, x_line_end ); + } } @@ -1246,11 +1306,11 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) { is_selected = true; } - + float *values = m_pattern->valuesAfter( it.key() ); for( int i = 0; i < (it+1).key() - it.key(); i++ ) { - + drawLevelTick( p, it.key() + i, values[i], is_selected ); } @@ -1346,7 +1406,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int AutomationEditor::xCoordOfTick(int tick ) { return VALUES_WIDTH + ( ( tick - m_currentPosition ) - * m_ppt / MidiTime::ticksPerTact() ); + * m_ppt / MidiTime::ticksPerTact() ); } diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 52cdd585e5c..6c757c4390c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -190,7 +190,9 @@ PianoRoll::PianoRoll() : m_mouseDownLeft( false ), m_mouseDownRight( false ), m_scrollBack( false ), - m_gridColor( 0, 0, 0 ), + m_barLineColor( 0, 0, 0 ), + m_beatLineColor( 0, 0, 0 ), + m_lineColor( 0, 0, 0 ), m_noteModeColor( 0, 0, 0 ), m_noteColor( 0, 0, 0 ), m_barColor( 0, 0, 0 ), @@ -200,7 +202,8 @@ PianoRoll::PianoRoll() : m_textShadow( 0, 0, 0 ), m_markedSemitoneColor( 0, 0, 0 ), m_noteOpacity( 255 ), - m_noteBorders( true ) + m_noteBorders( true ), + m_backgroundShade( 0, 0, 0 ) { // gui names of edit modes m_nemStr.push_back( tr( "Note Velocity" ) ); @@ -726,11 +729,23 @@ void PianoRoll::selectRegionFromPixels( int xStart, int xEnd ) /** \brief qproperty access implementation */ -QColor PianoRoll::gridColor() const -{ return m_gridColor; } +QColor PianoRoll::barLineColor() const +{ return m_barLineColor; } -void PianoRoll::setGridColor( const QColor & c ) -{ m_gridColor = c; } +void PianoRoll::setBarLineColor( const QColor & c ) +{ m_barLineColor = c; } + +QColor PianoRoll::beatLineColor() const +{ return m_beatLineColor; } + +void PianoRoll::setBeatLineColor( const QColor & c ) +{ m_beatLineColor = c; } + +QColor PianoRoll::lineColor() const +{ return m_lineColor; } + +void PianoRoll::setLineColor( const QColor & c ) +{ m_lineColor = c; } QColor PianoRoll::noteModeColor() const { return m_noteModeColor; } @@ -792,6 +807,12 @@ bool PianoRoll::noteBorders() const void PianoRoll::setNoteBorders( const bool b ) { m_noteBorders = b; } +QColor PianoRoll::backgroundShade() const +{ return m_backgroundShade; } + +void PianoRoll::setBackgroundShade( const QColor & c ) +{ m_backgroundShade = c; } + @@ -2568,13 +2589,16 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl ) Engine::getSong()->setModified(); } +int PianoRoll::xCoordOfTick(int tick ) +{ + return WHITE_KEY_WIDTH + ( ( tick - m_currentPosition ) + * m_ppt / MidiTime::ticksPerTact() ); +} + void PianoRoll::paintEvent(QPaintEvent * pe ) { bool drawNoteNames = ConfigManager::inst()->value( "ui", "printnotelabels").toInt(); - QColor horizCol = QColor( gridColor() ); - QColor vertCol = QColor( gridColor() ); - QStyleOption opt; opt.initFrom( this ); QPainter p( this ); @@ -2690,25 +2714,11 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) y -= WHITE_KEY_BIG_HEIGHT; } - // Draw the C line in a more prominent color - if( static_cast( key % KeysPerOctave ) == Key_C ) - { - horizCol.setAlpha( 192 ); - } - else - { - horizCol.setAlpha( 64 ); - } - - // draw key-line - p.setPen( horizCol ); - p.drawLine( WHITE_KEY_WIDTH, key_line_y, width(), key_line_y ); - // Compute the corrections for the note names int yCorrectionForNoteLabels = 0; int keyCode = key % KeysPerOctave; - switch (keyCode) + switch( keyCode ) { case 0: case 5: @@ -2725,7 +2735,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) break; } - if ( Piano::isWhiteKey( key ) ) + if( Piano::isWhiteKey( key ) ) { // Draw note names if activated in the preferences, C notes are always drawn if ( key % 12 == 0 || drawNoteNames ) @@ -2843,68 +2853,96 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) width() - WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN ); - // draw vertical raster - - // triplet mode occurs if the note duration isn't a multiple of 3 - bool triplets = ( quantization() % 3 != 0 ); - - int spt = MidiTime::stepsPerTact(); - float pp16th = (float)m_ppt / spt; - int bpt = DefaultBeatsPerTact; - if ( triplets ) { - spt = static_cast(1.5 * spt); - bpt = static_cast(bpt * 2.0/3.0); - pp16th *= 2.0/3.0; - } - - int tact_16th = m_currentPosition / bpt; + // draw the grid + if( hasValidPattern() ) + { + int q, x, tick; - const int offset = ( m_currentPosition % bpt ) * - m_ppt / MidiTime::ticksPerTact(); + if( m_zoomingModel.value() > 3 ) + { + // If we're over 100% zoom, we allow all quantization level grids + q = quantization(); + } + else if( quantization() % 3 != 0 ) + { + // If we're under 100% zoom, we allow quantization grid up to 1/24 for triplets + // to ensure a dense doesn't fill out the background + q = quantization() < 8 ? 8 : quantization(); + } + else { + // If we're under 100% zoom, we allow quantization grid up to 1/32 for normal notes + q = quantization() < 6 ? 6 : quantization(); + } - bool show32nds = ( m_zoomingModel.value() > 3 ); + // First we draw the vertical quantization lines + for( tick = m_currentPosition - m_currentPosition % q, x = xCoordOfTick( tick ); + x <= width(); tick += q, x = xCoordOfTick( tick ) ) + { + p.setPen( lineColor() ); + p.drawLine( x, PR_TOP_MARGIN, x, height() - PR_BOTTOM_MARGIN ); + } - // we need float here as odd time signatures might produce rounding - // errors else and thus an unusable grid - for( float x = WHITE_KEY_WIDTH - offset; x < width(); - x += pp16th, ++tact_16th ) - { - if( x >= WHITE_KEY_WIDTH ) + // Draw horizontal lines + key = m_startKey; + for( int y = keyAreaBottom() - 1; y > PR_TOP_MARGIN; + y -= KEY_LINE_HEIGHT ) { - // every tact-start needs to be a bright line - if( tact_16th % spt == 0 ) - { - p.setPen( gridColor() ); - } - // normal line - else if( tact_16th % 4 == 0 ) + if( static_cast( key % KeysPerOctave ) == Key_C ) { - vertCol.setAlpha( 160 ); - p.setPen( vertCol ); + // C note gets accented + p.setPen( beatLineColor() ); } - // weak line else { - vertCol.setAlpha( 128 ); - p.setPen( vertCol ); + p.setPen( lineColor() ); } + p.drawLine( WHITE_KEY_WIDTH, y, width(), y ); + ++key; + } - p.drawLine( (int) x, PR_TOP_MARGIN, (int) x, height() - - PR_BOTTOM_MARGIN ); + // Draw alternating shades on bars + // count the bars which disappear on left by scrolling + int barCount = m_currentPosition / MidiTime::ticksPerTact(); + int leftBars = m_currentPosition / m_ppt; - // extra 32nd's line - if( show32nds ) + for( int x = WHITE_KEY_WIDTH; x < width() + m_currentPosition; x += m_ppt, ++barCount ) + { + if( ( barCount + leftBars ) % 2 != 0 ) { - vertCol.setAlpha( 80 ); - p.setPen( vertCol ); - p.drawLine( (int)(x + pp16th / 2) , PR_TOP_MARGIN, - (int)(x + pp16th / 2), height() - - PR_BOTTOM_MARGIN ); + p.fillRect( x - m_currentPosition, PR_TOP_MARGIN, m_ppt, + height() - ( PR_BOTTOM_MARGIN + PR_TOP_MARGIN ), backgroundShade() ); } } - } + // Draw the vertical beat lines + int ticksPerBeat = DefaultTicksPerTact / + Engine::getSong()->getTimeSigModel().getDenominator(); + + // triplet mode occurs if the note quantization isn't a multiple of 3 + if( quantization() % 3 != 0 ) + { + ticksPerBeat = static_cast( ticksPerBeat * 2.0/3.0 ); + } + + for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, + x = xCoordOfTick( tick ); x <= width(); + tick += ticksPerBeat, x = xCoordOfTick( tick ) ) + { + p.setPen( beatLineColor() ); + p.drawLine( x, PR_TOP_MARGIN, x, height() - PR_BOTTOM_MARGIN ); + } + + // Draw the vertical bar lines + for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerTact(), + x = xCoordOfTick( tick ); x <= width(); + tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) + { + p.setPen( barLineColor() ); + p.drawLine( x, PR_TOP_MARGIN, x, height() - PR_BOTTOM_MARGIN ); + } + } + // following code draws all notes in visible area // and the note editing stuff (volume, panning, etc) @@ -3065,21 +3103,25 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) m_leftRightScroll->setPageStep( l ); } - // set alpha for horizontal lines - horizCol.setAlpha( 64 ); + // set line colors + QColor editAreaCol = QColor( lineColor() ); + QColor currentKeyCol = QColor( beatLineColor() ); + + editAreaCol.setAlpha( 64 ); + currentKeyCol.setAlpha( 64 ); // horizontal line for the key under the cursor if( hasValidPattern() ) { int key_num = getKey( mapFromGlobal( QCursor::pos() ).y() ); p.fillRect( 10, keyAreaBottom() + 3 - KEY_LINE_HEIGHT * - ( key_num - m_startKey + 1 ), width() - 10, KEY_LINE_HEIGHT - 7, horizCol ); + ( key_num - m_startKey + 1 ), width() - 10, KEY_LINE_HEIGHT - 7, currentKeyCol ); } // bar to resize note edit area p.setClipRect( 0, 0, width(), height() ); p.fillRect( QRect( 0, keyAreaBottom(), - width()-PR_RIGHT_MARGIN, NOTE_EDIT_RESIZE_BAR ), horizCol ); + width()-PR_RIGHT_MARGIN, NOTE_EDIT_RESIZE_BAR ), editAreaCol ); const QPixmap * cursor = NULL; // draw current edit-mode-icon below the cursor