diff --git a/resources.qrc b/resources.qrc index 094a99153..3aa493019 100644 --- a/resources.qrc +++ b/resources.qrc @@ -153,5 +153,6 @@ data/images/add-contact.png data/images/account-none.png data/images/green-dot.png + data/images/sliderbutton_knob.png diff --git a/src/widgets/AccountWidget.cpp b/src/widgets/AccountWidget.cpp index 408d80573..69774e4fc 100644 --- a/src/widgets/AccountWidget.cpp +++ b/src/widgets/AccountWidget.cpp @@ -128,6 +128,11 @@ AccountWidget::AccountWidget( QWidget* parent ) m_inviteButton->setText( tr( "Invite" ) ); vLayout->addWidget( m_inviteButton, 1, 1 ); + +#ifdef Q_OS_MAC + layout()->setContentsMargins( 0, 0, 0, 0 ); +#endif + setInviteWidgetsEnabled( false ); } diff --git a/src/widgets/AccountsPopupWidget.cpp b/src/widgets/AccountsPopupWidget.cpp index a39ac28e9..0a63c8016 100644 --- a/src/widgets/AccountsPopupWidget.cpp +++ b/src/widgets/AccountsPopupWidget.cpp @@ -47,6 +47,11 @@ AccountsPopupWidget::AccountsPopupWidget( QWidget* parent ) setContentsMargins( contentsMargins().left() + 2, contentsMargins().top() + 2 , contentsMargins().right(), contentsMargins().bottom() ); + +#ifdef Q_OS_MAC + setContentsMargins( 0, 0, 0, 0 ); + layout()->setContentsMargins( 0, 0, 0, 0 ); +#endif } void diff --git a/src/widgets/AccountsToolButton.cpp b/src/widgets/AccountsToolButton.cpp index 6070c1fbb..e6dad717a 100644 --- a/src/widgets/AccountsToolButton.cpp +++ b/src/widgets/AccountsToolButton.cpp @@ -72,6 +72,11 @@ AccountsToolButton::AccountsToolButton( QWidget* parent ) separatorLine->setStyleSheet( "QWidget { border-top: 1px solid black; }" ); wMainLayout->addWidget( separatorLine ); +#ifdef Q_OS_MAC + w->setContentsMargins( 4, 4, 2, 2 ); + wMainLayout->setContentsMargins( 4, 4, 2, 2 ); +#endif + m_popup->setWidget( w ); connect( m_popup, SIGNAL( hidden() ), SLOT( popupHidden() ) ); diff --git a/src/widgets/SlideSwitchButton.cpp b/src/widgets/SlideSwitchButton.cpp index 580755999..959e875ff 100644 --- a/src/widgets/SlideSwitchButton.cpp +++ b/src/widgets/SlideSwitchButton.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2012 Teo Mrnjavac + * Copyright 2012 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,9 +19,12 @@ #include "SlideSwitchButton.h" +#include "utils/TomahawkUtils.h" + #include #include #include +#include SlideSwitchButton::SlideSwitchButton( QWidget* parent ) : QPushButton( parent ) @@ -44,11 +48,20 @@ void SlideSwitchButton::init() { setCheckable( true ); +#ifndef Q_OS_MAC + setMouseTracking( true ); +#endif - m_backCheckedColor = QColor( 167, 183, 211 ); - m_backUncheckedColor = QColor( "#d9d9d9" ); + m_knob.load( RESPATH "images/sliderbutton_knob.png" ); + + m_backCheckedColorTop = QColor( 8, 54, 134 ); + m_backCheckedColorBottom = QColor( 118, 172, 240 ); + m_backUncheckedColorTop = QColor( 128, 128, 128 ); + m_backUncheckedColorBottom = QColor( 179, 179, 179 ); + + m_baseColorTop = m_backUncheckedColorTop; + m_baseColorBottom = m_backUncheckedColorBottom; - m_baseColor = m_backUncheckedColor; m_textColor = QColor( "#606060" ); setFocusPolicy( Qt::NoFocus ); @@ -64,15 +77,16 @@ SlideSwitchButton::init() } QSize -SlideSwitchButton::sizeHint() +SlideSwitchButton::sizeHint() const { - QSize size = QPushButton::sizeHint(); - QFontMetrics fm( m_textFont ); - int maxTextLength = qMax( fm.boundingRect( m_checkedText ).width(), - fm.boundingRect( m_uncheckedText ).width() ); - size.rwidth() = contentsMargins().left() + contentsMargins().right() - + 2 /*a bit of margin*/ + maxTextLength + ( height() - 4 ) * 1.25; - return size; +// QSize size = QPushButton::sizeHint(); +// QFontMetrics fm( m_textFont ); +// int maxTextLength = qMax( fm.boundingRect( m_checkedText ).width(), +// fm.boundingRect( m_uncheckedText ).width() ); +// size.rwidth() = contentsMargins().left() + contentsMargins().right() +// + 2 /*a bit of margin*/ + maxTextLength + ( height() - 4 ) * 1.25; +// return size; + return QSize( 70, 20 ); } @@ -80,83 +94,63 @@ void SlideSwitchButton::paintEvent( QPaintEvent* event ) { QPainter painter( this ); - - painter.initFrom( this ); - painter.setPen( m_baseColor ); - - QStyleOptionButton option; - option.initFrom( this ); + painter.setRenderHint( QPainter::Antialiasing ); QPalette palette; + QStyleOptionButton option; + initStyleOption( &option ); + + QPen border; + border.setWidth( 1 ); +#ifndef Q_OS_MAC if ( option.state & QStyle::State_MouseOver ) - painter.setPen( palette.color( QPalette::Highlight ) ); + border.setColor( palette.color( QPalette::Highlight ) ); + else +#endif + border.setColor( QColor( "#606060" ) ); + painter.setPen( border ); //TODO: should the whole thing be highlighted or just the knob? QLinearGradient gradient( 0, 0, 0, 1 ); gradient.setCoordinateMode( QGradient::ObjectBoundingMode ); - gradient.setColorAt( 0, m_baseColor.lighter( 95 ) ); - gradient.setColorAt( 1, m_baseColor.lighter( 115 ) ); + gradient.setColorAt( 0, m_baseColorTop ); + gradient.setColorAt( 1, m_baseColorBottom ); + painter.setBrush( gradient ); + painter.drawRoundedRect( QRect( 0, 0, width() - 0, height() - 0 ).adjusted( 3, 0, -3, 0 ), 2, 2 ); - painter.setBrush( QBrush( gradient ) ); - painter.setRenderHints( QPainter::Antialiasing, true ); - painter.drawRoundedRect( QRect( 0, 0, width() - 0, height() - 0 ), - 5, 5 ); + painter.drawPixmap( m_knobX * ( width() - m_knob.width() ), 0, m_knob ); - //knob - QRect knobRect( 2, 2, ( height() - 4 ) * 1.25, height() - 4 ); - knobRect.moveTo( QPoint( 2 + m_knobX * ( width() - 4 - knobRect.width() ), knobRect.y() ) ); - QLinearGradient knobGradient( 0, 0, 0, 1 ); - knobGradient.setCoordinateMode( QGradient::ObjectBoundingMode ); - knobGradient.setColorAt( 0, m_backUncheckedColor.lighter( 115 ) ); - knobGradient.setColorAt( 1, m_backUncheckedColor.lighter( 95 ) ); - painter.setBrush( QBrush( knobGradient ) ); + qDebug() << "Drawn with knob at:" << m_knobX; - painter.drawRoundedRect( knobRect, 1, 1 ); - -// if we ever want to try with primitives... -// QStyleOptionButton option; -// option.initFrom( this ); -// option.rect = QRect( m_knobX + 1, 1, ( height() - 2 ) * 1.25, height() - 2 ); -// style()->drawPrimitive( QStyle::PE_PanelButtonBevel, &option, &painter, this ); + if ( m_knobX != 1.0 && m_knobX != 0.0 ) + return; //let's draw some text... - QRect textRect = rect().adjusted( 4, 3, -4, -3 ); - painter.setFont( m_textFont ); - painter.setPen( m_textColor ); - if ( m_knobX == 0. ) - { - //draw on right - painter.drawText( textRect, Qt::AlignRight | Qt::AlignVCenter, m_uncheckedText ); - } - else if ( m_knobX == 1. ) - { - //draw on left - painter.drawText( textRect, Qt::AlignLeft | Qt::AlignVCenter, m_checkedText ); - } - //otherwise don't draw because the knob is being animated + if ( m_baseColorTop == m_backUncheckedColorTop ) + painter.setPen( m_textColor ); + else + painter.setPen( Qt::white ); - painter.end(); + painter.setFont( m_textFont ); + const QRect textRect( m_knobX == 0. ? m_knob.width() : 0, 0, width() - m_knob.width(), height() ); + painter.drawText( textRect, Qt::AlignCenter, m_knobX == 0 ? m_uncheckedText : m_checkedText ); } void SlideSwitchButton::onCheckedStateChanged() { - QPropertyAnimation *animation = new QPropertyAnimation( this, "knobX" ); - animation->setDuration( 50 ); + if ( !m_knobAnimation.isNull() ) + m_knobAnimation.data()->stop(); - if ( isChecked() ) - { - animation->setStartValue( 0. ); - animation->setEndValue( 1. ); - } - else - { - animation->setStartValue( 1. ); - animation->setEndValue( 0. ); - } - animation->start( QAbstractAnimation::DeleteWhenStopped ); + m_knobAnimation = QWeakPointer( new QPropertyAnimation( this, "knobX" ) ); + m_knobAnimation.data()->setDuration( 50 ); + + m_knobAnimation.data()->setStartValue( isChecked() ? 0 : 1 ); + m_knobAnimation.data()->setEndValue( isChecked() ? 1 : 0 ); + + m_knobAnimation.data()->start( QAbstractAnimation::DeleteWhenStopped ); } @@ -165,20 +159,24 @@ SlideSwitchButton::setBackChecked( bool state ) { if ( state != m_backChecked ) { + if ( !m_backTopAnimation.isNull() ) + m_backTopAnimation.data()->stop(); + if ( !m_backBottomAnimation.isNull() ) + m_backBottomAnimation.data()->stop(); + m_backChecked = state; - QPropertyAnimation *animation = new QPropertyAnimation( this, "baseColor" ); - animation->setDuration( 300 ); - if ( state ) - { - animation->setStartValue( m_backUncheckedColor ); - animation->setEndValue( m_backCheckedColor ); - } - else - { - animation->setStartValue( m_backCheckedColor ); - animation->setEndValue( m_backUncheckedColor ); - } - animation->start( QAbstractAnimation::DeleteWhenStopped ); + m_backTopAnimation = QWeakPointer( new QPropertyAnimation( this, "baseColorTop" ) ); + m_backBottomAnimation = QWeakPointer( new QPropertyAnimation( this, "baseColorBottom" ) ); + m_backTopAnimation.data()->setDuration( 300 ); + m_backBottomAnimation.data()->setDuration( 300 ); + + m_backTopAnimation.data()->setStartValue( state ? m_backUncheckedColorTop : m_backCheckedColorTop ); + m_backTopAnimation.data()->setEndValue( state ? m_backCheckedColorTop : m_backUncheckedColorTop ); + m_backBottomAnimation.data()->setStartValue( state ? m_backUncheckedColorBottom : m_backCheckedColorBottom ); + m_backBottomAnimation.data()->setEndValue( state ? m_backCheckedColorBottom : m_backUncheckedColorBottom ); + + m_backTopAnimation.data()->start( QAbstractAnimation::DeleteWhenStopped ); + m_backBottomAnimation.data()->start( QAbstractAnimation::DeleteWhenStopped ); } } diff --git a/src/widgets/SlideSwitchButton.h b/src/widgets/SlideSwitchButton.h index 067df5151..7c881d963 100644 --- a/src/widgets/SlideSwitchButton.h +++ b/src/widgets/SlideSwitchButton.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2012 Teo Mrnjavac + * Copyright 2012 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,10 +24,16 @@ #include #include #include +#include + +class QPropertyAnimation; class SlideSwitchButton : public QPushButton { Q_OBJECT + Q_PROPERTY( qreal knobX READ knobX WRITE setKnobX ) + Q_PROPERTY( QColor baseColorTop READ baseColorTop WRITE setBaseColorTop ) + Q_PROPERTY( QColor baseColorBottom READ baseColorBottom WRITE setBaseColorBottom ) public: explicit SlideSwitchButton( QWidget* parent = 0 ); explicit SlideSwitchButton( const QString& checkedText, @@ -35,22 +42,22 @@ public: void init(); - virtual QSize sizeHint(); - virtual QSize minimumSizeHint() { return sizeHint(); } + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const { return sizeHint(); } //the back check-state cannot be changed by the user, only programmatically //to notify that the user-requested operation has completed void setBackChecked( bool state ); bool backChecked() const; - void setKnobX( double x ) { m_knobX = x; repaint(); } - double knobX() const { return m_knobX; } - Q_PROPERTY( double knobX READ knobX WRITE setKnobX ) + void setKnobX( qreal x ) { m_knobX = x; repaint(); } + qreal knobX() const { return m_knobX; } - void setBaseColor( const QColor& color ) { m_baseColor = color; repaint(); } - QColor baseColor() const { return m_baseColor; } - Q_PROPERTY( QColor baseColor READ baseColor WRITE setBaseColor ) + void setBaseColorTop( const QColor& color ) { m_baseColorTop = color; repaint(); } + QColor baseColorTop() const { return m_baseColorTop; } + void setBaseColorBottom( const QColor& color ) { m_baseColorBottom = color; } + QColor baseColorBottom() const { return m_baseColorBottom; } protected: void paintEvent( QPaintEvent* event ); @@ -58,15 +65,21 @@ private slots: void onCheckedStateChanged(); private: + QPixmap m_knob; + QString m_checkedText; QString m_uncheckedText; - QColor m_baseColor; + QColor m_baseColorTop, m_baseColorBottom; QColor m_textColor; - QColor m_backUncheckedColor; - QColor m_backCheckedColor; + QColor m_backUncheckedColorTop, m_backUncheckedColorBottom; + QColor m_backCheckedColorTop, m_backCheckedColorBottom; QFont m_textFont; //needed for sizeHint bool m_backChecked; - double m_knobX; + qreal m_knobX; + + QWeakPointer m_backTopAnimation; + QWeakPointer m_backBottomAnimation; + QWeakPointer m_knobAnimation; }; #endif // SLIDESWITCHBUTTON_H