1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-13 17:43:59 +02:00

Initial commit for the new Accounts pop-up widget.

Still much left to do.
This commit is contained in:
Teo Mrnjavac
2012-08-13 12:00:08 +02:00
parent 3efb32cac8
commit 85a20b4ae9
19 changed files with 975 additions and 4 deletions

View File

@@ -73,7 +73,14 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
TomahawkWindow.cpp
LoadXSPFDialog.cpp
SocialWidget.cpp
ContainedMenuButton.cpp
widgets/ContainedMenuButton.cpp
widgets/AccountListWidget.cpp
widgets/AccountModelFactoryProxy.cpp
widgets/AccountWidget.cpp
widgets/AccountsPopupWidget.cpp
widgets/AccountsToolButton.cpp
widgets/UnstyledFrame.cpp
)
IF( WITH_BREAKPAD )

View File

@@ -44,6 +44,7 @@
#include "utils/TomahawkUtilsGui.h"
#include "utils/ProxyStyle.h"
#include "utils/WidgetDragFilter.h"
#include "widgets/AccountsToolButton.h"
#include "widgets/AnimatedSplitter.h"
#include "widgets/NewPlaylistWidget.h"
#include "widgets/SearchWidget.h"
@@ -73,7 +74,7 @@
#include "libtomahawk/filemetadata/ScanManager.h"
#include "TomahawkApp.h"
#include "LoadXSPFDialog.h"
#include "ContainedMenuButton.h"
#include "widgets/ContainedMenuButton.h"
#ifdef Q_OS_WIN
#include <qtsparkle/Updater>
@@ -285,6 +286,10 @@ TomahawkWindow::setupToolBar()
m_toolbarRightBalancer->setFixedWidth( 0 );
m_toolbar->addWidget( m_toolbarRightBalancer )->setProperty( "kind", QString( "spacer" ) );
m_accountsButton = new AccountsToolButton( m_toolbar );
m_toolbar->addWidget( m_accountsButton );
//TODO: hook up signals for the new accounts widget
#ifndef Q_OS_MAC
ContainedMenuButton* compactMenuButton = new ContainedMenuButton( m_toolbar );
compactMenuButton->setIcon( QIcon( RESPATH "images/configure.png" ) );

View File

