Try the next UI experiment - wide buttons down the side like Qt Creator

This commit is contained in:
David Sansome 2010-10-01 19:27:01 +00:00
parent 730708f0ca
commit 56d72a00bf
25 changed files with 1716 additions and 627 deletions

24
3rdparty/fancytabwidget/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 2.6)
set(SOURCES
fancytabwidget.cpp
styledbar.cpp
stylehelper.cpp
)
set(HEADERS
fancytabwidget.h
styledbar.h
)
qt4_wrap_cpp(MOC ${HEADERS})
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
add_library(fancytabwidget STATIC
${SOURCES}
${MOC}
)
target_link_libraries(fancytabwidget
${QT_LIBRARIES}
)

View File

@ -0,0 +1,519 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "fancytabwidget.h"
#include "stylehelper.h"
#include "styledbar.h"
#include <QDebug>
#include <QtGui/QColorDialog>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QMouseEvent>
#include <QtGui/QWindowsStyle>
#include <QtGui/QPainter>
#include <QtGui/QSplitter>
#include <QtGui/QStackedLayout>
#include <QtGui/QStatusBar>
#include <QtGui/QToolButton>
#include <QtGui/QToolTip>
#include <QtCore/QAnimationGroup>
#include <QtCore/QPropertyAnimation>
using namespace Core;
using namespace Internal;
const int FancyTabBar::m_rounding = 22;
const int FancyTabBar::m_textPadding = 4;
void FancyTab::fadeIn()
{
animator.stop();
animator.setDuration(80);
animator.setEndValue(40);
animator.start();
}
void FancyTab::fadeOut()
{
animator.stop();
animator.setDuration(160);
animator.setEndValue(0);
animator.start();
}
void FancyTab::setFader(float value)
{
m_fader = value;
tabbar->update();
}
FancyTabBar::FancyTabBar(QWidget *parent)
: QWidget(parent)
{
m_hoverIndex = -1;
m_currentIndex = -1;
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
setStyle(new QWindowsStyle);
setMinimumWidth(qMax(2 * m_rounding, 40));
setAttribute(Qt::WA_Hover, true);
setFocusPolicy(Qt::NoFocus);
setMouseTracking(true); // Needed for hover events
m_triggerTimer.setSingleShot(true);
// We use a zerotimer to keep the sidebar responsive
connect(&m_triggerTimer, SIGNAL(timeout()), this, SLOT(emitCurrentIndex()));
}
FancyTabBar::~FancyTabBar()
{
delete style();
}
QSize FancyTabBar::tabSizeHint(bool minimum) const
{
QFont boldFont(font());
boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize());
boldFont.setBold(true);
QFontMetrics fm(boldFont);
int spacing = 8;
int width = 60 + spacing + 2;
int maxLabelwidth = 0;
for (int tab=0 ; tab<count() ;++tab) {
int width = fm.width(tabText(tab));
if (width > maxLabelwidth)
maxLabelwidth = width;
}
int iconHeight = minimum ? 0 : 32;
return QSize(qMax(width, maxLabelwidth + 4), iconHeight + spacing + fm.height());
}
void FancyTabBar::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter p(this);
for (int i = 0; i < count(); ++i)
if (i != currentIndex())
paintTab(&p, i);
// paint active tab last, since it overlaps the neighbors
if (currentIndex() != -1)
paintTab(&p, currentIndex());
}
// Handle hover events for mouse fade ins
void FancyTabBar::mouseMoveEvent(QMouseEvent *e)
{
int newHover = -1;
for (int i = 0; i < count(); ++i) {
QRect area = tabRect(i);
if (area.contains(e->pos())) {
newHover = i;
break;
}
}
if (newHover == m_hoverIndex)
return;
if (validIndex(m_hoverIndex))
m_tabs[m_hoverIndex]->fadeOut();
m_hoverIndex = newHover;
if (validIndex(m_hoverIndex)) {
m_tabs[m_hoverIndex]->fadeIn();
m_hoverRect = tabRect(m_hoverIndex);
}
}
bool FancyTabBar::event(QEvent *event)
{
if (event->type() == QEvent::ToolTip) {
if (validIndex(m_hoverIndex)) {
QString tt = tabToolTip(m_hoverIndex);
if (!tt.isEmpty()) {
QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), tt, this);
return true;
}
}
}
return QWidget::event(event);
}
// Resets hover animation on mouse enter
void FancyTabBar::enterEvent(QEvent *e)
{
Q_UNUSED(e)
m_hoverRect = QRect();
m_hoverIndex = -1;
}
// Resets hover animation on mouse enter
void FancyTabBar::leaveEvent(QEvent *e)
{
Q_UNUSED(e)
m_hoverIndex = -1;
m_hoverRect = QRect();
for (int i = 0 ; i < m_tabs.count() ; ++i) {
m_tabs[i]->fadeOut();
}
}
QSize FancyTabBar::sizeHint() const
{
QSize sh = tabSizeHint();
return QSize(sh.width(), sh.height() * m_tabs.count());
}
QSize FancyTabBar::minimumSizeHint() const
{
QSize sh = tabSizeHint(true);
return QSize(sh.width(), sh.height() * m_tabs.count());
}
QRect FancyTabBar::tabRect(int index) const
{
QSize sh = tabSizeHint();
if (sh.height() * m_tabs.count() > height())
sh.setHeight(height() / m_tabs.count());
return QRect(0, index * sh.height(), sh.width(), sh.height());
}
// This keeps the sidebar responsive since
// we get a repaint before loading the
// mode itself
void FancyTabBar::emitCurrentIndex()
{
emit currentChanged(m_currentIndex);
}
void FancyTabBar::mousePressEvent(QMouseEvent *e)
{
e->accept();
for (int index = 0; index < m_tabs.count(); ++index) {
if (tabRect(index).contains(e->pos())) {
if (isTabEnabled(index)) {
m_currentIndex = index;
update();
m_triggerTimer.start(0);
}
break;
}
}
}
void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
{
if (!validIndex(tabIndex)) {
qWarning("invalid index");
return;
}
painter->save();
QRect rect = tabRect(tabIndex);
bool selected = (tabIndex == m_currentIndex);
bool enabled = isTabEnabled(tabIndex);
if (selected) {
//background
painter->save();
QLinearGradient grad(rect.topLeft(), rect.topRight());
grad.setColorAt(0, QColor(255, 255, 255, 140));
grad.setColorAt(1, QColor(255, 255, 255, 210));
painter->fillRect(rect.adjusted(0, 0, 0, -1), grad);
painter->restore();
//shadows
painter->setPen(QColor(0, 0, 0, 110));
painter->drawLine(rect.topLeft() + QPoint(1,-1), rect.topRight() - QPoint(0,1));
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
painter->setPen(QColor(0, 0, 0, 40));
painter->drawLine(rect.topLeft(), rect.bottomLeft());
//highlights
painter->setPen(QColor(255, 255, 255, 50));
painter->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0,2));
painter->drawLine(rect.bottomLeft() + QPoint(0, 1), rect.bottomRight() + QPoint(0,1));
painter->setPen(QColor(255, 255, 255, 40));
painter->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight());
painter->drawLine(rect.topRight() + QPoint(0, 1), rect.bottomRight() - QPoint(0, 1));
painter->drawLine(rect.bottomLeft() + QPoint(0,-1), rect.bottomRight()-QPoint(0,1));
}
QString tabText(this->tabText(tabIndex));
QRect tabTextRect(tabRect(tabIndex));
QRect tabIconRect(tabTextRect);
tabTextRect.translate(0, -2);
QFont boldFont(painter->font());
boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize());
boldFont.setBold(true);
painter->setFont(boldFont);
painter->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110));
int textFlags = Qt::AlignCenter | Qt::AlignBottom | Qt::TextWordWrap;
if (enabled) {
painter->drawText(tabTextRect, textFlags, tabText);
painter->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor());
} else {
painter->setPen(selected ? Utils::StyleHelper::panelTextColor() : QColor(255, 255, 255, 120));
}
#ifndef Q_WS_MAC
if (!selected && enabled) {
painter->save();
int fader = int(m_tabs[tabIndex]->fader());
QLinearGradient grad(rect.topLeft(), rect.topRight());
grad.setColorAt(0, Qt::transparent);
grad.setColorAt(0.5, QColor(255, 255, 255, fader));
grad.setColorAt(1, Qt::transparent);
painter->fillRect(rect, grad);
painter->setPen(QPen(grad, 1.0));
painter->drawLine(rect.topLeft(), rect.topRight());
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
painter->restore();
}
#endif
if (!enabled)
painter->setOpacity(0.7);
int textHeight = painter->fontMetrics().boundingRect(QRect(0, 0, width(), height()), Qt::TextWordWrap, tabText).height();
tabIconRect.adjust(0, 4, 0, -textHeight);
Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, enabled ? QIcon::Normal : QIcon::Disabled);
painter->translate(0, -1);
painter->drawText(tabTextRect, textFlags, tabText);
painter->restore();
}
void FancyTabBar::setCurrentIndex(int index) {
if (isTabEnabled(index)) {
m_currentIndex = index;
update();
emit currentChanged(m_currentIndex);
}
}
void FancyTabBar::setTabEnabled(int index, bool enable)
{
Q_ASSERT(index < m_tabs.size());
Q_ASSERT(index >= 0);
if (index < m_tabs.size() && index >= 0) {
m_tabs[index]->enabled = enable;
update(tabRect(index));
}
}
bool FancyTabBar::isTabEnabled(int index) const
{
Q_ASSERT(index < m_tabs.size());
Q_ASSERT(index >= 0);
if (index < m_tabs.size() && index >= 0)
return m_tabs[index]->enabled;
return false;
}
//////
// FancyColorButton
//////
class FancyColorButton : public QWidget
{
public:
FancyColorButton(QWidget *parent)
: m_parent(parent)
{
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
}
void mousePressEvent(QMouseEvent *ev)
{
if (ev->modifiers() & Qt::ShiftModifier)
Utils::StyleHelper::setBaseColor(QColorDialog::getColor(Utils::StyleHelper::requestedBaseColor(), m_parent));
}
private:
QWidget *m_parent;
};
//////
// FancyTabWidget
//////
FancyTabWidget::FancyTabWidget(QWidget *parent)
: QWidget(parent)
{
m_tabBar = new FancyTabBar(this);
m_selectionWidget = new QWidget(this);
QVBoxLayout *selectionLayout = new QVBoxLayout;
selectionLayout->setSpacing(0);
selectionLayout->setMargin(0);
Utils::StyledBar *bar = new Utils::StyledBar;
QHBoxLayout *layout = new QHBoxLayout(bar);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(new FancyColorButton(this));
selectionLayout->addWidget(bar);
selectionLayout->addWidget(m_tabBar, 1);
m_selectionWidget->setLayout(selectionLayout);
m_selectionWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
m_cornerWidgetContainer = new QWidget(this);
m_cornerWidgetContainer->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
m_cornerWidgetContainer->setAutoFillBackground(false);
QVBoxLayout *cornerWidgetLayout = new QVBoxLayout;
cornerWidgetLayout->setSpacing(0);
cornerWidgetLayout->setMargin(0);
cornerWidgetLayout->addStretch();
m_cornerWidgetContainer->setLayout(cornerWidgetLayout);
selectionLayout->addWidget(m_cornerWidgetContainer, 0);
m_modesStack = new QStackedLayout;
m_statusBar = new QStatusBar;
m_statusBar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
QVBoxLayout *vlayout = new QVBoxLayout;
vlayout->setMargin(0);
vlayout->setSpacing(0);
vlayout->addLayout(m_modesStack);
vlayout->addWidget(m_statusBar);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->setMargin(0);
mainLayout->setSpacing(1);
mainLayout->addWidget(m_selectionWidget);
mainLayout->addLayout(vlayout);
setLayout(mainLayout);
connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(showWidget(int)));
}
void FancyTabWidget::insertTab(int index, QWidget *tab, const QIcon &icon, const QString &label)
{
m_modesStack->insertWidget(index, tab);
m_tabBar->insertTab(index, icon, label);
}
void FancyTabWidget::removeTab(int index)
{
m_modesStack->removeWidget(m_modesStack->widget(index));
m_tabBar->removeTab(index);
}
void FancyTabWidget::setBackgroundBrush(const QBrush &brush)
{
QPalette pal = m_tabBar->palette();
pal.setBrush(QPalette::Mid, brush);
m_tabBar->setPalette(pal);
pal = m_cornerWidgetContainer->palette();
pal.setBrush(QPalette::Mid, brush);
m_cornerWidgetContainer->setPalette(pal);
}
void FancyTabWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
QRect rect = m_selectionWidget->rect().adjusted(0, 0, 1, 0);
rect = style()->visualRect(layoutDirection(), geometry(), rect);
Utils::StyleHelper::verticalGradient(&painter, rect, rect);
painter.setPen(Utils::StyleHelper::borderColor());
painter.drawLine(rect.topRight(), rect.bottomRight());
QColor light = Utils::StyleHelper::sidebarHighlight();
painter.setPen(light);
painter.drawLine(rect.bottomLeft(), rect.bottomRight());
}
void FancyTabWidget::insertCornerWidget(int pos, QWidget *widget)
{
QVBoxLayout *layout = static_cast<QVBoxLayout *>(m_cornerWidgetContainer->layout());
layout->insertWidget(pos, widget);
}
int FancyTabWidget::cornerWidgetCount() const
{
return m_cornerWidgetContainer->layout()->count();
}
void FancyTabWidget::addCornerWidget(QWidget *widget)
{
m_cornerWidgetContainer->layout()->addWidget(widget);
}
int FancyTabWidget::currentIndex() const
{
return m_tabBar->currentIndex();
}
QStatusBar *FancyTabWidget::statusBar() const
{
return m_statusBar;
}
void FancyTabWidget::setCurrentIndex(int index)
{
if (m_tabBar->isTabEnabled(index))
m_tabBar->setCurrentIndex(index);
}
void FancyTabWidget::showWidget(int index)
{
emit currentAboutToShow(index);
m_modesStack->setCurrentIndex(index);
emit currentChanged(index);
}
void FancyTabWidget::setTabToolTip(int index, const QString &toolTip)
{
m_tabBar->setTabToolTip(index, toolTip);
}
void FancyTabWidget::setTabEnabled(int index, bool enable)
{
m_tabBar->setTabEnabled(index, enable);
}
bool FancyTabWidget::isTabEnabled(int index) const
{
return m_tabBar->isTabEnabled(index);
}

