diff --git a/data/themes/classic/loop_point_b.png b/data/themes/classic/loop_point_b.png deleted file mode 100644 index bcd65ad0866..00000000000 Binary files a/data/themes/classic/loop_point_b.png and /dev/null differ diff --git a/data/themes/classic/loop_point_e.png b/data/themes/classic/loop_point_e.png deleted file mode 100644 index 40fdad94a54..00000000000 Binary files a/data/themes/classic/loop_point_e.png and /dev/null differ diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index e377776da77..6dcf3b80e1b 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -533,8 +533,28 @@ Fader { qproperty-peakRed: rgb( 255, 100, 100); } -TimeLine { - font-size: 8px; +TimeLineWidget { + /* font-size only supports px and pt. */ + font-size: 7pt; + /* lengths also support em. This will make sure that the height + will always change in the same proportion as the font size + defined above. + If you want a fixed size set min and max to the same value. */ + min-height: 1.5em; + max-height: 1.5em; + + background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #8796a7, stop: 1.0 #3e454e ); + + qproperty-inactiveLoopColor: rgba( 52, 63, 53, 64 ); + qproperty-inactiveLoopBrush: rgba( 255, 255, 255, 32 ); + qproperty-inactiveLoopInnerColor: rgba( 255, 255, 255, 32 ); + qproperty-activeLoopColor: rgba( 52, 63, 53, 255 ); + qproperty-activeLoopBrush: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #378d59, stop: 1.0 #297e36 ); + qproperty-activeLoopInnerColor: rgba( 74, 155, 100, 255 ); + qproperty-barLineColor: rgb( 192, 192, 192 ); + qproperty-barNumberColor: rgb( 192, 192, 192 ); } QTreeView { diff --git a/data/themes/default/loop_point_b.png b/data/themes/default/loop_point_b.png deleted file mode 100755 index 41f7219469d..00000000000 Binary files a/data/themes/default/loop_point_b.png and /dev/null differ diff --git a/data/themes/default/loop_point_e.png b/data/themes/default/loop_point_e.png deleted file mode 100755 index 3b7b10e066d..00000000000 Binary files a/data/themes/default/loop_point_e.png and /dev/null differ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 6c0b9fca69e..cd2b26917e1 100755 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -536,8 +536,36 @@ Fader { qproperty-peakRed: #660505; } -TimeLine { - font-size: 8px; +TimeLineWidget { + /* font-size only supports px and pt. */ + font-size: 7pt; + /* lengths also support em. This will make sure that the height + will always change in the same proportion as the font size + defined above. + If you want a fixed size set min and max to the same value. */ + min-height: 1.5em; + max-height: 1.5em; + + /* Properties for the loop indicator rectangle in inactive state: + - LoopColor: Color of the outermost border + - LoopBrush: Brush to paint the main portion of the rectangle + - LoopInnerColor: Color used to paint the inlayed border */ + qproperty-inactiveLoopColor: #3B424A; + qproperty-inactiveLoopBrush: #3B424A; + qproperty-inactiveLoopInnerColor: #3B424A; + + /* Properties for the loop indicator rectangle in active state. + See above for detailed description. */ + qproperty-activeLoopColor: #21A14F; + qproperty-activeLoopBrush: #21A14F; + qproperty-activeLoopInnerColor: #21A14F; + + /* Vertical padding for the loop indicator rectangle. + A value of zero draws the rectangle at the full height of the widget. */ + qproperty-loopRectangleVerticalPadding: 1; + + qproperty-barLineColor: rgb( 192, 192, 192 ); + qproperty-barNumberColor: rgb( 192, 192, 192 ); } QTreeView { diff --git a/include/TimeLineWidget.h b/include/TimeLineWidget.h index 6487c840a63..0f8ac835025 100644 --- a/include/TimeLineWidget.h +++ b/include/TimeLineWidget.h @@ -42,6 +42,16 @@ class TimeLineWidget : public QWidget, public JournallingObject { Q_OBJECT public: + Q_PROPERTY( QColor barLineColor READ getBarLineColor WRITE setBarLineColor ) + Q_PROPERTY( QColor barNumberColor READ getBarNumberColor WRITE setBarNumberColor ) + Q_PROPERTY( QColor inactiveLoopColor READ getInactiveLoopColor WRITE setInactiveLoopColor ) + Q_PROPERTY( QBrush inactiveLoopBrush READ getInactiveLoopBrush WRITE setInactiveLoopBrush ) + Q_PROPERTY( QColor inactiveLoopInnerColor READ getInactiveLoopInnerColor WRITE setInactiveLoopInnerColor ) + Q_PROPERTY( QColor activeLoopColor READ getActiveLoopColor WRITE setActiveLoopColor ) + Q_PROPERTY( QBrush activeLoopBrush READ getActiveLoopBrush WRITE setActiveLoopBrush ) + Q_PROPERTY( QColor activeLoopInnerColor READ getActiveLoopInnerColor WRITE setActiveLoopInnerColor ) + Q_PROPERTY( int loopRectangleVerticalPadding READ getLoopRectangleVerticalPadding WRITE setLoopRectangleVerticalPadding ) + enum AutoScrollStates { AutoScrollEnabled, @@ -66,6 +76,33 @@ class TimeLineWidget : public QWidget, public JournallingObject const MidiTime & begin, QWidget * parent ); virtual ~TimeLineWidget(); + inline QColor const & getBarLineColor() const { return m_barLineColor; } + inline void setBarLineColor(QColor const & tactLineColor) { m_barLineColor = tactLineColor; } + + inline QColor const & getBarNumberColor() const { return m_barNumberColor; } + inline void setBarNumberColor(QColor const & tactNumberColor) { m_barNumberColor = tactNumberColor; } + + inline QColor const & getInactiveLoopColor() const { return m_inactiveLoopColor; } + inline void setInactiveLoopColor(QColor const & inactiveLoopColor) { m_inactiveLoopColor = inactiveLoopColor; } + + inline QBrush const & getInactiveLoopBrush() const { return m_inactiveLoopBrush; } + inline void setInactiveLoopBrush(QBrush const & inactiveLoopBrush) { m_inactiveLoopBrush = inactiveLoopBrush; } + + inline QColor const & getInactiveLoopInnerColor() const { return m_inactiveLoopInnerColor; } + inline void setInactiveLoopInnerColor(QColor const & inactiveLoopInnerColor) { m_inactiveLoopInnerColor = inactiveLoopInnerColor; } + + inline QColor const & getActiveLoopColor() const { return m_activeLoopColor; } + inline void setActiveLoopColor(QColor const & activeLoopColor) { m_activeLoopColor = activeLoopColor; } + + inline QBrush const & getActiveLoopBrush() const { return m_activeLoopBrush; } + inline void setActiveLoopBrush(QBrush const & activeLoopBrush) { m_activeLoopBrush = activeLoopBrush; } + + inline QColor const & getActiveLoopInnerColor() const { return m_activeLoopInnerColor; } + inline void setActiveLoopInnerColor(QColor const & activeLoopInnerColor) { m_activeLoopInnerColor = activeLoopInnerColor; } + + inline int const & getLoopRectangleVerticalPadding() const { return m_loopRectangleVerticalPadding; } + inline void setLoopRectangleVerticalPadding(int const & loopRectangleVerticalPadding) { m_loopRectangleVerticalPadding = loopRectangleVerticalPadding; } + inline Song::PlayPos & pos() { return( m_pos ); @@ -155,9 +192,19 @@ public slots: private: static QPixmap * s_posMarkerPixmap; - static QPixmap * s_loopPointBeginPixmap; - static QPixmap * s_loopPointEndPixmap; - static QPixmap * s_loopPointDisabledPixmap; + + QColor m_inactiveLoopColor; + QBrush m_inactiveLoopBrush; + QColor m_inactiveLoopInnerColor; + + QColor m_activeLoopColor; + QBrush m_activeLoopBrush; + QColor m_activeLoopInnerColor; + + int m_loopRectangleVerticalPadding; + + QColor m_barLineColor; + QColor m_barNumberColor; AutoScrollStates m_autoScroll; LoopPointStates m_loopPoints; diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index a367d2bcfd8..682fb56fd1b 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -48,13 +48,20 @@ QPixmap * TimeLineWidget::s_posMarkerPixmap = NULL; -QPixmap * TimeLineWidget::s_loopPointBeginPixmap = NULL; -QPixmap * TimeLineWidget::s_loopPointEndPixmap = NULL; TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, Song::PlayPos & pos, const MidiTime & begin, QWidget * parent ) : QWidget( parent ), + m_inactiveLoopColor( 52, 63, 53, 64 ), + m_inactiveLoopBrush( QColor( 255, 255, 255, 32 ) ), + m_inactiveLoopInnerColor( 255, 255, 255, 32 ), + m_activeLoopColor( 52, 63, 53, 255 ), + m_activeLoopBrush( QColor( 55, 141, 89 ) ), + m_activeLoopInnerColor( 74, 155, 100, 255 ), + m_loopRectangleVerticalPadding( 1 ), + m_barLineColor( 192, 192, 192 ), + m_barNumberColor( m_barLineColor.darker( 120 ) ), m_autoScroll( AutoScrollEnabled ), m_loopPoints( LoopPointsDisabled ), m_behaviourAtStop( BackToZero ), @@ -77,20 +84,9 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, s_posMarkerPixmap = new QPixmap( embed::getIconPixmap( "playpos_marker" ) ); } - if( s_loopPointBeginPixmap == NULL ) - { - s_loopPointBeginPixmap = new QPixmap( embed::getIconPixmap( - "loop_point_b" ) ); - } - if( s_loopPointEndPixmap == NULL ) - { - s_loopPointEndPixmap = new QPixmap( embed::getIconPixmap( - "loop_point_e" ) ); - } setAttribute( Qt::WA_OpaquePaintEvent, true ); move( 0, yoff ); - setFixedHeight( 18 ); m_xOffset -= s_posMarkerPixmap->width() / 2; @@ -224,55 +220,71 @@ void TimeLineWidget::paintEvent( QPaintEvent * ) { QPainter p( this ); - QColor bg_color = QApplication::palette().color( QPalette::Active, - QPalette::Background ); - QLinearGradient g( 0, 0, 0, height() ); - g.setColorAt( 0, bg_color.lighter( 150 ) ); - g.setColorAt( 1, bg_color.darker( 150 ) ); - p.fillRect( 0, 0, width(), height(), g ); + // Draw background + p.fillRect( 0, 0, width(), height(), p.background() ); + // Clip so that we only draw everything starting from the offset p.setClipRect( m_xOffset, 0, width() - m_xOffset, height() ); - p.setPen( QColor( 0, 0, 0 ) ); - - p.setOpacity( loopPointsEnabled() ? 0.9 : 0.2 ); - p.drawPixmap( markerX( loopBegin() )+2, 2, *s_loopPointBeginPixmap ); - p.drawPixmap( markerX( loopEnd() )+2, 2, *s_loopPointEndPixmap ); - p.setOpacity( 1.0 ); + // Draw the loop rectangle + int const & loopRectMargin = getLoopRectangleVerticalPadding(); + int const loopRectHeight = this->height() - 2 * loopRectMargin; + int const loopStart = markerX( loopBegin() ) + 8; + int const loopEndR = markerX( loopEnd() ) + 9; + int const loopRectWidth = loopEndR - loopStart; - tact_t tact_num = m_begin.getTact(); - int x = m_xOffset + s_posMarkerPixmap->width() / 2 - - ( ( static_cast( m_begin * m_ppt ) / MidiTime::ticksPerTact() ) % static_cast( m_ppt ) ); + bool const loopPointsActive = loopPointsEnabled(); - QColor lineColor( 192, 192, 192 ); - QColor tactColor( lineColor.darker( 120 ) ); + // Draw the main rectangle (inner fill only) + QRect outerRectangle( loopStart, loopRectMargin, loopRectWidth - 1, loopRectHeight - 1 ); + p.fillRect( outerRectangle, loopPointsActive ? getActiveLoopBrush() : getInactiveLoopBrush()); - // Set font to half of the widgets size (in pixels) + // Draw the bar lines and numbers + // Activate hinting on the font QFont font = p.font(); - font.setPixelSize( this->height() * 0.5 ); - p.setFont( font ); + font.setHintingPreference( QFont::PreferFullHinting ); + p.setFont(font); + int const fontAscent = p.fontMetrics().ascent(); + int const fontHeight = p.fontMetrics().height(); + + QColor const & barLineColor = getBarLineColor(); + QColor const & barNumberColor = getBarNumberColor(); + + tact_t barNumber = m_begin.getTact(); + int const x = m_xOffset + s_posMarkerPixmap->width() / 2 - + ( ( static_cast( m_begin * m_ppt ) / MidiTime::ticksPerTact() ) % static_cast( m_ppt ) ); for( int i = 0; x + i * m_ppt < width(); ++i ) { - const int cx = x + qRound( i * m_ppt ); - p.setPen( lineColor ); - p.drawLine( cx, 5, cx, height() - 6 ); - ++tact_num; - if( ( tact_num - 1 ) % + ++barNumber; + if( ( barNumber - 1 ) % qMax( 1, qRound( 1.0f / 3.0f * MidiTime::ticksPerTact() / m_ppt ) ) == 0 ) { - const QString s = QString::number( tact_num ); - p.setPen( tactColor ); - p.drawText( cx + qRound( ( m_ppt - p.fontMetrics(). - width( s ) ) / 2 ), - height() - p.fontMetrics().ascent() / 2, s ); + const int cx = x + qRound( i * m_ppt ); + p.setPen( barLineColor ); + p.drawLine( cx, 5, cx, height() - 6 ); + + const QString s = QString::number( barNumber ); + p.setPen( barNumberColor ); + p.drawText( cx + 5, ((height() - fontHeight) / 2) + fontAscent, s ); } } + // Draw the main rectangle (outer border) + p.setPen( loopPointsActive ? getActiveLoopColor() : getInactiveLoopColor() ); + p.setBrush( Qt::NoBrush ); + p.drawRect( outerRectangle ); + + // Draw the inner border outline (no fill) + QRect innerRectangle = outerRectangle.adjusted( 1, 1, -1, -1 ); + p.setPen( loopPointsActive ? getActiveLoopInnerColor() : getInactiveLoopInnerColor() ); + p.setBrush( Qt::NoBrush ); + p.drawRect( innerRectangle ); + + // Draw the position marker p.setOpacity( 0.6 ); - p.drawPixmap( m_posMarkerX, height() - s_posMarkerPixmap->height(), - *s_posMarkerPixmap ); + p.drawPixmap( m_posMarkerX, height() - s_posMarkerPixmap->height(), *s_posMarkerPixmap ); }