From 85a20b4ae921e5de0cce568677d1d575f07a8214 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 13 Aug 2012 12:00:08 +0200 Subject: [PATCH] Initial commit for the new Accounts pop-up widget. Still much left to do. --- src/CMakeLists.txt | 9 +- src/TomahawkWindow.cpp | 7 +- src/TomahawkWindow.h | 3 + src/libtomahawk/utils/AnimatedSpinner.cpp | 14 +- src/libtomahawk/utils/AnimatedSpinner.h | 3 + src/widgets/AccountListWidget.cpp | 119 ++++++++++++++ src/widgets/AccountListWidget.h | 48 ++++++ src/widgets/AccountModelFactoryProxy.cpp | 66 ++++++++ src/widgets/AccountModelFactoryProxy.h | 46 ++++++ src/widgets/AccountWidget.cpp | 192 ++++++++++++++++++++++ src/widgets/AccountWidget.h | 57 +++++++ src/widgets/AccountsPopupWidget.cpp | 135 +++++++++++++++ src/widgets/AccountsPopupWidget.h | 51 ++++++ src/widgets/AccountsToolButton.cpp | 96 +++++++++++ src/widgets/AccountsToolButton.h | 49 ++++++ src/{ => widgets}/ContainedMenuButton.cpp | 2 +- src/{ => widgets}/ContainedMenuButton.h | 0 src/widgets/UnstyledFrame.cpp | 38 +++++ src/widgets/UnstyledFrame.h | 44 +++++ 19 files changed, 975 insertions(+), 4 deletions(-) create mode 100644 src/widgets/AccountListWidget.cpp create mode 100644 src/widgets/AccountListWidget.h create mode 100644 src/widgets/AccountModelFactoryProxy.cpp create mode 100644 src/widgets/AccountModelFactoryProxy.h create mode 100644 src/widgets/AccountWidget.cpp create mode 100644 src/widgets/AccountWidget.h create mode 100644 src/widgets/AccountsPopupWidget.cpp create mode 100644 src/widgets/AccountsPopupWidget.h create mode 100644 src/widgets/AccountsToolButton.cpp create mode 100644 src/widgets/AccountsToolButton.h rename src/{ => widgets}/ContainedMenuButton.cpp (95%) rename src/{ => widgets}/ContainedMenuButton.h (100%) create mode 100644 src/widgets/UnstyledFrame.cpp create mode 100644 src/widgets/UnstyledFrame.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 99f56e808..cd0cdd914 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 ) diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index ef0547d61..ff7490077 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -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 @@ -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" ) ); diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index 29fb59cbe..5715fee69 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -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; diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp index 9c9f7c878..41ede8954 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.cpp +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -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 ); diff --git a/src/libtomahawk/utils/AnimatedSpinner.h b/src/libtomahawk/utils/AnimatedSpinner.h index 19ec3090e..00b2544fd 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.h +++ b/src/libtomahawk/utils/AnimatedSpinner.h @@ -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 m_colors; QPixmap m_pixmap; bool m_autoCenter; + + QSize m_size; }; diff --git a/src/widgets/AccountListWidget.cpp b/src/widgets/AccountListWidget.cpp new file mode 100644 index 000000000..d3b51122c --- /dev/null +++ b/src/widgets/AccountListWidget.cpp @@ -0,0 +1,119 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#include "AccountListWidget.h" + +#include "accounts/AccountModel.h" +#include "AccountWidget.h" +#include "utils/TomahawkUtilsGui.h" + +#include + +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 ); + } +} diff --git a/src/widgets/AccountListWidget.h b/src/widgets/AccountListWidget.h new file mode 100644 index 000000000..5379c26f9 --- /dev/null +++ b/src/widgets/AccountListWidget.h @@ -0,0 +1,48 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#ifndef ACCOUNTLISTWIDGET_H +#define ACCOUNTLISTWIDGET_H + +#include "AccountModelFactoryProxy.h" + +#include +#include + +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 diff --git a/src/widgets/AccountModelFactoryProxy.cpp b/src/widgets/AccountModelFactoryProxy.cpp new file mode 100644 index 000000000..090f569ac --- /dev/null +++ b/src/widgets/AccountModelFactoryProxy.cpp @@ -0,0 +1,66 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Teo Mrnjavac + * + * 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 . + */ + +#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(); +} diff --git a/src/widgets/AccountModelFactoryProxy.h b/src/widgets/AccountModelFactoryProxy.h new file mode 100644 index 000000000..f7fad0dac --- /dev/null +++ b/src/widgets/AccountModelFactoryProxy.h @@ -0,0 +1,46 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Teo Mrnjavac + * + * 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 . + */ + +#ifndef ACCOUNTMODELFACTORYPROXY_H +#define ACCOUNTMODELFACTORYPROXY_H + +#include "accounts/Account.h" +#include "accounts/AccountModel.h" + +#include + + +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 diff --git a/src/widgets/AccountWidget.cpp b/src/widgets/AccountWidget.cpp new file mode 100644 index 000000000..85a1566de --- /dev/null +++ b/src/widgets/AccountWidget.cpp @@ -0,0 +1,192 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#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 +#include +#include +#include +#include +#include +#include +#include +#include + +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( "" + + account->accountServiceName() + + "
" + + 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(); + } + } +} diff --git a/src/widgets/AccountWidget.h b/src/widgets/AccountWidget.h new file mode 100644 index 000000000..54ff132ab --- /dev/null +++ b/src/widgets/AccountWidget.h @@ -0,0 +1,57 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#ifndef ACCOUNTWIDGET_H +#define ACCOUNTWIDGET_H + +#include + +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 diff --git a/src/widgets/AccountsPopupWidget.cpp b/src/widgets/AccountsPopupWidget.cpp new file mode 100644 index 000000000..deb87af25 --- /dev/null +++ b/src/widgets/AccountsPopupWidget.cpp @@ -0,0 +1,135 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Leo Franchi + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#include "AccountsPopupWidget.h" + +#include +#include +#include +#include + +#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(); +} diff --git a/src/widgets/AccountsPopupWidget.h b/src/widgets/AccountsPopupWidget.h new file mode 100644 index 000000000..1499b287c --- /dev/null +++ b/src/widgets/AccountsPopupWidget.h @@ -0,0 +1,51 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Teo Mrnjavac + * + * 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 . + */ + +#ifndef ACCOUNTSPOPUPWIDGET_H +#define ACCOUNTSPOPUPWIDGET_H + +#include "DllMacro.h" +#include "Typedefs.h" + +#include + +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 diff --git a/src/widgets/AccountsToolButton.cpp b/src/widgets/AccountsToolButton.cpp new file mode 100644 index 000000000..df9568f20 --- /dev/null +++ b/src/widgets/AccountsToolButton.cpp @@ -0,0 +1,96 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Teo Mrnjavac + * + * 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 . + */ + +#include "AccountsToolButton.h" + +#include "AccountListWidget.h" +#include "utils/TomahawkUtils.h" + +#include +#include +#include +#include + +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 ); +} diff --git a/src/widgets/AccountsToolButton.h b/src/widgets/AccountsToolButton.h new file mode 100644 index 000000000..2524dd26b --- /dev/null +++ b/src/widgets/AccountsToolButton.h @@ -0,0 +1,49 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Teo Mrnjavac + * + * 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 . + */ + +#ifndef ACCOUNTSTOOLBUTTON_H +#define ACCOUNTSTOOLBUTTON_H + +#include "AccountsPopupWidget.h" + +#include "accounts/AccountModel.h" +#include "AccountModelFactoryProxy.h" +#include "DllMacro.h" +#include "Typedefs.h" + +#include + +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 diff --git a/src/ContainedMenuButton.cpp b/src/widgets/ContainedMenuButton.cpp similarity index 95% rename from src/ContainedMenuButton.cpp rename to src/widgets/ContainedMenuButton.cpp index e4b771763..be9ea8b5c 100644 --- a/src/ContainedMenuButton.cpp +++ b/src/widgets/ContainedMenuButton.cpp @@ -33,7 +33,7 @@ ContainedMenuButton::setMenu( QMenu *menu ) } void -ContainedMenuButton::mousePressEvent( QMouseEvent *event ) +ContainedMenuButton::mousePressEvent( QMouseEvent* event ) { if( m_menu ) { diff --git a/src/ContainedMenuButton.h b/src/widgets/ContainedMenuButton.h similarity index 100% rename from src/ContainedMenuButton.h rename to src/widgets/ContainedMenuButton.h diff --git a/src/widgets/UnstyledFrame.cpp b/src/widgets/UnstyledFrame.cpp new file mode 100644 index 000000000..a56fab17b --- /dev/null +++ b/src/widgets/UnstyledFrame.cpp @@ -0,0 +1,38 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#include "UnstyledFrame.h" + +#include + +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(); +} diff --git a/src/widgets/UnstyledFrame.h b/src/widgets/UnstyledFrame.h new file mode 100644 index 000000000..929b2c041 --- /dev/null +++ b/src/widgets/UnstyledFrame.h @@ -0,0 +1,44 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Teo Mrnjavac + * + * 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 . + */ + +#ifndef UNSTYLEDFRAME_H +#define UNSTYLEDFRAME_H + +#include + +/** + * @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