@@ -58,6 +58,8 @@ class PlaylistModel;
class QueueView;
class AnimatedSplitter;
class AccountsToolButton;
namespace Ui
{
class TomahawkWindow;
@@ -192,6 +194,7 @@ private:
QAction *m_compactMenuAction;
QMenu *m_compactMainMenu;
#endif
AccountsToolButton *m_accountsButton;
QToolBar *m_toolbar;
QWidget *m_toolbarLeftBalancer;
QWidget *m_toolbarRightBalancer;

View File

@@ -36,6 +36,17 @@ AnimatedSpinner::AnimatedSpinner( QWidget* parent )
, m_showHide( new QTimeLine )
, m_animation( new QTimeLine )
, m_currentIndex( -1 )
, m_size( QSize( 0, 0 ) )
{
init();
}
AnimatedSpinner::AnimatedSpinner( const QSize& size, QWidget *parent )
: QWidget( parent )
, m_showHide( new QTimeLine )
, m_animation( new QTimeLine )
, m_currentIndex( -1 )
, m_size( size )
{
init();
}
@@ -87,7 +98,7 @@ AnimatedSpinner::init()
QSize size;
if ( parentWidget() )
size = sizeHint();
size = m_size != QSize( 0, 0 ) ? m_size : sizeHint();
else
size = m_pixmap.size();
@@ -111,6 +122,7 @@ AnimatedSpinner::paintEvent( QPaintEvent* event )
if ( m_autoCenter && parentWidget() )
{
QPoint center = parentWidget()->contentsRect().center() - QPoint( sizeHint().width() / 2, sizeHint().height() / 2 );
if ( center != pos() )
{
move( center );

View File

@@ -46,6 +46,7 @@ class DLLEXPORT AnimatedSpinner : public QWidget
public:
explicit AnimatedSpinner( QWidget* parent = 0 ); // widget mode
explicit AnimatedSpinner( const QSize& size, QWidget* parent = 0 );
AnimatedSpinner( const QSize& size, bool autoStart ); // pixmap mode
QSize sizeHint() const;
@@ -87,6 +88,8 @@ private:
QVector<qreal> m_colors;
QPixmap m_pixmap;
bool m_autoCenter;
QSize m_size;
};

View File

@@ -0,0 +1,119 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountListWidget.h"
#include "accounts/AccountModel.h"
#include "AccountWidget.h"
#include "utils/TomahawkUtilsGui.h"
#include <QDebug>
AccountListWidget::AccountListWidget( AccountModelFactoryProxy* model, QWidget* parent )
: QWidget( parent )
, m_model( model )
{
m_layout = new QVBoxLayout( this );
TomahawkUtils::unmarginLayout( m_layout );
connect( m_model, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ),
this, SLOT( updateEntries( QModelIndex, QModelIndex ) ) );
connect( m_model, SIGNAL( rowsInserted ( QModelIndex, int, int ) ),
this, SLOT( insertEntries( QModelIndex, int, int ) ) );
connect( m_model, SIGNAL( rowsRemoved( QModelIndex, int, int ) ),
this, SLOT( removeEntries( QModelIndex, int, int ) ) );
connect( m_model, SIGNAL( modelReset() ),
this, SLOT( loadAllEntries() ) );
}
void
AccountListWidget::updateEntries( const QModelIndex& topLeft, const QModelIndex& bottomRight )
{
for ( QHash< QPersistentModelIndex, QList< AccountWidget* > >::iterator it
= m_entries.begin();
it != m_entries.end(); ++it )
{
updateEntry( it.key() );
}
}
void
AccountListWidget::updateEntry( const QPersistentModelIndex& idx )
{
for ( int i = 0; i < m_entries.value( idx ).count(); ++i )
{
m_entries[ idx ][ i ]->update( idx, i ); //update the i-th account of the idx-th factory
}
}
void
AccountListWidget::loadAllEntries()
{
foreach ( QList< AccountWidget* > entry, m_entries )
{
foreach ( AccountWidget* w, entry )
{
m_layout->removeWidget( w );
w->deleteLater();
}
entry.clear();
}
m_entries.clear();
int rc = m_model->rowCount();
insertEntries( QModelIndex(), 0, rc - 1 );
}
void
AccountListWidget::insertEntries( const QModelIndex& parent, int start, int end )
{
for ( int i = start; i <= end; ++i )
{
QPersistentModelIndex idx( m_model->index( i, 0, parent ) );
int count = idx.data( Tomahawk::Accounts::AccountModel::ChildrenOfFactoryRole )
.value< QList< Tomahawk::Accounts::Account* > >().count();
QList< AccountWidget* > entryAccounts;
for ( int j = 0; j < count; ++j )
{
AccountWidget *entry = new AccountWidget( this );
entryAccounts.append( entry );
}
m_entries.insert( idx, entryAccounts );
for ( int j = 0; j < entryAccounts.length(); ++j )
m_layout->insertWidget( i+j, entryAccounts.at( j ) );
updateEntry( idx );
}
}
void
AccountListWidget::removeEntries( const QModelIndex& parent, int start, int end )
{
for ( int i = start; i <= end; ++i )
{
QPersistentModelIndex idx( m_model->index( i, 0, parent ) );
QList< AccountWidget* > &entryAccounts = m_entries[ idx ];
for ( int j = 0; j < entryAccounts.count(); ++j )
{
AccountWidget *a = entryAccounts.at( j );
m_layout->removeWidget( a );
a->deleteLater();
}
m_entries.remove( idx );
}
}

View File

@@ -0,0 +1,48 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTLISTWIDGET_H
#define ACCOUNTLISTWIDGET_H
#include "AccountModelFactoryProxy.h"
#include <QLabel>
#include <QVBoxLayout>
class AccountWidget;
class AccountListWidget : public QWidget
{
Q_OBJECT
public:
explicit AccountListWidget( AccountModelFactoryProxy *model, QWidget* parent = 0 );
private slots:
void updateEntries( const QModelIndex& topLeft, const QModelIndex& bottomRight );
void updateEntry( const QPersistentModelIndex& idx );
void loadAllEntries();
void insertEntries( const QModelIndex& parent, int start, int end );
void removeEntries( const QModelIndex& parent, int start, int end );
private:
QHash< QPersistentModelIndex, QList< AccountWidget* > > m_entries;
AccountModelFactoryProxy* m_model;
QVBoxLayout* m_layout;
};
#endif // ACCOUNTLISTWIDGET_H

View File

@@ -0,0 +1,66 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountModelFactoryProxy.h"
using namespace Tomahawk;
using namespace Accounts;
AccountModelFactoryProxy::AccountModelFactoryProxy( QObject* parent )
: QSortFilterProxyModel( parent )
, m_filterEnabled( false )
, m_filterRowType( AccountModel::TopLevelFactory )
{
}
bool
AccountModelFactoryProxy::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
if ( !m_filterEnabled )
return true;
const QModelIndex idx = sourceModel()->index( sourceRow, 0, sourceParent );
const Qt::CheckState checkState = static_cast< Qt::CheckState >( idx.data( Qt::CheckStateRole ).value< int >() );
if( checkState == Qt::Unchecked ) //if the service is not even enabled
return false;
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( idx.data( AccountModel::RowTypeRole ).value< int >() );
return rowType == m_filterRowType;
}
void
AccountModelFactoryProxy::setFilterEnabled( bool enabled )
{
m_filterEnabled = enabled;
invalidate();
}
void
AccountModelFactoryProxy::setFilterRowType( AccountModel::RowType rowType )
{
if( rowType == m_filterRowType )
return;
m_filterRowType = rowType;
if( m_filterEnabled )
invalidate();
}

