Adding a trail (gradient) behind the position bar (#5543)

* src/gui/editors/SongEditor.cpp

* Gradient can be toggled and color can be changed.

* Made playback line (and tail) transparent to mouse clicks

* Gradient disappears when paused/stopped; tail length depends on zoom

* Fixes bug where gradient appears when a pattern is played; style corrections

* Cleaned up code

* Rename m_zoomLevels to s_zoomLevels

* Finalising code

* Make positionLine class independent of parent zooming model

* Edit a bug fix to make it more efficient

* Rename m_x and finalise positionLine code

* Rename m_x and finalise positionLine changes

* Rename X to playHeadPos
This commit is contained in:
Kumar
2020-07-02 19:56:41 +05:30
committed by GitHub
parent 5d7e6720e1
commit 984fd3a935
4 changed files with 114 additions and 15 deletions

View File

@@ -118,6 +118,11 @@ QMenu::indicator:selected {
background-color: #747474;
}
positionLine {
qproperty-tailGradient: false;
qproperty-lineColor: rgb(255, 255, 255);
}
PianoRoll {
background-color: rgb(0, 0, 0);
qproperty-backgroundShade: rgba( 255, 255, 255, 10 );

View File

@@ -150,6 +150,11 @@ QMenu::indicator:selected {
background-color: #101213;
}
positionLine {
qproperty-tailGradient: true;
qproperty-lineColor: rgb(255, 255, 255);
}
PianoRoll {
background-color: #141616;
qproperty-backgroundShade: rgba(255, 255, 255, 10);

View File

@@ -28,6 +28,7 @@
#define SONG_EDITOR_H
#include <QVector>
#include <QLinearGradient>
#include "ActionGroup.h"
#include "Editor.h"
@@ -47,13 +48,28 @@ class TimeLineWidget;
class positionLine : public QWidget
{
Q_OBJECT
Q_PROPERTY ( bool tailGradient READ hasTailGradient WRITE setHasTailGradient )
Q_PROPERTY ( QColor lineColor READ lineColor WRITE setLineColor )
public:
positionLine( QWidget * parent );
positionLine ( QWidget* parent );
// qproperty access functions
bool hasTailGradient () const;
void setHasTailGradient ( const bool g );
QColor lineColor () const;
void setLineColor ( const QColor & c );
public slots:
void zoomChange (double zoom);
private:
void paintEvent( QPaintEvent * pe ) override;
void paintEvent( QPaintEvent* pe ) override;
bool m_hasTailGradient;
QColor m_lineColor;
} ;
};
class SongEditor : public TrackContainerView
@@ -164,6 +180,9 @@ private:
bool m_selectRegion;
friend class SongEditorWindow;
signals:
void zoomingValueChanged( double );
} ;

View File

@@ -52,26 +52,89 @@
#include "PianoRoll.h"
#include "Track.h"
positionLine::positionLine( QWidget * parent ) :
QWidget( parent )
positionLine::positionLine( QWidget* parent ) :
QWidget( parent ),
m_hasTailGradient ( false ),
m_lineColor (0, 0, 0, 0)
{
setFixedWidth( 1 );
resize( 8, height() );
setAttribute( Qt::WA_NoSystemBackground, true );
setAttribute( Qt::WA_TransparentForMouseEvents );
}
void positionLine::paintEvent( QPaintEvent * pe )
void positionLine::paintEvent( QPaintEvent* pe )
{
QPainter p( this );
p.fillRect( rect(), QColor( 255, 255, 255, 153 ) );
// If width is 1, we don't need a gradient
if (width() == 1)
{
p.fillRect( rect(),
QColor( m_lineColor.red(), m_lineColor.green(), m_lineColor.blue(), 153) );
}
// If width > 1, we need the gradient
else
{
// Create the gradient trail behind the line
QLinearGradient gradient( rect().bottomLeft(), rect().bottomRight() );
// If gradient is enabled, we're in focus and we're playing, enable gradient
if (Engine::getSong()->isPlaying() && m_hasTailGradient &&
Engine::getSong()->playMode() == Song::Mode_PlaySong)
{
gradient.setColorAt(( ( width() - 1.0 )/width() ),
QColor( m_lineColor.red(), m_lineColor.green(), m_lineColor.blue(), 60) );
}
else
{
gradient.setColorAt(( ( width() - 1.0 )/width() ),
QColor( m_lineColor.red(), m_lineColor.green(), m_lineColor.blue(), 0) );
}
// Fill in the remaining parts
gradient.setColorAt(0,
QColor( m_lineColor.red(), m_lineColor.green(), m_lineColor.blue(), 0) );
gradient.setColorAt(1,
QColor( m_lineColor.red(), m_lineColor.green(), m_lineColor.blue(), 153) );
// Fill line
p.fillRect( rect(), gradient );
}
}
// QProperty handles
bool positionLine::hasTailGradient() const
{ return m_hasTailGradient; }
void positionLine::setHasTailGradient( const bool g )
{ m_hasTailGradient = g; }
QColor positionLine::lineColor() const
{ return m_lineColor; }
void positionLine::setLineColor( const QColor & c )
{ m_lineColor = c; }
// NOTE: the move() implementation fixes a bug where the position line would appear
// in an unexpected location when positioned at the start of the track
void positionLine::zoomChange( double zoom )
{
int playHeadPos = x() + width() - 1;
resize( 8.0 * zoom, height() );
move( playHeadPos - width() + 1, y() );
update();
}
const QVector<double> SongEditor::m_zoomLevels =
{ 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f, 16.0f };
SongEditor::SongEditor( Song * song ) :
TrackContainerView( song ),
m_song( song ),
@@ -111,6 +174,11 @@ SongEditor::SongEditor( Song * song ) :
m_positionLine = new positionLine( this );
static_cast<QVBoxLayout *>( layout() )->insertWidget( 1, m_timeLine );
connect( m_song, SIGNAL( playbackStateChanged() ),
m_positionLine, SLOT( update() ) );
connect( this, SIGNAL( zoomingValueChanged( double ) ),
m_positionLine, SLOT( zoomChange( double ) ) );
// add some essential widgets to global tool-bar
@@ -250,6 +318,8 @@ SongEditor::SongEditor( Song * song ) :
m_zoomingModel->findText( "100%" ) );
connect( m_zoomingModel, SIGNAL( dataChanged() ),
this, SLOT( zoomingChanged() ) );
connect( m_zoomingModel, SIGNAL( dataChanged() ),
m_positionLine, SLOT( update() ) );
//Set up snapping model, 2^i
for ( int i = 3; i >= -4; i-- )
@@ -808,7 +878,7 @@ void SongEditor::updatePosition( const MidiTime & t )
if( x >= trackOpWidth + widgetWidth -1 )
{
m_positionLine->show();
m_positionLine->move( x, m_timeLine->height() );
m_positionLine->move( x-( m_positionLine->width() - 1 ), m_timeLine->height() );
}
else
{
@@ -837,11 +907,11 @@ void SongEditor::zoomingChanged()
setPixelsPerBar( pixelsPerBar() );
realignTracks();
updateRubberband();
emit zoomingValueChanged( m_zoomLevels[m_zoomingModel->value()] );
}
void SongEditor::selectAllTcos( bool select )
{
QVector<selectableObject *> so = select ? rubberBand()->selectableObjects() : rubberBand()->selectedObjects();