187
3rdparty/fancytabwidget/fancytabwidget.h vendored Normal file
View File

@ -0,0 +1,187 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef FANCYTABWIDGET_H
#define FANCYTABWIDGET_H
#include <QtGui/QIcon>
#include <QtGui/QWidget>
#include <QtCore/QTimer>
#include <QtCore/QPropertyAnimation>
QT_BEGIN_NAMESPACE
class QPainter;
class QStackedLayout;
class QStatusBar;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
class FancyTab : public QObject{
Q_OBJECT
Q_PROPERTY(float fader READ fader WRITE setFader)
public:
FancyTab(QWidget *tabbar) : enabled(false), tabbar(tabbar), m_fader(0) {
animator.setPropertyName("fader");
animator.setTargetObject(this);
}
float fader() { return m_fader; }
void setFader(float value);
void fadeIn();
void fadeOut();
QIcon icon;
QString text;
QString toolTip;
bool enabled;
private:
QPropertyAnimation animator;
QWidget *tabbar;
float m_fader;
};
class FancyTabBar : public QWidget
{
Q_OBJECT
public:
FancyTabBar(QWidget *parent = 0);
~FancyTabBar();
bool event(QEvent *event);
void paintEvent(QPaintEvent *event);
void paintTab(QPainter *painter, int tabIndex) const;
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
bool validIndex(int index) const { return index >= 0 && index < m_tabs.count(); }
QSize sizeHint() const;
QSize minimumSizeHint() const;
void setTabEnabled(int index, bool enable);
bool isTabEnabled(int index) const;
void insertTab(int index, const QIcon &icon, const QString &label) {
FancyTab *tab = new FancyTab(this);
tab->icon = icon;
tab->text = label;
m_tabs.insert(index, tab);
}
void setEnabled(int index, bool enabled);
void removeTab(int index) {
FancyTab *tab = m_tabs.takeAt(index);
delete tab;
}
void setCurrentIndex(int index);
int currentIndex() const { return m_currentIndex; }
void setTabToolTip(int index, QString toolTip) { m_tabs[index]->toolTip = toolTip; }
QString tabToolTip(int index) const { return m_tabs.at(index)->toolTip; }
QIcon tabIcon(int index) const {return m_tabs.at(index)->icon; }
QString tabText(int index) const { return m_tabs.at(index)->text; }
int count() const {return m_tabs.count(); }
QRect tabRect(int index) const;
signals:
void currentChanged(int);
public slots:
void emitCurrentIndex();
private:
static const int m_rounding;
static const int m_textPadding;
QRect m_hoverRect;
int m_hoverIndex;
int m_currentIndex;
QList<FancyTab*> m_tabs;
QTimer m_triggerTimer;
QSize tabSizeHint(bool minimum = false) const;
};
class FancyTabWidget : public QWidget
{
Q_OBJECT
public:
FancyTabWidget(QWidget *parent = 0);
void insertTab(int index, QWidget *tab, const QIcon &icon, const QString &label);
void removeTab(int index);
void setBackgroundBrush(const QBrush &brush);
void addCornerWidget(QWidget *widget);
void insertCornerWidget(int pos, QWidget *widget);
int cornerWidgetCount() const;
void setTabToolTip(int index, const QString &toolTip);
int count() const { return m_tabBar->count(); }
void paintEvent(QPaintEvent *event);
int currentIndex() const;
QStatusBar *statusBar() const;
void setTabEnabled(int index, bool enable);
bool isTabEnabled(int index) const;
signals:
void currentAboutToShow(int index);
void currentChanged(int index);
public slots:
void setCurrentIndex(int index);
private slots:
void showWidget(int index);
private:
FancyTabBar *m_tabBar;
QWidget *m_cornerWidgetContainer;
QStackedLayout *m_modesStack;
QWidget *m_selectionWidget;
QStatusBar *m_statusBar;
};
} // namespace Internal
} // namespace Core
using Core::Internal::FancyTab;
using Core::Internal::FancyTabBar;
using Core::Internal::FancyTabWidget;
#endif // FANCYTABWIDGET_H