View File

@@ -0,0 +1,46 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTMODELFACTORYPROXY_H
#define ACCOUNTMODELFACTORYPROXY_H
#include "accounts/Account.h"
#include "accounts/AccountModel.h"
#include <QSortFilterProxyModel>
class AccountModelFactoryProxy : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit AccountModelFactoryProxy( QObject* parent = 0 );
void setFilterEnabled( bool enabled );
void setFilterRowType( Tomahawk::Accounts::AccountModel::RowType rowType );
protected:
virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex& sourceParent ) const;
private:
bool m_filterEnabled;
Tomahawk::Accounts::AccountModel::RowType m_filterRowType;
};
#endif // ACCOUNTMODELFACTORYPROXY_H

View File

@@ -0,0 +1,192 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountWidget.h"
#include "UnstyledFrame.h"
#include "accounts/Account.h"
#include "accounts/AccountModel.h"
#include "utils/TomahawkUtilsGui.h"
#include "utils/AnimatedSpinner.h"
#include "widgets/ElidedLabel.h"
#include <QBoxLayout>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPersistentModelIndex>
#include <QPixmap>
#include <QPushButton>
#include <QToolButton>
AccountWidget::AccountWidget( QWidget* parent )
: QWidget( parent )
{
QHBoxLayout *mainLayout = new QHBoxLayout( this );
TomahawkUtils::unmarginLayout( mainLayout );
setLayout( mainLayout );
setContentsMargins( 8, 8, 8, 8 );
m_imageLabel = new QLabel( this );
mainLayout->addWidget( m_imageLabel );
mainLayout->setSpacing( 4 );
QGridLayout* vLayout = new QGridLayout( this );
vLayout->setMargin( 3 );
vLayout->setSpacing( 3 );
mainLayout->addLayout( vLayout );
QFrame* idContainer = new QFrame( this );
idContainer->setAttribute( Qt::WA_TranslucentBackground, false );
vLayout->addWidget( idContainer, 0, 0 );
QHBoxLayout* idContLayout = new QHBoxLayout( idContainer );
idContainer->setLayout( idContLayout );
idContainer->setContentsMargins( 0, 0, 0, 0 );
idContLayout->setMargin( 2 );
m_idLabel = new ElidedLabel( idContainer );
m_idLabel->setElideMode( Qt::ElideRight );
m_idLabel->setContentsMargins( 3, 0, 3, 0 );
m_idLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
m_idLabel->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
idContLayout->addWidget( m_idLabel );
m_spinnerWidget = new QWidget( idContainer );
QSize spinnerSize = 16 > m_spinnerWidget->logicalDpiX() * .2 ?
QSize( 16, 16 ) :
QSize( m_spinnerWidget->logicalDpiX() * .15,
m_spinnerWidget->logicalDpiX() * .15 );
m_spinnerWidget->setFixedSize( spinnerSize );
idContLayout->addWidget( m_spinnerWidget );
m_spinnerWidget->setContentsMargins( 0, 0, 0, 0 );
m_spinner = new AnimatedSpinner( m_spinnerWidget->size(), m_spinnerWidget );
idContainer->setStyleSheet( QString( "QFrame {"
"border: 1px solid #c9c9c9;"
"border-radius: %1px;"
"background: #c9c9c9;"
"}" ).arg( idContainer->sizeHint().height() / 2 + 1 ) );
m_statusToggle = new QCheckBox( this );
vLayout->addWidget( m_statusToggle, 0, 1 );
UnstyledFrame* inviteContainer = new UnstyledFrame( this );
vLayout->addWidget( inviteContainer, 1, 0 );
inviteContainer->setFrameColor( QColor( 0x8c, 0x8c, 0x8c ) ); //from ProxyStyle
inviteContainer->setFixedWidth( inviteContainer->logicalDpiX() * 2 );
inviteContainer->setContentsMargins( 1, 1, 1, 2 );
inviteContainer->setAttribute( Qt::WA_TranslucentBackground, false );
inviteContainer->setStyleSheet( "background: white" );
QHBoxLayout* containerLayout = new QHBoxLayout( inviteContainer );
inviteContainer->setLayout( containerLayout );
TomahawkUtils::unmarginLayout( containerLayout );
containerLayout->setContentsMargins( 1, 1, 0, 0 );
m_addAccountIcon = new QLabel( inviteContainer );
m_addAccountIcon->setContentsMargins( 1, 0, 0, 0 );
m_addAccountIcon->setPixmap( QIcon( RESPATH "images/user-avatar.png" ).pixmap( 16 ) );
m_addAccountIcon->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding );
m_addAccountIcon->setAlignment( Qt::AlignCenter );
containerLayout->addWidget( m_addAccountIcon );
m_tweetMenuButton = new QToolButton( inviteContainer );
m_tweetMenuButton->setContentsMargins( 1, 0, 0, 0 );
m_tweetMenuButton->setIcon( QIcon( RESPATH "images/jump-link.png" ) );
m_tweetMenuButton->setToolButtonStyle( Qt::ToolButtonIconOnly );
m_tweetMenuButton->setPopupMode( QToolButton::InstantPopup );
m_tweetMenuButton->setMenu( new QMenu() );
m_tweetMenuButton->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );
m_tweetMenuButton->setFixedWidth( m_tweetMenuButton->sizeHint().height() ); //accommodate the menu indicator
QString tweetMenuButtonSheet(
"QToolButton { border: none; backgroud: white; }"
"QToolButton::menu-indicator { left: 3px; }" );
m_tweetMenuButton->setStyleSheet( tweetMenuButtonSheet );
containerLayout->addWidget( m_tweetMenuButton );
m_inviteEdit = new QLineEdit( inviteContainer );
m_inviteEdit->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
containerLayout->addWidget( m_inviteEdit );
m_inviteEdit->setFrame( false );
m_inviteButton = new QPushButton( this );
m_inviteButton->setFixedWidth( m_inviteButton->logicalDpiX() * 0.8 );
vLayout->addWidget( m_inviteButton, 1, 1 );
}
AccountWidget::~AccountWidget()
{
delete m_spinner;
}
void
AccountWidget::update( const QPersistentModelIndex& idx, int accountIdx )
{
const QPixmap &pixmap = static_cast< QPixmap >( idx.data( Qt::DecorationRole ).value< QPixmap >() );
QSize pixmapSize( 32, 32 );
m_imageLabel->setPixmap( pixmap.scaled( pixmapSize, Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
m_imageLabel->setFixedSize( pixmapSize );
Tomahawk::Accounts::Account* account =
idx.data( Tomahawk::Accounts::AccountModel::ChildrenOfFactoryRole )
.value< QList< Tomahawk::Accounts::Account* > >().at( accountIdx );
if ( account )
{
QFontMetrics fm = m_idLabel->fontMetrics();
m_idLabel->setText( account->accountFriendlyName() );
m_idLabel->setToolTip( "<b>" +
account->accountServiceName() +
"</b><br>" +
account->accountFriendlyName() );
//TODO: make it handle all connection states
m_statusToggle->setChecked( account->connectionState() == Tomahawk::Accounts::Account::Connected );
//we already know it's a factory because of the FactoryProxy
Tomahawk::Accounts::AccountFactory* fac =
qobject_cast< Tomahawk::Accounts::AccountFactory* >(
idx.data( Tomahawk::Accounts::AccountModel::AccountData )
.value< QObject* >() );
if ( fac->factoryId() == "twitteraccount" )
{
m_inviteButton->setText( tr( "Tweet" ) );
m_addAccountIcon->setVisible( false );
m_tweetMenuButton->setVisible( true );
}
else
{
m_inviteButton->setText( tr( "Invite" ) );
m_tweetMenuButton->setVisible( false );
m_addAccountIcon->setVisible( true );
}
if ( account->connectionState() == Tomahawk::Accounts::Account::Connected ||
account->connectionState() == Tomahawk::Accounts::Account::Disconnected )
{
m_spinner->fadeOut();
}
else
{
m_spinner->fadeIn();
}
}
}

View File

@@ -0,0 +1,57 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTWIDGET_H
#define ACCOUNTWIDGET_H
#include <QWidget>
class AnimatedSpinner;
class ElidedLabel;
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
class QPersistentModelIndex;
class QToolButton;
class AccountWidget : public QWidget
{
Q_OBJECT
public:
explicit AccountWidget( QWidget* parent = 0 );
virtual ~AccountWidget();
void update( const QPersistentModelIndex& idx, int accountIdx );
private:
QLabel* m_imageLabel;
ElidedLabel* m_idLabel;
QWidget* m_spinnerWidget;
AnimatedSpinner* m_spinner;
QCheckBox* m_statusToggle;
QLineEdit* m_inviteEdit;
QPushButton* m_inviteButton;
QLabel* m_addAccountIcon;
QToolButton* m_tweetMenuButton;
//TODO: on/off button
};
#endif // ACCOUNTWIDGET_H

View File

@@ -0,0 +1,135 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Leo Franchi <lfranchi@kde.org>
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountsPopupWidget.h"
#include <QDebug>
#include <QPainter>
#include <QPaintEvent>
#include <QVBoxLayout>
#ifdef QT_MAC_USE_COCOA
#include "SourceTreePopupDialog_mac.h"
#endif
AccountsPopupWidget::AccountsPopupWidget( QWidget* parent )
: QWidget( parent )
, m_widget( 0 )
{
setWindowFlags( Qt::FramelessWindowHint );
setWindowFlags( Qt::Popup );
setAutoFillBackground( false );
setAttribute( Qt::WA_TranslucentBackground, true );
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
m_layout = new QVBoxLayout( this );
setLayout( m_layout );
setContentsMargins( contentsMargins().left() + 2, contentsMargins().top() + 2 ,
contentsMargins().right(), contentsMargins().bottom() );
}
void
AccountsPopupWidget::setWidget( QWidget* widget )
{
m_widget = widget;
m_layout->addWidget( m_widget );
}
void
AccountsPopupWidget::anchorAt( const QPoint &p )
{
QPoint myTopRight( p.x() - sizeHint().width() + 8, p.y() );
move( myTopRight );
if( isVisible() )
repaint();
}
void AccountsPopupWidget::paintEvent( QPaintEvent* )
{
// Constants for painting
const int cornerRadius = 8; //the rounding radius of the widget
const QRect brect = rect().adjusted( 2, 2, -2, -2 );
QPainterPath outline;
outline.addRoundedRect( 3, 3, brect.width(), brect.height(), cornerRadius, cornerRadius );
/* if we ever want to draw a triangle...
const int triangleWidth = 20; //the length of the base of the triangle
// Top triangle right branch
outline.moveTo( brect.width() - triangleOffset, brect.top() - triangleDepth );
outline.lineTo( brect.width() - triangleOffset + triangleWidth / 2,
brect.top() );
const int triangleDepth = 10; //the height of the triangle
const int triangleOffset = 30;//the distance from the widget's top-right corner
//to the center of the triangle
// main outline
outline.lineTo( brect.width() - cornerRadius, brect.top() );
outline.quadTo( brect.topRight(),
QPoint( width(), brect.top() + cornerRadius ) );
outline.lineTo( brect.width(), brect.height() - cornerRadius );
outline.quadTo( brect.bottomRight(),
QPoint( brect.width() - cornerRadius, brect.height() ) );
outline.lineTo( brect.left() + cornerRadius, brect.height() );
outline.quadTo( brect.bottomLeft(),
QPoint( brect.left(), brect.height() - cornerRadius ) );
outline.lineTo( brect.left(), brect.top() + cornerRadius );
outline.quadTo( brect.topLeft(),
QPoint( brect.left() + cornerRadius, brect.top() ) );
// Top triangle left branch
outline.lineTo( brect.width() - triangleOffset - triangleWidth / 2,
brect.top() );
outline.lineTo( brect.width() - triangleOffset, brect.top() - triangleDepth );*/
QPainter p( this );
p.setRenderHint( QPainter::Antialiasing );
QPen pen( QColor( 0x8c, 0x8c, 0x8c ) );
pen.setWidth( 2 );
p.setPen( pen );
p.drawPath( outline );
p.setOpacity( 0.96 );
p.fillPath( outline, QColor( "#FFFFFF" ) );
#ifdef QT_MAC_USE_COCOA
// Work around bug in Qt/Mac Cocoa where opening subsequent popups
// would incorrectly calculate the background due to it not being
// invalidated.
SourceTreePopupHelper::clearBackground( this );
#endif
}
void
AccountsPopupWidget::focusOutEvent( QFocusEvent* )
{
hide();
}
void
AccountsPopupWidget::hideEvent( QHideEvent* )
{
emit hidden();
}

View File

@@ -0,0 +1,51 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTSPOPUPWIDGET_H
#define ACCOUNTSPOPUPWIDGET_H
#include "DllMacro.h"
#include "Typedefs.h"
#include <QWidget>
class QVBoxLayout;
class DLLEXPORT AccountsPopupWidget : public QWidget
{
Q_OBJECT
public:
explicit AccountsPopupWidget( QWidget* parent = 0 );
void setWidget( QWidget* widget );
void anchorAt( const QPoint &p );
signals:
void hidden();
protected:
virtual void paintEvent( QPaintEvent* );
virtual void focusOutEvent( QFocusEvent* );
virtual void hideEvent( QHideEvent* );
private:
QVBoxLayout* m_layout;
QWidget* m_widget;
};
#endif // ACCOUNTSPOPUPWIDGET_H

View File

@@ -0,0 +1,96 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AccountsToolButton.h"
#include "AccountListWidget.h"
#include "utils/TomahawkUtils.h"
#include <QLabel>
#include <QListView>
#include <QMouseEvent>
#include <QVBoxLayout>
AccountsToolButton::AccountsToolButton( QWidget* parent )
: QToolButton( parent )
{
m_popup = new AccountsPopupWidget( this );
m_popup->hide();
//Set up popup...
QWidget *w = new QWidget( this );
w->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum );
QVBoxLayout *wMainLayout = new QVBoxLayout( w );
w->setLayout( wMainLayout );
QLabel *connectionsLabel = new QLabel( tr( "Connections" ), w );
QFont clFont = connectionsLabel->font();
clFont.setBold( true );
clFont.setPointSize( 12 );
connectionsLabel->setFont( clFont );
connectionsLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
QToolButton *settingsButton = new QToolButton( w );
settingsButton->setIcon( QIcon( RESPATH "images/account-settings.png" ) );
settingsButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
settingsButton->setText( tr( "Account Settings" ) );
QHBoxLayout *headerLayout = new QHBoxLayout( w );
headerLayout->addWidget( connectionsLabel );
headerLayout->addSpacing( 30 );
headerLayout->addWidget( settingsButton );
wMainLayout->addLayout( headerLayout );
QWidget *separatorLine = new QWidget( w );
separatorLine->setFixedHeight( 1 );
separatorLine->setContentsMargins( 0, 0, 0, 0 );
separatorLine->setStyleSheet( "QWidget { border-top: 1px solid black; }" );
wMainLayout->addWidget( separatorLine );
m_popup->setWidget( w );
connect( m_popup, SIGNAL( hidden() ), SLOT( popupHidden() ) );
m_model = new Tomahawk::Accounts::AccountModel( this );
m_proxy = new AccountModelFactoryProxy( m_model );
m_proxy->setSourceModel( m_model );
m_proxy->setFilterRowType( Tomahawk::Accounts::AccountModel::TopLevelFactory );
m_proxy->setFilterEnabled( true );
AccountListWidget *view = new AccountListWidget( m_proxy, m_popup );
wMainLayout->addWidget( view );
view->setAutoFillBackground( false );
view->setAttribute( Qt::WA_TranslucentBackground, true );
}
void
AccountsToolButton::mousePressEvent( QMouseEvent* event )
{
if( m_popup )
{
QPoint myPos = mapToGlobal( rect().bottomRight() );
m_popup->anchorAt( myPos );
m_popup->show();
event->accept();
}
QToolButton::mousePressEvent( event );
}
void
AccountsToolButton::popupHidden() //SLOT
{
setDown( false );
}

View File

@@ -0,0 +1,49 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCOUNTSTOOLBUTTON_H
#define ACCOUNTSTOOLBUTTON_H
#include "AccountsPopupWidget.h"
#include "accounts/AccountModel.h"
#include "AccountModelFactoryProxy.h"
#include "DllMacro.h"
#include "Typedefs.h"
#include <QToolButton>
class DLLEXPORT AccountsToolButton : public QToolButton
{
Q_OBJECT
public:
explicit AccountsToolButton( QWidget* parent = 0 );
protected:
void mousePressEvent( QMouseEvent *event );
private slots:
void popupHidden();
private:
AccountsPopupWidget* m_popup;
Tomahawk::Accounts::AccountModel *m_model;
AccountModelFactoryProxy *m_proxy;
};
#endif // ACCOUNTSTOOLBUTTON_H

View File

@@ -0,0 +1,38 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "UnstyledFrame.h"
#include <QPainter>
UnstyledFrame::UnstyledFrame( QWidget* parent )
: QWidget( parent )
{
m_frameColor = Qt::black;
}
void
UnstyledFrame::paintEvent( QPaintEvent* event )
{
QWidget::paintEvent( event );
QPainter p;
p.begin( this );
p.setPen( m_frameColor );
p.drawRect( contentsRect() );
p.end();
}

View File

@@ -0,0 +1,44 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 Teo Mrnjavac <teo@kde.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UNSTYLEDFRAME_H
#define UNSTYLEDFRAME_H
#include <QWidget>
/**
* @brief The UnstyledFrame class is just a QWidget with an overridden paintEvent
* to provide a *really* unstyled frame to be used with styles that don't obey
* QFrame::Shape.
*/
class UnstyledFrame : public QWidget
{
Q_OBJECT
public:
explicit UnstyledFrame( QWidget* parent = 0 );
void setFrameColor( const QColor& color ) { m_frameColor = color; repaint(); }
protected:
void paintEvent( QPaintEvent* event );
private:
QColor m_frameColor;
};
#endif // UNSTYLEDFRAME_H