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:
@@ -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 );
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 );
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user