95
3rdparty/fancytabwidget/styledbar.cpp vendored Normal file
View File

@ -0,0 +1,95 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "styledbar.h"
#include "stylehelper.h"
#include <QtCore/QVariant>
#include <QtGui/QPainter>
#include <QtGui/QPixmapCache>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
using namespace Utils;
StyledBar::StyledBar(QWidget *parent)
: QWidget(parent)
{
setProperty("panelwidget", true);
setProperty("panelwidget_singlerow", true);
setProperty("lightColored", false);
}
void StyledBar::setSingleRow(bool singleRow)
{
setProperty("panelwidget_singlerow", singleRow);
}
bool StyledBar::isSingleRow() const
{
return property("panelwidget_singlerow").toBool();
}
void StyledBar::setLightColored(bool lightColored)
{
setProperty("lightColored", lightColored);
}
bool StyledBar::isLightColored() const
{
return property("lightColored").toBool();
}
void StyledBar::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
QStyleOption option;
option.rect = rect();
option.state = QStyle::State_Horizontal;
style()->drawControl(QStyle::CE_ToolBar, &option, &painter, this);
}
StyledSeparator::StyledSeparator(QWidget *parent)
: QWidget(parent)
{
setFixedWidth(10);
}
void StyledSeparator::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
QStyleOption option;
option.rect = rect();
option.state = QStyle::State_Horizontal;
option.palette = palette();
style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &option, &painter, this);
}

63
3rdparty/fancytabwidget/styledbar.h vendored Normal file
View File

@ -0,0 +1,63 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef STYLEDBAR_H
#define STYLEDBAR_H
#include <QtGui/QWidget>
namespace Utils {
class StyledBar : public QWidget
{
Q_OBJECT
public:
StyledBar(QWidget *parent = 0);
void setSingleRow(bool singleRow);
bool isSingleRow() const;
void setLightColored(bool lightColored);
bool isLightColored() const;
protected:
void paintEvent(QPaintEvent *event);
};
class StyledSeparator : public QWidget
{
Q_OBJECT
public:
StyledSeparator(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *event);
};
} // Utils
#endif // STYLEDBAR_H

485
3rdparty/fancytabwidget/stylehelper.cpp vendored Normal file
View File

@ -0,0 +1,485 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "stylehelper.h"
#include <QtGui/QPixmapCache>
#include <QtGui/QWidget>
#include <QtCore/QRect>
#include <QtGui/QPainter>
#include <QtGui/QApplication>
#include <QtGui/QPalette>
#include <QtGui/QStyleOption>
#include <QtCore/QObject>
// Clamps float color values within (0, 255)
static int clamp(float x)
{
const int val = x > 255 ? 255 : static_cast<int>(x);
return val < 0 ? 0 : val;
}
// Clamps float color values within (0, 255)
/*
static int range(float x, int min, int max)
{
int val = x > max ? max : x;
return val < min ? min : val;
}
*/
namespace Utils {
QColor StyleHelper::mergedColors(const QColor &colorA, const QColor &colorB, int factor)
{
const int maxFactor = 100;
QColor tmp = colorA;
tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
return tmp;
}
qreal StyleHelper::sidebarFontSize()
{
#if defined(Q_WS_MAC)
return 10;
#else
return 7.5;
#endif
}
QPalette StyleHelper::sidebarFontPalette(const QPalette &original)
{
QPalette palette = original;
palette.setColor(QPalette::Active, QPalette::Text, panelTextColor());
palette.setColor(QPalette::Active, QPalette::WindowText, panelTextColor());
palette.setColor(QPalette::Inactive, QPalette::Text, panelTextColor().darker());
palette.setColor(QPalette::Inactive, QPalette::WindowText, panelTextColor().darker());
return palette;
}
QColor StyleHelper::panelTextColor(bool lightColored)
{
//qApp->palette().highlightedText().color();
if (!lightColored)
return Qt::white;
else
return Qt::black;
}
// Invalid by default, setBaseColor needs to be called at least once
QColor StyleHelper::m_baseColor;
QColor StyleHelper::m_requestedBaseColor;
QColor StyleHelper::baseColor(bool lightColored)
{
if (!lightColored)
return m_baseColor;
else
return m_baseColor.lighter(230);
}
QColor StyleHelper::highlightColor(bool lightColored)
{
QColor result = baseColor(lightColored);
if (!lightColored)
result.setHsv(result.hue(),
clamp(result.saturation()),
clamp(result.value() * 1.16));
else
result.setHsv(result.hue(),
clamp(result.saturation()),
clamp(result.value() * 1.06));
return result;
}
QColor StyleHelper::shadowColor(bool lightColored)
{
QColor result = baseColor(lightColored);
result.setHsv(result.hue(),
clamp(result.saturation() * 1.1),
clamp(result.value() * 0.70));
return result;
}
QColor StyleHelper::borderColor(bool lightColored)
{
QColor result = baseColor(lightColored);
result.setHsv(result.hue(),
result.saturation(),
result.value() / 2);
return result;
}
// We try to ensure that the actual color used are within
// reasonalbe bounds while generating the actual baseColor
// from the users request.
void StyleHelper::setBaseColor(const QColor &newcolor)
{
m_requestedBaseColor = newcolor;
QColor color;
color.setHsv(newcolor.hue(),
newcolor.saturation() * 0.7,
64 + newcolor.value() / 3);
if (color.isValid() && color != m_baseColor) {
m_baseColor = color;
foreach (QWidget *w, QApplication::topLevelWidgets())
w->update();
}
}
static void verticalGradientHelper(QPainter *p, const QRect &spanRect, const QRect &rect, bool lightColored)
{
QColor highlight = StyleHelper::highlightColor(lightColored);
QColor shadow = StyleHelper::shadowColor(lightColored);
QLinearGradient grad(spanRect.topRight(), spanRect.topLeft());
grad.setColorAt(0, highlight.lighter(117));
grad.setColorAt(1, shadow.darker(109));
p->fillRect(rect, grad);
QColor light(255, 255, 255, 80);
p->setPen(light);
p->drawLine(rect.topRight() - QPoint(1, 0), rect.bottomRight() - QPoint(1, 0));
QColor dark(0, 0, 0, 90);
p->setPen(dark);
p->drawLine(rect.topLeft(), rect.bottomLeft());
}
void StyleHelper::verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
{
if (StyleHelper::usePixmapCache()) {
QString key;
QColor keyColor = baseColor(lightColored);
key.sprintf("mh_vertical %d %d %d %d %d",
spanRect.width(), spanRect.height(), clipRect.width(),
clipRect.height(), keyColor.rgb());;
QPixmap pixmap;
if (!QPixmapCache::find(key, pixmap)) {
pixmap = QPixmap(clipRect.size());
QPainter p(&pixmap);
QRect rect(0, 0, clipRect.width(), clipRect.height());
verticalGradientHelper(&p, spanRect, rect, lightColored);
p.end();
QPixmapCache::insert(key, pixmap);
}
painter->drawPixmap(clipRect.topLeft(), pixmap);
} else {
verticalGradientHelper(painter, spanRect, clipRect, lightColored);
}
}
static void horizontalGradientHelper(QPainter *p, const QRect &spanRect, const
QRect &rect, bool lightColored)
{
if (lightColored) {
QLinearGradient shadowGradient(rect.topLeft(), rect.bottomLeft());
shadowGradient.setColorAt(0, 0xf0f0f0);
shadowGradient.setColorAt(1, 0xcfcfcf);
p->fillRect(rect, shadowGradient);
return;
}
QColor base = StyleHelper::baseColor(lightColored);
QColor highlight = StyleHelper::highlightColor(lightColored);
QColor shadow = StyleHelper::shadowColor(lightColored);
QLinearGradient grad(rect.topLeft(), rect.bottomLeft());
grad.setColorAt(0, highlight.lighter(120));
if (rect.height() == StyleHelper::navigationWidgetHeight()) {
grad.setColorAt(0.4, highlight);
grad.setColorAt(0.401, base);
}
grad.setColorAt(1, shadow);
p->fillRect(rect, grad);
QLinearGradient shadowGradient(spanRect.topLeft(), spanRect.topRight());
shadowGradient.setColorAt(0, QColor(0, 0, 0, 30));
QColor lighterHighlight;
if (!lightColored)
lighterHighlight = highlight.lighter(130);
else
lighterHighlight = highlight.lighter(90);
lighterHighlight.setAlpha(100);
shadowGradient.setColorAt(0.7, lighterHighlight);
shadowGradient.setColorAt(1, QColor(0, 0, 0, 40));
p->fillRect(rect, shadowGradient);
}
void StyleHelper::horizontalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
{
if (StyleHelper::usePixmapCache()) {
QString key;
QColor keyColor = baseColor(lightColored);
key.sprintf("mh_horizontal %d %d %d %d %d %d",
spanRect.width(), spanRect.height(), clipRect.width(),
clipRect.height(), keyColor.rgb(), spanRect.x());
QPixmap pixmap;
if (!QPixmapCache::find(key, pixmap)) {
pixmap = QPixmap(clipRect.size());
QPainter p(&pixmap);
QRect rect = QRect(0, 0, clipRect.width(), clipRect.height());
horizontalGradientHelper(&p, spanRect, rect, lightColored);
p.end();
QPixmapCache::insert(key, pixmap);
}
painter->drawPixmap(clipRect.topLeft(), pixmap);
} else {
horizontalGradientHelper(painter, spanRect, clipRect, lightColored);
}
}
static void menuGradientHelper(QPainter *p, const QRect &spanRect, const QRect &rect)
{
QLinearGradient grad(spanRect.topLeft(), spanRect.bottomLeft());
QColor menuColor = StyleHelper::mergedColors(StyleHelper::baseColor(), QColor(244, 244, 244), 25);
grad.setColorAt(0, menuColor.lighter(112));
grad.setColorAt(1, menuColor);
p->fillRect(rect, grad);
}
void StyleHelper::drawArrow(QStyle::PrimitiveElement element, QPainter *painter, const QStyleOption *option)
{
// From windowsstyle but modified to enable AA
if (option->rect.width() <= 1 || option->rect.height() <= 1)
return;
QRect r = option->rect;
int size = qMin(r.height(), r.width());
QPixmap pixmap;
QString pixmapName;
pixmapName.sprintf("arrow-%s-%d-%d-%d-%lld",
"$qt_ia",
uint(option->state), element,
size, option->palette.cacheKey());
if (!QPixmapCache::find(pixmapName, pixmap)) {
int border = size/5;
int sqsize = 2*(size/2);
QImage image(sqsize, sqsize, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter imagePainter(&image);
imagePainter.setRenderHint(QPainter::Antialiasing, true);
imagePainter.translate(0.5, 0.5);
QPolygon a;
switch (element) {
case QStyle::PE_IndicatorArrowUp:
a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
break;
case QStyle::PE_IndicatorArrowDown:
a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
break;
case QStyle::PE_IndicatorArrowRight:
a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
break;
case QStyle::PE_IndicatorArrowLeft:
a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
break;
default:
break;
}
int bsx = 0;
int bsy = 0;
if (option->state & QStyle::State_Sunken) {
bsx = qApp->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal);
bsy = qApp->style()->pixelMetric(QStyle::PM_ButtonShiftVertical);
}
QRect bounds = a.boundingRect();
int sx = sqsize / 2 - bounds.center().x() - 1;
int sy = sqsize / 2 - bounds.center().y() - 1;
imagePainter.translate(sx + bsx, sy + bsy);
if (!(option->state & QStyle::State_Enabled)) {
QColor foreGround(150, 150, 150, 150);
imagePainter.setBrush(option->palette.mid().color());
imagePainter.setPen(option->palette.mid().color());
} else {
QColor shadow(0, 0, 0, 100);
imagePainter.translate(0, 1);
imagePainter.setPen(shadow);
imagePainter.setBrush(shadow);
QColor foreGround(255, 255, 255, 210);
imagePainter.drawPolygon(a);
imagePainter.translate(0, -1);
imagePainter.setPen(foreGround);
imagePainter.setBrush(foreGround);
}
imagePainter.drawPolygon(a);
imagePainter.end();
pixmap = QPixmap::fromImage(image);
QPixmapCache::insert(pixmapName, pixmap);
}
int xOffset = r.x() + (r.width() - size)/2;
int yOffset = r.y() + (r.height() - size)/2;
painter->drawPixmap(xOffset, yOffset, pixmap);
}
void StyleHelper::menuGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect)
{
if (StyleHelper::usePixmapCache()) {
QString key;
key.sprintf("mh_menu %d %d %d %d %d",
spanRect.width(), spanRect.height(), clipRect.width(),
clipRect.height(), StyleHelper::baseColor().rgb());
QPixmap pixmap;
if (!QPixmapCache::find(key, pixmap)) {
pixmap = QPixmap(clipRect.size());
QPainter p(&pixmap);
QRect rect = QRect(0, 0, clipRect.width(), clipRect.height());
menuGradientHelper(&p, spanRect, rect);
p.end();
QPixmapCache::insert(key, pixmap);
}
painter->drawPixmap(clipRect.topLeft(), pixmap);
} else {
menuGradientHelper(painter, spanRect, clipRect);
}
}
// Draws a cached pixmap with shadow
void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
QPainter *p, QIcon::Mode iconMode, int radius, const QColor &color, const QPoint &offset)
{
QPixmap cache;
QString pixmapName = QString("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());
if (!QPixmapCache::find(pixmapName, cache)) {
QPixmap px = icon.pixmap(rect.size());
cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
cache.fill(Qt::transparent);
QPainter cachePainter(&cache);
if (iconMode == QIcon::Disabled) {
QImage im = px.toImage().convertToFormat(QImage::Format_ARGB32);
for (int y=0; y<im.height(); ++y) {
QRgb *scanLine = (QRgb*)im.scanLine(y);
for (int x=0; x<im.width(); ++x) {
QRgb pixel = *scanLine;
char intensity = qGray(pixel);
*scanLine = qRgba(intensity, intensity, intensity, qAlpha(pixel));
++scanLine;
}
}
px = QPixmap::fromImage(im);
}
// Draw shadow
QImage tmp(px.size() + QSize(radius * 2, radius * 2 + 1), QImage::Format_ARGB32_Premultiplied);
tmp.fill(Qt::transparent);
QPainter tmpPainter(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
tmpPainter.drawPixmap(QPoint(radius, radius), px);
tmpPainter.end();
// blur the alpha channel
QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
blurred.fill(Qt::transparent);
QPainter blurPainter(&blurred);
qt_blurImage(&blurPainter, tmp, radius, false, true);
blurPainter.end();
tmp = blurred;
// blacken the image...
tmpPainter.begin(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
tmpPainter.fillRect(tmp.rect(), color);
tmpPainter.end();
tmpPainter.begin(&tmp);
tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
tmpPainter.fillRect(tmp.rect(), color);
tmpPainter.end();
// draw the blurred drop shadow...
cachePainter.drawImage(QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp);
// Draw the actual pixmap...
cachePainter.drawPixmap(QPoint(radius, radius) + offset, px);
QPixmapCache::insert(pixmapName, cache);
}
QRect targetRect = cache.rect();
targetRect.moveCenter(rect.center());
p->drawPixmap(targetRect.topLeft() - offset, cache);
}
// Draws a CSS-like border image where the defined borders are not stretched
void StyleHelper::drawCornerImage(const QImage &img, QPainter *painter, QRect rect,
int left, int top, int right, int bottom)
{
QSize size = img.size();
if (top > 0) { //top
painter->drawImage(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), img,
QRect(left, 0, size.width() -right - left, top));
if (left > 0) //top-left
painter->drawImage(QRect(rect.left(), rect.top(), left, top), img,
QRect(0, 0, left, top));
if (right > 0) //top-right
painter->drawImage(QRect(rect.left() + rect.width() - right, rect.top(), right, top), img,
QRect(size.width() - right, 0, right, top));
}
//left
if (left > 0)
painter->drawImage(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), img,
QRect(0, top, left, size.height() - bottom - top));
//center
painter->drawImage(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left,
rect.height() - bottom - top), img,
QRect(left, top, size.width() -right -left,
size.height() - bottom - top));
if (right > 0) //right
painter->drawImage(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), img,
QRect(size.width() - right, top, right, size.height() - bottom - top));
if (bottom > 0) { //bottom
painter->drawImage(QRect(rect.left() +left, rect.top() + rect.height() - bottom,
rect.width() - right - left, bottom), img,
QRect(left, size.height() - bottom,
size.width() - right - left, bottom));
if (left > 0) //bottom-left
painter->drawImage(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), img,
QRect(0, size.height() - bottom, left, bottom));
if (right > 0) //bottom-right
painter->drawImage(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), img,
QRect(size.width() - right, size.height() - bottom, right, bottom));
}
}
} // namespace Utils

97
3rdparty/fancytabwidget/stylehelper.h vendored Normal file
View File

@ -0,0 +1,97 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef STYLEHELPER_H
#define STYLEHELPER_H
#include <QtGui/QColor>
#include <QtGui/QStyle>
QT_BEGIN_NAMESPACE
class QPalette;
class QPainter;
class QRect;
// Note, this is exported but in a private header as qtopengl depends on it.
// We should consider adding this as a public helper function.
void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
QT_END_NAMESPACE
// Helper class holding all custom color values
namespace Utils {
class StyleHelper
{
public:
static const unsigned int DEFAULT_BASE_COLOR = 0x666666;
// Height of the project explorer navigation bar
static int navigationWidgetHeight() { return 24; }
static qreal sidebarFontSize();
static QPalette sidebarFontPalette(const QPalette &original);
// This is our color table, all colors derive from baseColor
static QColor requestedBaseColor() { return m_requestedBaseColor; }
static QColor baseColor(bool lightColored = false);
static QColor panelTextColor(bool lightColored = false);
static QColor highlightColor(bool lightColored = false);
static QColor shadowColor(bool lightColored = false);
static QColor borderColor(bool lightColored = false);
static QColor buttonTextColor() { return QColor(0x4c4c4c); }
static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50);
static QColor sidebarHighlight() { return QColor(255, 255, 255, 40); }
static QColor sidebarShadow() { return QColor(0, 0, 0, 40); }
// Sets the base color and makes sure all top level widgets are updated
static void setBaseColor(const QColor &color);
// Draws a shaded anti-aliased arrow
static void drawArrow(QStyle::PrimitiveElement element, QPainter *painter, const QStyleOption *option);
// Gradients used for panels
static void horizontalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored = false);
static void verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored = false);
static void menuGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect);
static bool usePixmapCache() { return true; }
static void drawIconWithShadow(const QIcon &icon, const QRect &rect, QPainter *p, QIcon::Mode iconMode,
int radius = 3, const QColor &color = QColor(0, 0, 0, 130),
const QPoint &offset = QPoint(1, -2));
static void drawCornerImage(const QImage &img, QPainter *painter, QRect rect,
int left = 0, int top = 0, int right = 0, int bottom = 0);
private:
static QColor m_baseColor;
static QColor m_requestedBaseColor;
};
} // namespace Utils
using Utils::StyleHelper;
#endif // STYLEHELPER_H

View File

@ -92,6 +92,7 @@ include_directories(${GLIB_INCLUDE_DIRS})
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
include_directories(${LIBXML_INCLUDE_DIRS})
include_directories(${LASTFM_INCLUDE_DIRS})
include_directories("3rdparty/fancytabwidget")
include_directories("3rdparty/qsqlite")
include_directories("3rdparty/universalchardet")
@ -213,6 +214,7 @@ if (WIN32)
add_subdirectory(3rdparty/qtwin)
endif (WIN32)
add_subdirectory(3rdparty/universalchardet)
add_subdirectory(3rdparty/fancytabwidget)
add_subdirectory(tests)
add_subdirectory(dist)
add_subdirectory(tools/ultimate_lyrics_parser)

View File

@ -1,7 +1,6 @@
<RCC>
<qresource prefix="/">
<file>mainwindow.css</file>
<file>slimbuttonbox.css</file>
<file>schema.sql</file>
<file>volumeslider-handle_glow.png</file>
<file>volumeslider-handle.png</file>

View File

@ -1,22 +0,0 @@
QPushButton {
border: 1px solid palette(dark);
border-radius: 4px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 palette(button), stop: 1 palette(dark));
padding: 1px 5px 1px 5px;
margin: 0px;
min-width: 60px;
min-height: 18px;
}
QPushButton:hover {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 palette(light), stop: 1 palette(button));
}
QPushButton:checked:!disabled {
border: 1px solid palette(text);
color: palette(highlighted-text);
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 palette(highlight), stop: 1 %darkhighlight);
}

View File

@ -80,6 +80,7 @@ set(SOURCES
library/libraryplaylistitem.cpp
library/libraryquery.cpp
library/libraryview.cpp
library/libraryviewcontainer.cpp
library/librarywatcher.cpp
library/sqlrow.cpp
@ -88,7 +89,6 @@ set(SOURCES
lyrics/lyricprovider.cpp
lyrics/lyricsettings.cpp
lyrics/lyricview.cpp
lyrics/songinfobuttonbox.cpp
lyrics/ultimatelyricsreader.cpp
playlist/playlist.cpp
@ -167,7 +167,6 @@ set(SOURCES
widgets/osdpretty.cpp
widgets/progressitemdelegate.cpp
widgets/sliderwidget.cpp
widgets/slimbuttonbox.cpp
widgets/spinbox.cpp
widgets/stickyslider.cpp
widgets/stretchheaderview.cpp
@ -217,6 +216,7 @@ set(HEADERS
library/libraryfilterwidget.h
library/librarymodel.h
library/libraryview.h
library/libraryviewcontainer.h
library/librarywatcher.h
lyrics/htmlscraper.h
@ -224,7 +224,6 @@ set(HEADERS
lyrics/lyricprovider.h
lyrics/lyricsettings.h
lyrics/lyricview.h
lyrics/songinfobuttonbox.h
lyrics/ultimatelyricsreader.h
playlist/playlist.h
@ -296,7 +295,6 @@ set(HEADERS
widgets/osdpretty.h
widgets/progressitemdelegate.h
widgets/sliderwidget.h
widgets/slimbuttonbox.h
widgets/spinbox.h
widgets/stickyslider.h
widgets/stretchheaderview.h
@ -309,6 +307,7 @@ set(UI
library/groupbydialog.ui
library/libraryconfig.ui
library/libraryfilterwidget.ui
library/libraryviewcontainer.ui
lyrics/lyricsettings.ui
lyrics/lyricview.ui
@ -679,6 +678,7 @@ add_dependencies(clementine_lib pot)
target_link_libraries(clementine_lib
chardet
fancytabwidget
${GOBJECT_LIBRARIES}
${GLIB_LIBRARIES}
${TAGLIB_LIBRARIES}

View File

@ -150,6 +150,11 @@ DeviceView::DeviceView(QWidget* parent)
setItemDelegate(new DeviceItemDelegate(this));
SetExpandOnReset(false);
setAttribute(Qt::WA_MacShowFocusRect, false);
setHeaderHidden(true);
setAllColumnsShowFocus(true);
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragOnly);
setSelectionMode(QAbstractItemView::ExtendedSelection);
}
DeviceView::~DeviceView() {

View File

@ -92,6 +92,11 @@ LibraryView::LibraryView(QWidget* parent)
{
setItemDelegate(new LibraryItemDelegate(this));
setAttribute(Qt::WA_MacShowFocusRect, false);
setHeaderHidden(true);
setAllColumnsShowFocus(true);
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragOnly);
setSelectionMode(QAbstractItemView::ExtendedSelection);
ReloadSettings();
}

View File

@ -0,0 +1,41 @@
/* This file is part of Clementine.
Clementine 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.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "libraryviewcontainer.h"
#include "ui_libraryviewcontainer.h"
LibraryViewContainer::LibraryViewContainer(QWidget* parent)
: QWidget(parent),
ui_(new Ui_LibraryViewContainer)
{
ui_->setupUi(this);
connect(filter(), SIGNAL(UpPressed()), view(), SLOT(UpAndFocus()));
connect(filter(), SIGNAL(DownPressed()), view(), SLOT(DownAndFocus()));
connect(filter(), SIGNAL(ReturnPressed()), view(), SLOT(FilterReturnPressed()));
}
LibraryViewContainer::~LibraryViewContainer() {
delete ui_;
}
LibraryView* LibraryViewContainer::view() const {
return ui_->view;
}
LibraryFilterWidget* LibraryViewContainer::filter() const {
return ui_->filter;
}

View File

@ -14,43 +14,27 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SLIMBUTTONBOX_H
#define SLIMBUTTONBOX_H
#ifndef LIBRARYVIEWCONTAINER_H
#define LIBRARYVIEWCONTAINER_H
#include <QIcon>
#include <QList>
#include <QWidget>
class QPushButton;
class LibraryFilterWidget;
class LibraryView;
class Ui_LibraryViewContainer;
class SlimButtonBox : public QWidget {
class LibraryViewContainer : public QWidget {
Q_OBJECT
public:
SlimButtonBox(QWidget* parent = 0);
LibraryViewContainer(QWidget* parent = 0);
~LibraryViewContainer();
void AddButton(const QString& text, const QIcon& icon = QIcon());
bool IsAnyButtonChecked() const;
void SetCurrentButton(int index);
void SetTabBarBase(bool tab_bar_base);
signals:
void CurrentChanged(int index);
protected:
void changeEvent(QEvent* e);
void paintEvent(QPaintEvent*);
private slots:
void ButtonClicked();
LibraryFilterWidget* filter() const;
LibraryView* view() const;
private:
void ReloadStylesheet();
private:
bool tab_bar_base_;
QList<QPushButton*> buttons_;
Ui_LibraryViewContainer* ui_;
};
#endif // SLIMBUTTONBOX_H
#endif // LIBRARYVIEWCONTAINER_H

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LibraryViewContainer</class>
<widget class="QWidget" name="LibraryViewContainer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="LibraryFilterWidget" name="filter" native="true"/>
</item>
<item>
<widget class="LibraryView" name="view" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LibraryFilterWidget</class>
<extends>QWidget</extends>
<header>library/libraryfilterwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LibraryView</class>
<extends>QWidget</extends>
<header>library/libraryview.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -1,113 +0,0 @@
/* This file is part of Clementine.
Clementine 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.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "lyricview.h"
#include "songinfobuttonbox.h"
#include <QSettings>
#include <QSplitter>
#include <QStackedWidget>
const char* SongInfoButtonBox::kSettingsGroup = "SongInfo";
SongInfoButtonBox::SongInfoButtonBox(QWidget* parent)
: SlimButtonBox(parent),
splitter_(NULL),
stack_(NULL),
lyrics_(NULL)
{
setEnabled(false);
AddButton(tr("Lyrics"));
AddButton(tr("Song info"));
AddButton(tr("Artist info"));
connect(this, SIGNAL(CurrentChanged(int)), SLOT(SetActive(int)));
}
void SongInfoButtonBox::SetSplitter(QSplitter* splitter) {
splitter_ = splitter;
connect(splitter_, SIGNAL(splitterMoved(int,int)), SLOT(SplitterSizeChanged()));
stack_ = new QStackedWidget;
splitter->addWidget(stack_);
stack_->setVisible(false);
lyrics_ = new LyricView;
stack_->addWidget(lyrics_);
stack_->addWidget(new QWidget);
stack_->addWidget(new QWidget);
// Restore settings
QSettings s;
s.beginGroup(kSettingsGroup);
const int current_index = s.value("current_index", -1).toInt();
SetCurrentButton(current_index);
SetActive(current_index);
if (!splitter_->restoreState(s.value("splitter_state").toByteArray())) {
// Set sensible default sizes
splitter_->setSizes(QList<int>() << 850 << 150);
}
}
LyricFetcher* SongInfoButtonBox::lyric_fetcher() const {
return lyrics_->fetcher();
}
void SongInfoButtonBox::SongChanged(const Song& metadata) {
setEnabled(true);
metadata_ = metadata;
if (IsAnyButtonChecked()) {
stack_->show();
UpdateCurrentSong();
}
}
void SongInfoButtonBox::SongFinished() {
metadata_ = Song();
setEnabled(false);
stack_->hide();
}
void SongInfoButtonBox::SetActive(int index) {
if (index == -1) {
stack_->hide();
} else {
if (isEnabled())
stack_->show();
stack_->setCurrentIndex(index);
if (metadata_.is_valid())
UpdateCurrentSong();
}
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("current_index", index);
}
void SongInfoButtonBox::SplitterSizeChanged() {
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("splitter_state", splitter_->saveState());
}
void SongInfoButtonBox::UpdateCurrentSong() {
QMetaObject::invokeMethod(stack_->currentWidget(), "SongChanged",
Q_ARG(Song, metadata_));
}

View File

@ -1,62 +0,0 @@
/* This file is part of Clementine.
Clementine 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.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SONGINFOBUTTONBOX_H
#define SONGINFOBUTTONBOX_H
#include "core/song.h"
#include "widgets/slimbuttonbox.h"
class QSplitter;
class QStackedWidget;
class LyricFetcher;
class LyricView;
class SongInfoButtonBox : public SlimButtonBox {
Q_OBJECT
public:
SongInfoButtonBox(QWidget* parent = 0);
static const char* kSettingsGroup;
void SetSplitter(QSplitter* splitter);
LyricFetcher* lyric_fetcher() const;
LyricView* lyric_view() const { return lyrics_; }
public slots:
void SongChanged(const Song& metadata);
void SongFinished();
private slots:
void SetActive(int index);
void SplitterSizeChanged();
private:
void UpdateCurrentSong();
private:
QSplitter* splitter_;
QStackedWidget* stack_;
LyricView* lyrics_;
Song metadata_;
};
#endif // SONGINFOBUTTONBOX_H

View File

@ -17,7 +17,6 @@
#include "playlistcontainer.h"
#include "playlistmanager.h"
#include "ui_playlistcontainer.h"
#include "lyrics/songinfobuttonbox.h"
#include "playlistparsers/playlistparser.h"
#include "ui/iconloader.h"
#include "widgets/maclineedit.h"
@ -36,7 +35,6 @@ const char* PlaylistContainer::kSettingsGroup = "Playlist";
PlaylistContainer::PlaylistContainer(QWidget *parent)
: QWidget(parent),
ui_(new Ui_PlaylistContainer),
song_info_button_box_(new SongInfoButtonBox(this)),
manager_(NULL),
undo_(NULL),
redo_(NULL),
@ -47,12 +45,6 @@ PlaylistContainer::PlaylistContainer(QWidget *parent)
{
ui_->setupUi(this);
song_info_button_box_->SetSplitter(ui_->splitter);
// Initially add the info button box to the toolbar, but it might get moved
// later when the user adds a playlist.
ui_->toolbar->layout()->addWidget(song_info_button_box_);
no_matches_label_->setText(tr("No matches found. Clear the search box to show the whole playlist again."));
no_matches_label_->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
no_matches_label_->setAttribute(Qt::WA_TransparentForMouseEvents);
@ -82,7 +74,7 @@ PlaylistContainer::PlaylistContainer(QWidget *parent)
ui_->tab_bar->setMovable(true);
connect(tab_bar_animation_, SIGNAL(frameChanged(int)), SLOT(SetTabBarHeight(int)));
ui_->tab_bar_container->setMaximumHeight(0);
ui_->tab_bar->setMaximumHeight(0);
// Connections
connect(ui_->clear, SIGNAL(clicked()), SLOT(ClearFilter()));
@ -237,7 +229,7 @@ void PlaylistContainer::PlaylistAdded(int id, const QString &name) {
// Skip the animation since the window is hidden (eg. if we're still
// loading the UI).
tab_bar_visible_ = true;
SetTabBarHeight(tab_bar_animation_->endFrame());
ui_->tab_bar->setMaximumHeight(tab_bar_animation_->endFrame());
} else {
SetTabBarVisible(true);
}
@ -330,17 +322,10 @@ void PlaylistContainer::SetTabBarVisible(bool visible) {
tab_bar_animation_->setDirection(visible ? QTimeLine::Forward : QTimeLine::Backward);
tab_bar_animation_->start();
if (visible) {
ui_->tab_bar_container->layout()->addWidget(song_info_button_box_);
} else {
ui_->toolbar->layout()->addWidget(song_info_button_box_);
}
song_info_button_box_->SetTabBarBase(visible);
}
void PlaylistContainer::SetTabBarHeight(int height) {
ui_->tab_bar_container->setMaximumHeight(height);
ui_->tab_bar->setMaximumHeight(height);
}
void PlaylistContainer::UpdateFilter() {

View File

@ -26,7 +26,6 @@ class LineEditInterface;
class Playlist;
class PlaylistManager;
class PlaylistView;
class SongInfoButtonBox;
class QTimeLine;
class QLabel;
@ -45,7 +44,6 @@ public:
void SetManager(PlaylistManager* manager);
PlaylistView* view() const;
SongInfoButtonBox* song_info() const { return song_info_button_box_; }
signals:
void TabChanged(int id);
@ -88,7 +86,6 @@ private:
private:
Ui_PlaylistContainer* ui_;
SongInfoButtonBox* song_info_button_box_;
PlaylistManager* manager_;
QAction* undo_;

View File

@ -20,7 +20,7 @@
border-width: 0px 1px 0px 1px;
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
@ -28,26 +28,7 @@
<number>0</number>
</property>
<item>
<widget class="QWidget" name="tab_bar_container" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="PlaylistTabBar" name="tab_bar" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="PlaylistTabBar" name="tab_bar" native="true"/>
</item>
<item>
<widget class="QFrame" name="toolbar">
@ -154,48 +135,37 @@
</widget>
</item>
<item>
<widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<widget class="PlaylistView" name="playlist">
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
<property name="editTriggers">
<set>QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<widget class="PlaylistView" name="playlist">
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="editTriggers">
<set>QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>

View File

@ -15,6 +15,7 @@
*/
#include "mainwindow.h"
#include "stylehelper.h"
#include "ui_mainwindow.h"
#include "core/commandlineoptions.h"
#include "core/database.h"
@ -28,15 +29,17 @@
#include "core/taskmanager.h"
#include "devices/devicemanager.h"
#include "devices/devicestatefiltermodel.h"
#include "devices/deviceview.h"
#include "engines/enginebase.h"
#include "library/groupbydialog.h"
#include "library/library.h"
#include "library/librarybackend.h"
#include "library/libraryconfig.h"
#include "library/librarydirectorymodel.h"
#include "library/library.h"
#include "library/libraryfilterwidget.h"
#include "library/libraryviewcontainer.h"
#include "lyrics/lyricfetcher.h"
#include "lyrics/lyricview.h"
#include "lyrics/songinfobuttonbox.h"
#include "playlist/playlistbackend.h"
#include "playlist/playlist.h"
#include "playlist/playlistmanager.h"
@ -68,6 +71,7 @@
#include "ui/settingsdialog.h"
#include "ui/systemtrayicon.h"
#include "widgets/errordialog.h"
#include "widgets/fileview.h"
#include "widgets/multiloadingindicator.h"
#include "widgets/osd.h"
#include "widgets/trackslider.h"
@ -84,19 +88,22 @@
# include "visualisations/visualisationcontainer.h"
#endif
#include <QFileSystemModel>
#include <QSortFilterProxyModel>
#include <QUndoStack>
#include <QCloseEvent>
#include <QDir>
#include <QFileDialog>
#include <QFileSystemModel>
#include <QLinearGradient>
#include <QMenu>
#include <QMessageBox>
#include <QSettings>
#include <QtDebug>
#include <QCloseEvent>
#include <QSignalMapper>
#include <QFileDialog>
#include <QTimer>
#include <QShortcut>
#include <QSignalMapper>
#include <QSortFilterProxyModel>
#include <QStatusBar>
#include <QtDebug>
#include <QTimer>
#include <QUndoStack>
#include <cmath>
@ -130,6 +137,11 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
library_(NULL),
global_shortcuts_(new GlobalShortcuts(this)),
devices_(NULL),
library_view_(new LibraryViewContainer(this)),
file_view_(new FileView(this)),
radio_view_(new RadioViewContainer(this)),
device_view_(new DeviceView(this)),
lyric_view_(new LyricView(this)),
settings_dialog_(NULL),
cover_manager_(NULL),
equalizer_(new Equalizer),
@ -166,14 +178,21 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
ui_->multi_loading_indicator->SetTaskManager(task_manager_);
ui_->volume->setValue(player_->GetVolume());
// Add tabs to the fancy tab widget
AddFancyTab(library_view_, IconLoader::Load("folder-sound"), tr("Library"));
AddFancyTab(file_view_, IconLoader::Load("document-open"), tr("Files"));
AddFancyTab(radio_view_, QIcon(":last.fm/icon_radio.png"), tr("Internet"));
AddFancyTab(device_view_, IconLoader::Load("multimedia-player-ipod-mini-blue"), tr("Devices"));
AddFancyTab(lyric_view_, IconLoader::Load("view-media-lyrics"), tr("Lyrics"));
AddFancyTab(new QWidget, IconLoader::Load("view-media-lyrics"), tr("Song info"));
AddFancyTab(new QWidget, IconLoader::Load("view-media-lyrics"), tr("Artist info"));
ui_->tabs->statusBar()->hide();
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
track_position_timer_->setInterval(1000);
connect(track_position_timer_, SIGNAL(timeout()), SLOT(UpdateTrackPosition()));
#ifdef Q_OS_MAC
// For some reason this makes the tabs go a funny colour on mac
ui_->tabs->setDocumentMode(false);
#endif
// Start initialising the player
player_->Init();
@ -193,15 +212,15 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
ui_->playlist->SetManager(playlists_);
ui_->library_view->setModel(library_sort_model_);
ui_->library_view->SetLibrary(library_->model());
ui_->library_view->SetTaskManager(task_manager_);
ui_->library_view->SetDeviceManager(devices_);
library_view_->view()->setModel(library_sort_model_);
library_view_->view()->SetLibrary(library_->model());
library_view_->view()->SetTaskManager(task_manager_);
library_view_->view()->SetDeviceManager(devices_);
ui_->radio_view->SetModel(radio_model_);
radio_view_->SetModel(radio_model_);
ui_->devices_view->SetDeviceManager(devices_);
ui_->devices_view->SetLibrary(library_->model());
device_view_->SetDeviceManager(devices_);
device_view_->SetLibrary(library_->model());
organise_dialog_->SetDestinationModel(library_->model()->directory_model());
@ -235,14 +254,14 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
ui_->action_rain->setIcon(IconLoader::Load("weather-showers-scattered"));
// File view connections
connect(ui_->file_view, SIGNAL(AddToPlaylist(QList<QUrl>)), SLOT(AddFilesToPlaylist(QList<QUrl>)));
connect(ui_->file_view, SIGNAL(Load(QList<QUrl>)), SLOT(LoadFilesToPlaylist(QList<QUrl>)));
connect(ui_->file_view, SIGNAL(DoubleClicked(QList<QUrl>)), SLOT(FilesDoubleClicked(QList<QUrl>)));
connect(ui_->file_view, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
connect(ui_->file_view, SIGNAL(CopyToLibrary(QList<QUrl>)), SLOT(CopyFilesToLibrary(QList<QUrl>)));
connect(ui_->file_view, SIGNAL(MoveToLibrary(QList<QUrl>)), SLOT(MoveFilesToLibrary(QList<QUrl>)));
connect(ui_->file_view, SIGNAL(CopyToDevice(QList<QUrl>)), SLOT(CopyFilesToDevice(QList<QUrl>)));
ui_->file_view->SetTaskManager(task_manager_);
connect(file_view_, SIGNAL(AddToPlaylist(QList<QUrl>)), SLOT(AddFilesToPlaylist(QList<QUrl>)));
connect(file_view_, SIGNAL(Load(QList<QUrl>)), SLOT(LoadFilesToPlaylist(QList<QUrl>)));
connect(file_view_, SIGNAL(DoubleClicked(QList<QUrl>)), SLOT(FilesDoubleClicked(QList<QUrl>)));
connect(file_view_, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
connect(file_view_, SIGNAL(CopyToLibrary(QList<QUrl>)), SLOT(CopyFilesToLibrary(QList<QUrl>)));
connect(file_view_, SIGNAL(MoveToLibrary(QList<QUrl>)), SLOT(MoveFilesToLibrary(QList<QUrl>)));
connect(file_view_, SIGNAL(CopyToDevice(QList<QUrl>)), SLOT(CopyFilesToDevice(QList<QUrl>)));
file_view_->SetTaskManager(task_manager_);
// Action connections
connect(ui_->action_next_track, SIGNAL(triggered()), player_, SLOT(Next()));
@ -325,14 +344,12 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(player_, SIGNAL(Paused()), osd_, SLOT(Paused()));
connect(player_, SIGNAL(Stopped()), osd_, SLOT(Stopped()));
connect(player_, SIGNAL(PlaylistFinished()), osd_, SLOT(PlaylistFinished()));
connect(player_, SIGNAL(Stopped()), ui_->playlist->song_info(), SLOT(SongFinished()));
connect(player_, SIGNAL(PlaylistFinished()), ui_->playlist->song_info(), SLOT(SongFinished()));
connect(player_, SIGNAL(VolumeChanged(int)), osd_, SLOT(VolumeChanged(int)));
connect(player_, SIGNAL(VolumeChanged(int)), ui_->volume, SLOT(setValue(int)));
connect(player_, SIGNAL(ForceShowOSD(Song)), SLOT(ForceShowOSD(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), osd_, SLOT(SongChanged(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), player_, SLOT(CurrentMetadataChanged(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), ui_->playlist->song_info(), SLOT(SongChanged(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), lyric_view_, SLOT(SongChanged(Song)));
connect(playlists_, SIGNAL(PlaylistChanged()), player_, SLOT(PlaylistChanged()));
connect(playlists_, SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex)));
connect(playlists_, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
@ -349,31 +366,28 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(database_->Worker().get(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
// Library connections
connect(ui_->library_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryItemDoubleClicked(QModelIndex)));
connect(ui_->library_view, SIGNAL(Load(QModelIndexList)), SLOT(LoadLibraryItemToPlaylist(QModelIndexList)));
connect(ui_->library_view, SIGNAL(AddToPlaylist(QModelIndexList)), SLOT(AddLibraryItemToPlaylist(QModelIndexList)));
connect(ui_->library_view, SIGNAL(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
connect(library_->model(), SIGNAL(TotalSongCountUpdated(int)), ui_->library_view, SLOT(TotalSongCountUpdated(int)));
connect(library_view_->view(), SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryItemDoubleClicked(QModelIndex)));
connect(library_view_->view(), SIGNAL(Load(QModelIndexList)), SLOT(LoadLibraryItemToPlaylist(QModelIndexList)));
connect(library_view_->view(), SIGNAL(AddToPlaylist(QModelIndexList)), SLOT(AddLibraryItemToPlaylist(QModelIndexList)));
connect(library_view_->view(), SIGNAL(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
connect(library_->model(), SIGNAL(TotalSongCountUpdated(int)), library_view_->view(), SLOT(TotalSongCountUpdated(int)));
connect(task_manager_, SIGNAL(PauseLibraryWatchers()), library_, SLOT(PauseWatcher()));
connect(task_manager_, SIGNAL(ResumeLibraryWatchers()), library_, SLOT(ResumeWatcher()));
// Devices connections
connect(devices_, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
connect(ui_->devices_view, SIGNAL(Load(SongList)), SLOT(LoadDeviceSongsToPlaylist(SongList)));
connect(ui_->devices_view, SIGNAL(AddToPlaylist(SongList)), SLOT(AddDeviceSongsToPlaylist(SongList)));
connect(ui_->devices_view, SIGNAL(DoubleClicked(SongList)), SLOT(DeviceSongsDoubleClicked(SongList)));
connect(device_view_, SIGNAL(Load(SongList)), SLOT(LoadDeviceSongsToPlaylist(SongList)));
connect(device_view_, SIGNAL(AddToPlaylist(SongList)), SLOT(AddDeviceSongsToPlaylist(SongList)));
connect(device_view_, SIGNAL(DoubleClicked(SongList)), SLOT(DeviceSongsDoubleClicked(SongList)));
// Library filter widget
QAction* library_config_action = new QAction(
IconLoader::Load("configure"), tr("Configure library..."), this);
connect(library_config_action, SIGNAL(triggered()), SLOT(ShowLibraryConfig()));
ui_->library_filter->SetSettingsGroup(kSettingsGroup);
ui_->library_filter->SetLibraryModel(library_->model());
ui_->library_filter->AddMenuAction(library_config_action);
connect(ui_->library_filter, SIGNAL(UpPressed()), ui_->library_view, SLOT(UpAndFocus()));
connect(ui_->library_filter, SIGNAL(DownPressed()), ui_->library_view, SLOT(DownAndFocus()));
connect(ui_->library_filter, SIGNAL(ReturnPressed()), ui_->library_view, SLOT(FilterReturnPressed()));
library_view_->filter()->SetSettingsGroup(kSettingsGroup);
library_view_->filter()->SetLibraryModel(library_->model());
library_view_->filter()->AddMenuAction(library_config_action);
// Playlist menu
playlist_play_pause_ = playlist_menu_->addAction(tr("Play"), this, SLOT(PlaylistPlay()));
@ -421,7 +435,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(radio_model_, SIGNAL(AddItemsToPlaylist(PlaylistItemList)), SLOT(InsertRadioItems(PlaylistItemList)));
connect(radio_model_->GetLastFMService(), SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChanged(bool)));
connect(radio_model_->GetLastFMService(), SIGNAL(ButtonVisibilityChanged(bool)), SLOT(LastFMButtonVisibilityChanged(bool)));
connect(ui_->radio_view->tree(), SIGNAL(doubleClicked(QModelIndex)), SLOT(RadioDoubleClick(QModelIndex)));
connect(radio_view_->tree(), SIGNAL(doubleClicked(QModelIndex)), SLOT(RadioDoubleClick(QModelIndex)));
connect(radio_model_->Service<MagnatuneService>(), SIGNAL(DownloadFinished(QStringList)), osd_, SLOT(MagnatuneDownloadFinished(QStringList)));
LastFMButtonVisibilityChanged(radio_model_->GetLastFMService()->AreButtonsVisible());
@ -474,7 +488,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(global_shortcuts_, SIGNAL(ShowOSD()), player_, SLOT(ShowOSD()));
// Lyrics
ui_->playlist->song_info()->lyric_view()->set_network(network);
lyric_view_->set_network(network);
// Analyzer
ui_->analyzer->SetEngine(player_->GetEngine());
@ -521,7 +535,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
ui_->splitter->setSizes(QList<int>() << 200 << width() - 200);
}
ui_->tabs->setCurrentIndex(settings_.value("current_tab", 0).toInt());
ui_->file_view->SetPath(settings_.value("file_path", QDir::homePath()).toString());
file_view_->SetPath(settings_.value("file_path", QDir::homePath()).toString());
ReloadSettings();
@ -1476,17 +1490,17 @@ void MainWindow::EnsureSettingsDialogCreated() {
#endif
settings_dialog_->SetGlobalShortcutManager(global_shortcuts_);
settings_dialog_->SetLyricFetcher(ui_->playlist->song_info()->lyric_fetcher());
settings_dialog_->SetLyricFetcher(lyric_view_->fetcher());
// Settings
connect(settings_dialog_.get(), SIGNAL(accepted()), SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), library_, SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), player_, SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), osd_, SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), ui_->library_view, SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), library_view_, SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), player_->GetEngine(), SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), ui_->playlist->view(), SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), ui_->playlist->song_info()->lyric_fetcher(), SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(accepted()), lyric_view_->fetcher(), SLOT(ReloadSettings()));
#ifdef ENABLE_WIIMOTEDEV
connect(settings_dialog_.get(), SIGNAL(accepted()), wiimotedev_shortcuts_.get(), SLOT(ReloadSettings()));
connect(settings_dialog_.get(), SIGNAL(SetWiimotedevInterfaceActived(bool)), wiimotedev_shortcuts_.get(), SLOT(SetWiimotedevInterfaceActived(bool)));
@ -1562,3 +1576,9 @@ void MainWindow::ShowVisualisations() {
visualisation_->show();
#endif // ENABLE_VISUALISATIONS
}
void MainWindow::AddFancyTab(QWidget* widget, const QIcon& icon, const QString& label) {
const int i = ui_->tabs->count();
ui_->tabs->insertTab(i, widget, icon, label);
ui_->tabs->setTabEnabled(i, true);
}

View File

@ -36,12 +36,16 @@ class AlbumCoverManager;
class CommandlineOptions;
class Database;
class DeviceManager;
class DeviceView;
class EditTagDialog;
class Equalizer;
class ErrorDialog;
class FileView;
class GlobalShortcuts;
class GroupByDialog;
class Library;
class LibraryViewContainer;
class LyricView;
class MultiLoadingIndicator;
class NetworkAccessManager;
class OrganiseDialog;
@ -53,6 +57,7 @@ class PlaylistParser;
class QueueManager;
class RadioItem;
class RadioModel;
class RadioViewContainer;
class Song;
class SystemTrayIcon;
class TaskManager;
@ -190,6 +195,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
void AddLibrarySongsToPlaylist(bool clear_first, const SongList& songs);
void AddDeviceSongsToPlaylist(bool clear_first, const SongList& songs);
void AddUrls(bool play_now, const QList<QUrl>& urls);
void AddFancyTab(QWidget* widget, const QIcon& icon, const QString& label);
private:
Ui_MainWindow* ui_;
@ -212,6 +218,12 @@ class MainWindow : public QMainWindow, public PlatformInterface {
DeviceManager* devices_;
LibraryViewContainer* library_view_;
FileView* file_view_;
RadioViewContainer* radio_view_;
DeviceView* device_view_;
LyricView* lyric_view_;
boost::scoped_ptr<SettingsDialog> settings_dialog_;
boost::scoped_ptr<AddStreamDialog> add_stream_dialog_;
boost::scoped_ptr<AlbumCoverManager> cover_manager_;

View File

@ -36,131 +36,7 @@
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabs">
<property name="tabPosition">
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="usesScrollButtons">
<bool>true</bool>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
<property name="tabsClosable">
<bool>false</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="library_tab">
<attribute name="title">
<string>Library</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="LibraryFilterWidget" name="library_filter" native="true"/>
</item>
<item>
<widget class="LibraryView" name="library_view">
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="file_tab">
<attribute name="title">
<string>Files</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="FileView" name="file_view" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="radio_tab">
<attribute name="title">
<string>Internet</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="RadioViewContainer" name="radio_view" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="devices_tab">
<attribute name="title">
<string>Devices</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="DeviceView" name="devices_view">
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="FancyTabWidget" name="tabs" />
</item>
<item>
<widget class="NowPlayingWidget" name="now_playing" native="true"/>
@ -860,35 +736,12 @@
<extends>QSlider</extends>
<header>widgets/sliderwidget.h</header>
</customwidget>
<customwidget>
<class>LibraryView</class>
<extends>QTreeView</extends>
<header>library/libraryview.h</header>
</customwidget>
<customwidget>
<class>FileView</class>
<extends>QWidget</extends>
<header>widgets/fileview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>AnalyzerContainer</class>
<extends>QWidget</extends>
<header>analyzers/analyzercontainer.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LibraryFilterWidget</class>
<extends>QWidget</extends>
<header>library/libraryfilterwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RadioViewContainer</class>
<extends>QWidget</extends>
<header>radio/radioviewcontainer.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>PlaylistContainer</class>
<extends>QWidget</extends>
@ -920,9 +773,16 @@
<container>1</container>
</customwidget>
<customwidget>
<class>DeviceView</class>
<extends>QTreeView</extends>
<header>devices/deviceview.h</header>
<class>FancyTabWidget</class>
<extends>QWidget</extends>
<header>fancytabwidget.h</header>
<container>0</container>
</customwidget>
<customwidget>
<class>LyricView</class>
<extends>QWidget</extends>
<header>lyrics/lyricview.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>

View File

@ -1,111 +0,0 @@
/* This file is part of Clementine.
Clementine 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.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "slimbuttonbox.h"
#include <QEvent>
#include <QFile>
#include <QHBoxLayout>
#include <QPushButton>
#include <QStylePainter>
#include <QStyleOptionTabBarBaseV2>
SlimButtonBox::SlimButtonBox(QWidget* parent)
: QWidget(parent),
tab_bar_base_(false)
{
setLayout(new QHBoxLayout);
layout()->setSpacing(3);
layout()->setContentsMargins(6, 0, 0, 0);
ReloadStylesheet();
}
void SlimButtonBox::AddButton(const QString& text, const QIcon& icon) {
QPushButton* button = new QPushButton(icon, text, this);
button->setCheckable(true);
connect(button, SIGNAL(clicked()), SLOT(ButtonClicked()));
layout()->addWidget(button);
buttons_ << button;
}
void SlimButtonBox::ButtonClicked() {
QPushButton* button = qobject_cast<QPushButton*>(sender());
if (!button)
return;
if (!button->isChecked()) {
emit CurrentChanged(-1);
} else {
// Uncheck all the other buttons as well. We can't use auto exclusive,
// because we want to allow no buttons being pressed.
foreach (QPushButton* other_button, buttons_) {
if (other_button != button)
other_button->setChecked(false);
}
emit CurrentChanged(buttons_.indexOf(button));
}
}
void SlimButtonBox::changeEvent(QEvent* e) {
if (e->type() == QEvent::PaletteChange) {
ReloadStylesheet();
}
}
void SlimButtonBox::paintEvent(QPaintEvent*) {
QStylePainter p(this);
if (tab_bar_base_) {
QStyleOptionTabBarBaseV2 opt;
opt.initFrom(this);
opt.documentMode = true;
opt.shape = QTabBar::RoundedSouth;
p.drawPrimitive(QStyle::PE_FrameTabBarBase, opt);
}
}
void SlimButtonBox::ReloadStylesheet() {
QFile resource(":/slimbuttonbox.css");
resource.open(QIODevice::ReadOnly);
QString css = QString::fromLatin1(resource.readAll());
css.replace("%darkhighlight", palette().color(QPalette::Highlight).darker(150).name());
setStyleSheet(css);
}
void SlimButtonBox::SetTabBarBase(bool tab_bar_base) {
tab_bar_base_ = tab_bar_base;
update();
}
bool SlimButtonBox::IsAnyButtonChecked() const {
foreach (QPushButton* button, buttons_) {
if (button->isChecked())
return true;
}
return false;
}
void SlimButtonBox::SetCurrentButton(int index) {
for (int i=0 ; i<buttons_.count() ; ++i) {
buttons_[i]->setChecked(i == index);
}
}