Try the next UI experiment - wide buttons down the side like Qt Creator
This commit is contained in:
parent
730708f0ca
commit
56d72a00bf
|
@ -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}
|
||||||
|
)
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -92,6 +92,7 @@ include_directories(${GLIB_INCLUDE_DIRS})
|
||||||
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
|
||||||
include_directories(${LIBXML_INCLUDE_DIRS})
|
include_directories(${LIBXML_INCLUDE_DIRS})
|
||||||
include_directories(${LASTFM_INCLUDE_DIRS})
|
include_directories(${LASTFM_INCLUDE_DIRS})
|
||||||
|
include_directories("3rdparty/fancytabwidget")
|
||||||
include_directories("3rdparty/qsqlite")
|
include_directories("3rdparty/qsqlite")
|
||||||
include_directories("3rdparty/universalchardet")
|
include_directories("3rdparty/universalchardet")
|
||||||
|
|
||||||
|
@ -213,6 +214,7 @@ if (WIN32)
|
||||||
add_subdirectory(3rdparty/qtwin)
|
add_subdirectory(3rdparty/qtwin)
|
||||||
endif (WIN32)
|
endif (WIN32)
|
||||||
add_subdirectory(3rdparty/universalchardet)
|
add_subdirectory(3rdparty/universalchardet)
|
||||||
|
add_subdirectory(3rdparty/fancytabwidget)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
add_subdirectory(dist)
|
add_subdirectory(dist)
|
||||||
add_subdirectory(tools/ultimate_lyrics_parser)
|
add_subdirectory(tools/ultimate_lyrics_parser)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file>mainwindow.css</file>
|
<file>mainwindow.css</file>
|
||||||
<file>slimbuttonbox.css</file>
|
|
||||||
<file>schema.sql</file>
|
<file>schema.sql</file>
|
||||||
<file>volumeslider-handle_glow.png</file>
|
<file>volumeslider-handle_glow.png</file>
|
||||||
<file>volumeslider-handle.png</file>
|
<file>volumeslider-handle.png</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);
|
|
||||||
}
|
|
|
@ -80,6 +80,7 @@ set(SOURCES
|
||||||
library/libraryplaylistitem.cpp
|
library/libraryplaylistitem.cpp
|
||||||
library/libraryquery.cpp
|
library/libraryquery.cpp
|
||||||
library/libraryview.cpp
|
library/libraryview.cpp
|
||||||
|
library/libraryviewcontainer.cpp
|
||||||
library/librarywatcher.cpp
|
library/librarywatcher.cpp
|
||||||
library/sqlrow.cpp
|
library/sqlrow.cpp
|
||||||
|
|
||||||
|
@ -88,7 +89,6 @@ set(SOURCES
|
||||||
lyrics/lyricprovider.cpp
|
lyrics/lyricprovider.cpp
|
||||||
lyrics/lyricsettings.cpp
|
lyrics/lyricsettings.cpp
|
||||||
lyrics/lyricview.cpp
|
lyrics/lyricview.cpp
|
||||||
lyrics/songinfobuttonbox.cpp
|
|
||||||
lyrics/ultimatelyricsreader.cpp
|
lyrics/ultimatelyricsreader.cpp
|
||||||
|
|
||||||
playlist/playlist.cpp
|
playlist/playlist.cpp
|
||||||
|
@ -167,7 +167,6 @@ set(SOURCES
|
||||||
widgets/osdpretty.cpp
|
widgets/osdpretty.cpp
|
||||||
widgets/progressitemdelegate.cpp
|
widgets/progressitemdelegate.cpp
|
||||||
widgets/sliderwidget.cpp
|
widgets/sliderwidget.cpp
|
||||||
widgets/slimbuttonbox.cpp
|
|
||||||
widgets/spinbox.cpp
|
widgets/spinbox.cpp
|
||||||
widgets/stickyslider.cpp
|
widgets/stickyslider.cpp
|
||||||
widgets/stretchheaderview.cpp
|
widgets/stretchheaderview.cpp
|
||||||
|
@ -217,6 +216,7 @@ set(HEADERS
|
||||||
library/libraryfilterwidget.h
|
library/libraryfilterwidget.h
|
||||||
library/librarymodel.h
|
library/librarymodel.h
|
||||||
library/libraryview.h
|
library/libraryview.h
|
||||||
|
library/libraryviewcontainer.h
|
||||||
library/librarywatcher.h
|
library/librarywatcher.h
|
||||||
|
|
||||||
lyrics/htmlscraper.h
|
lyrics/htmlscraper.h
|
||||||
|
@ -224,7 +224,6 @@ set(HEADERS
|
||||||
lyrics/lyricprovider.h
|
lyrics/lyricprovider.h
|
||||||
lyrics/lyricsettings.h
|
lyrics/lyricsettings.h
|
||||||
lyrics/lyricview.h
|
lyrics/lyricview.h
|
||||||
lyrics/songinfobuttonbox.h
|
|
||||||
lyrics/ultimatelyricsreader.h
|
lyrics/ultimatelyricsreader.h
|
||||||
|
|
||||||
playlist/playlist.h
|
playlist/playlist.h
|
||||||
|
@ -296,7 +295,6 @@ set(HEADERS
|
||||||
widgets/osdpretty.h
|
widgets/osdpretty.h
|
||||||
widgets/progressitemdelegate.h
|
widgets/progressitemdelegate.h
|
||||||
widgets/sliderwidget.h
|
widgets/sliderwidget.h
|
||||||
widgets/slimbuttonbox.h
|
|
||||||
widgets/spinbox.h
|
widgets/spinbox.h
|
||||||
widgets/stickyslider.h
|
widgets/stickyslider.h
|
||||||
widgets/stretchheaderview.h
|
widgets/stretchheaderview.h
|
||||||
|
@ -309,6 +307,7 @@ set(UI
|
||||||
library/groupbydialog.ui
|
library/groupbydialog.ui
|
||||||
library/libraryconfig.ui
|
library/libraryconfig.ui
|
||||||
library/libraryfilterwidget.ui
|
library/libraryfilterwidget.ui
|
||||||
|
library/libraryviewcontainer.ui
|
||||||
|
|
||||||
lyrics/lyricsettings.ui
|
lyrics/lyricsettings.ui
|
||||||
lyrics/lyricview.ui
|
lyrics/lyricview.ui
|
||||||
|
@ -679,6 +678,7 @@ add_dependencies(clementine_lib pot)
|
||||||
|
|
||||||
target_link_libraries(clementine_lib
|
target_link_libraries(clementine_lib
|
||||||
chardet
|
chardet
|
||||||
|
fancytabwidget
|
||||||
${GOBJECT_LIBRARIES}
|
${GOBJECT_LIBRARIES}
|
||||||
${GLIB_LIBRARIES}
|
${GLIB_LIBRARIES}
|
||||||
${TAGLIB_LIBRARIES}
|
${TAGLIB_LIBRARIES}
|
||||||
|
|
|
@ -150,6 +150,11 @@ DeviceView::DeviceView(QWidget* parent)
|
||||||
setItemDelegate(new DeviceItemDelegate(this));
|
setItemDelegate(new DeviceItemDelegate(this));
|
||||||
SetExpandOnReset(false);
|
SetExpandOnReset(false);
|
||||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
|
setHeaderHidden(true);
|
||||||
|
setAllColumnsShowFocus(true);
|
||||||
|
setDragEnabled(true);
|
||||||
|
setDragDropMode(QAbstractItemView::DragOnly);
|
||||||
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceView::~DeviceView() {
|
DeviceView::~DeviceView() {
|
||||||
|
|
|
@ -92,6 +92,11 @@ LibraryView::LibraryView(QWidget* parent)
|
||||||
{
|
{
|
||||||
setItemDelegate(new LibraryItemDelegate(this));
|
setItemDelegate(new LibraryItemDelegate(this));
|
||||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
|
setHeaderHidden(true);
|
||||||
|
setAllColumnsShowFocus(true);
|
||||||
|
setDragEnabled(true);
|
||||||
|
setDragDropMode(QAbstractItemView::DragOnly);
|
||||||
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
ReloadSettings();
|
ReloadSettings();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -14,43 +14,27 @@
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SLIMBUTTONBOX_H
|
#ifndef LIBRARYVIEWCONTAINER_H
|
||||||
#define SLIMBUTTONBOX_H
|
#define LIBRARYVIEWCONTAINER_H
|
||||||
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QList>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QPushButton;
|
class LibraryFilterWidget;
|
||||||
|
class LibraryView;
|
||||||
|
class Ui_LibraryViewContainer;
|
||||||
|
|
||||||
class SlimButtonBox : public QWidget {
|
class LibraryViewContainer : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SlimButtonBox(QWidget* parent = 0);
|
LibraryViewContainer(QWidget* parent = 0);
|
||||||
|
~LibraryViewContainer();
|
||||||
|
|
||||||
void AddButton(const QString& text, const QIcon& icon = QIcon());
|
LibraryFilterWidget* filter() const;
|
||||||
bool IsAnyButtonChecked() const;
|
LibraryView* view() 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();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ReloadStylesheet();
|
Ui_LibraryViewContainer* ui_;
|
||||||
|
|
||||||
private:
|
|
||||||
bool tab_bar_base_;
|
|
||||||
QList<QPushButton*> buttons_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SLIMBUTTONBOX_H
|
#endif // LIBRARYVIEWCONTAINER_H
|
|
@ -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>
|
|
@ -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_));
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "playlistcontainer.h"
|
#include "playlistcontainer.h"
|
||||||
#include "playlistmanager.h"
|
#include "playlistmanager.h"
|
||||||
#include "ui_playlistcontainer.h"
|
#include "ui_playlistcontainer.h"
|
||||||
#include "lyrics/songinfobuttonbox.h"
|
|
||||||
#include "playlistparsers/playlistparser.h"
|
#include "playlistparsers/playlistparser.h"
|
||||||
#include "ui/iconloader.h"
|
#include "ui/iconloader.h"
|
||||||
#include "widgets/maclineedit.h"
|
#include "widgets/maclineedit.h"
|
||||||
|
@ -36,7 +35,6 @@ const char* PlaylistContainer::kSettingsGroup = "Playlist";
|
||||||
PlaylistContainer::PlaylistContainer(QWidget *parent)
|
PlaylistContainer::PlaylistContainer(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
ui_(new Ui_PlaylistContainer),
|
ui_(new Ui_PlaylistContainer),
|
||||||
song_info_button_box_(new SongInfoButtonBox(this)),
|
|
||||||
manager_(NULL),
|
manager_(NULL),
|
||||||
undo_(NULL),
|
undo_(NULL),
|
||||||
redo_(NULL),
|
redo_(NULL),
|
||||||
|
@ -47,12 +45,6 @@ PlaylistContainer::PlaylistContainer(QWidget *parent)
|
||||||
{
|
{
|
||||||
ui_->setupUi(this);
|
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_->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_->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||||
no_matches_label_->setAttribute(Qt::WA_TransparentForMouseEvents);
|
no_matches_label_->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
@ -82,7 +74,7 @@ PlaylistContainer::PlaylistContainer(QWidget *parent)
|
||||||
ui_->tab_bar->setMovable(true);
|
ui_->tab_bar->setMovable(true);
|
||||||
|
|
||||||
connect(tab_bar_animation_, SIGNAL(frameChanged(int)), SLOT(SetTabBarHeight(int)));
|
connect(tab_bar_animation_, SIGNAL(frameChanged(int)), SLOT(SetTabBarHeight(int)));
|
||||||
ui_->tab_bar_container->setMaximumHeight(0);
|
ui_->tab_bar->setMaximumHeight(0);
|
||||||
|
|
||||||
// Connections
|
// Connections
|
||||||
connect(ui_->clear, SIGNAL(clicked()), SLOT(ClearFilter()));
|
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
|
// Skip the animation since the window is hidden (eg. if we're still
|
||||||
// loading the UI).
|
// loading the UI).
|
||||||
tab_bar_visible_ = true;
|
tab_bar_visible_ = true;
|
||||||
SetTabBarHeight(tab_bar_animation_->endFrame());
|
ui_->tab_bar->setMaximumHeight(tab_bar_animation_->endFrame());
|
||||||
} else {
|
} else {
|
||||||
SetTabBarVisible(true);
|
SetTabBarVisible(true);
|
||||||
}
|
}
|
||||||
|
@ -330,17 +322,10 @@ void PlaylistContainer::SetTabBarVisible(bool visible) {
|
||||||
|
|
||||||
tab_bar_animation_->setDirection(visible ? QTimeLine::Forward : QTimeLine::Backward);
|
tab_bar_animation_->setDirection(visible ? QTimeLine::Forward : QTimeLine::Backward);
|
||||||
tab_bar_animation_->start();
|
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) {
|
void PlaylistContainer::SetTabBarHeight(int height) {
|
||||||
ui_->tab_bar_container->setMaximumHeight(height);
|
ui_->tab_bar->setMaximumHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistContainer::UpdateFilter() {
|
void PlaylistContainer::UpdateFilter() {
|
||||||
|
|
|
@ -26,7 +26,6 @@ class LineEditInterface;
|
||||||
class Playlist;
|
class Playlist;
|
||||||
class PlaylistManager;
|
class PlaylistManager;
|
||||||
class PlaylistView;
|
class PlaylistView;
|
||||||
class SongInfoButtonBox;
|
|
||||||
|
|
||||||
class QTimeLine;
|
class QTimeLine;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
@ -45,7 +44,6 @@ public:
|
||||||
void SetManager(PlaylistManager* manager);
|
void SetManager(PlaylistManager* manager);
|
||||||
|
|
||||||
PlaylistView* view() const;
|
PlaylistView* view() const;
|
||||||
SongInfoButtonBox* song_info() const { return song_info_button_box_; }
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void TabChanged(int id);
|
void TabChanged(int id);
|
||||||
|
@ -88,7 +86,6 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui_PlaylistContainer* ui_;
|
Ui_PlaylistContainer* ui_;
|
||||||
SongInfoButtonBox* song_info_button_box_;
|
|
||||||
|
|
||||||
PlaylistManager* manager_;
|
PlaylistManager* manager_;
|
||||||
QAction* undo_;
|
QAction* undo_;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
border-width: 0px 1px 0px 1px;
|
border-width: 0px 1px 0px 1px;
|
||||||
}</string>
|
}</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -28,26 +28,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="tab_bar_container" native="true">
|
<widget class="PlaylistTabBar" name="tab_bar" 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>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="toolbar">
|
<widget class="QFrame" name="toolbar">
|
||||||
|
@ -154,48 +135,37 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter">
|
<widget class="PlaylistView" name="playlist">
|
||||||
<property name="sizePolicy">
|
<property name="acceptDrops">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<bool>true</bool>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="editTriggers">
|
||||||
<enum>Qt::Horizontal</enum>
|
<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>
|
</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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "stylehelper.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include "core/commandlineoptions.h"
|
#include "core/commandlineoptions.h"
|
||||||
#include "core/database.h"
|
#include "core/database.h"
|
||||||
|
@ -28,15 +29,17 @@
|
||||||
#include "core/taskmanager.h"
|
#include "core/taskmanager.h"
|
||||||
#include "devices/devicemanager.h"
|
#include "devices/devicemanager.h"
|
||||||
#include "devices/devicestatefiltermodel.h"
|
#include "devices/devicestatefiltermodel.h"
|
||||||
|
#include "devices/deviceview.h"
|
||||||
#include "engines/enginebase.h"
|
#include "engines/enginebase.h"
|
||||||
#include "library/groupbydialog.h"
|
#include "library/groupbydialog.h"
|
||||||
|
#include "library/library.h"
|
||||||
#include "library/librarybackend.h"
|
#include "library/librarybackend.h"
|
||||||
#include "library/libraryconfig.h"
|
#include "library/libraryconfig.h"
|
||||||
#include "library/librarydirectorymodel.h"
|
#include "library/librarydirectorymodel.h"
|
||||||
#include "library/library.h"
|
#include "library/libraryfilterwidget.h"
|
||||||
|
#include "library/libraryviewcontainer.h"
|
||||||
#include "lyrics/lyricfetcher.h"
|
#include "lyrics/lyricfetcher.h"
|
||||||
#include "lyrics/lyricview.h"
|
#include "lyrics/lyricview.h"
|
||||||
#include "lyrics/songinfobuttonbox.h"
|
|
||||||
#include "playlist/playlistbackend.h"
|
#include "playlist/playlistbackend.h"
|
||||||
#include "playlist/playlist.h"
|
#include "playlist/playlist.h"
|
||||||
#include "playlist/playlistmanager.h"
|
#include "playlist/playlistmanager.h"
|
||||||
|
@ -68,6 +71,7 @@
|
||||||
#include "ui/settingsdialog.h"
|
#include "ui/settingsdialog.h"
|
||||||
#include "ui/systemtrayicon.h"
|
#include "ui/systemtrayicon.h"
|
||||||
#include "widgets/errordialog.h"
|
#include "widgets/errordialog.h"
|
||||||
|
#include "widgets/fileview.h"
|
||||||
#include "widgets/multiloadingindicator.h"
|
#include "widgets/multiloadingindicator.h"
|
||||||
#include "widgets/osd.h"
|
#include "widgets/osd.h"
|
||||||
#include "widgets/trackslider.h"
|
#include "widgets/trackslider.h"
|
||||||
|
@ -84,19 +88,22 @@
|
||||||
# include "visualisations/visualisationcontainer.h"
|
# include "visualisations/visualisationcontainer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QFileSystemModel>
|
#include <QCloseEvent>
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
#include <QUndoStack>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFileSystemModel>
|
||||||
|
#include <QLinearGradient>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QtDebug>
|
|
||||||
#include <QCloseEvent>
|
|
||||||
#include <QSignalMapper>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
|
#include <QSignalMapper>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -130,6 +137,11 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
||||||
library_(NULL),
|
library_(NULL),
|
||||||
global_shortcuts_(new GlobalShortcuts(this)),
|
global_shortcuts_(new GlobalShortcuts(this)),
|
||||||
devices_(NULL),
|
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),
|
settings_dialog_(NULL),
|
||||||
cover_manager_(NULL),
|
cover_manager_(NULL),
|
||||||
equalizer_(new Equalizer),
|
equalizer_(new Equalizer),
|
||||||
|
@ -166,14 +178,21 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
||||||
ui_->multi_loading_indicator->SetTaskManager(task_manager_);
|
ui_->multi_loading_indicator->SetTaskManager(task_manager_);
|
||||||
ui_->volume->setValue(player_->GetVolume());
|
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);
|
track_position_timer_->setInterval(1000);
|
||||||
connect(track_position_timer_, SIGNAL(timeout()), SLOT(UpdateTrackPosition()));
|
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
|
// Start initialising the player
|
||||||
player_->Init();
|
player_->Init();
|
||||||
|
|
||||||
|
@ -193,15 +212,15 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
||||||
|
|
||||||
ui_->playlist->SetManager(playlists_);
|
ui_->playlist->SetManager(playlists_);
|
||||||
|
|
||||||
ui_->library_view->setModel(library_sort_model_);
|
library_view_->view()->setModel(library_sort_model_);
|
||||||
ui_->library_view->SetLibrary(library_->model());
|
library_view_->view()->SetLibrary(library_->model());
|
||||||
ui_->library_view->SetTaskManager(task_manager_);
|
library_view_->view()->SetTaskManager(task_manager_);
|
||||||
ui_->library_view->SetDeviceManager(devices_);
|
library_view_->view()->SetDeviceManager(devices_);
|
||||||
|
|
||||||
ui_->radio_view->SetModel(radio_model_);
|
radio_view_->SetModel(radio_model_);
|
||||||
|
|
||||||
ui_->devices_view->SetDeviceManager(devices_);
|
device_view_->SetDeviceManager(devices_);
|
||||||
ui_->devices_view->SetLibrary(library_->model());
|
device_view_->SetLibrary(library_->model());
|
||||||
|
|
||||||
organise_dialog_->SetDestinationModel(library_->model()->directory_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"));
|
ui_->action_rain->setIcon(IconLoader::Load("weather-showers-scattered"));
|
||||||
|
|
||||||
// File view connections
|
// File view connections
|
||||||
connect(ui_->file_view, SIGNAL(AddToPlaylist(QList<QUrl>)), SLOT(AddFilesToPlaylist(QList<QUrl>)));
|
connect(file_view_, SIGNAL(AddToPlaylist(QList<QUrl>)), SLOT(AddFilesToPlaylist(QList<QUrl>)));
|
||||||
connect(ui_->file_view, SIGNAL(Load(QList<QUrl>)), SLOT(LoadFilesToPlaylist(QList<QUrl>)));
|
connect(file_view_, SIGNAL(Load(QList<QUrl>)), SLOT(LoadFilesToPlaylist(QList<QUrl>)));
|
||||||
connect(ui_->file_view, SIGNAL(DoubleClicked(QList<QUrl>)), SLOT(FilesDoubleClicked(QList<QUrl>)));
|
connect(file_view_, SIGNAL(DoubleClicked(QList<QUrl>)), SLOT(FilesDoubleClicked(QList<QUrl>)));
|
||||||
connect(ui_->file_view, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
|
connect(file_view_, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
|
||||||
connect(ui_->file_view, SIGNAL(CopyToLibrary(QList<QUrl>)), SLOT(CopyFilesToLibrary(QList<QUrl>)));
|
connect(file_view_, SIGNAL(CopyToLibrary(QList<QUrl>)), SLOT(CopyFilesToLibrary(QList<QUrl>)));
|
||||||
connect(ui_->file_view, SIGNAL(MoveToLibrary(QList<QUrl>)), SLOT(MoveFilesToLibrary(QList<QUrl>)));
|
connect(file_view_, SIGNAL(MoveToLibrary(QList<QUrl>)), SLOT(MoveFilesToLibrary(QList<QUrl>)));
|
||||||
connect(ui_->file_view, SIGNAL(CopyToDevice(QList<QUrl>)), SLOT(CopyFilesToDevice(QList<QUrl>)));
|
connect(file_view_, SIGNAL(CopyToDevice(QList<QUrl>)), SLOT(CopyFilesToDevice(QList<QUrl>)));
|
||||||
ui_->file_view->SetTaskManager(task_manager_);
|
file_view_->SetTaskManager(task_manager_);
|
||||||
|
|
||||||
// Action connections
|
// Action connections
|
||||||
connect(ui_->action_next_track, SIGNAL(triggered()), player_, SLOT(Next()));
|
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(Paused()), osd_, SLOT(Paused()));
|
||||||
connect(player_, SIGNAL(Stopped()), osd_, SLOT(Stopped()));
|
connect(player_, SIGNAL(Stopped()), osd_, SLOT(Stopped()));
|
||||||
connect(player_, SIGNAL(PlaylistFinished()), osd_, SLOT(PlaylistFinished()));
|
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)), osd_, SLOT(VolumeChanged(int)));
|
||||||
connect(player_, SIGNAL(VolumeChanged(int)), ui_->volume, SLOT(setValue(int)));
|
connect(player_, SIGNAL(VolumeChanged(int)), ui_->volume, SLOT(setValue(int)));
|
||||||
connect(player_, SIGNAL(ForceShowOSD(Song)), SLOT(ForceShowOSD(Song)));
|
connect(player_, SIGNAL(ForceShowOSD(Song)), SLOT(ForceShowOSD(Song)));
|
||||||
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), osd_, SLOT(SongChanged(Song)));
|
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), osd_, SLOT(SongChanged(Song)));
|
||||||
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), player_, SLOT(CurrentMetadataChanged(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(PlaylistChanged()), player_, SLOT(PlaylistChanged()));
|
||||||
connect(playlists_, SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex)));
|
connect(playlists_, SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex)));
|
||||||
connect(playlists_, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
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)));
|
connect(database_->Worker().get(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
||||||
|
|
||||||
// Library connections
|
// Library connections
|
||||||
connect(ui_->library_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryItemDoubleClicked(QModelIndex)));
|
connect(library_view_->view(), SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryItemDoubleClicked(QModelIndex)));
|
||||||
connect(ui_->library_view, SIGNAL(Load(QModelIndexList)), SLOT(LoadLibraryItemToPlaylist(QModelIndexList)));
|
connect(library_view_->view(), SIGNAL(Load(QModelIndexList)), SLOT(LoadLibraryItemToPlaylist(QModelIndexList)));
|
||||||
connect(ui_->library_view, SIGNAL(AddToPlaylist(QModelIndexList)), SLOT(AddLibraryItemToPlaylist(QModelIndexList)));
|
connect(library_view_->view(), SIGNAL(AddToPlaylist(QModelIndexList)), SLOT(AddLibraryItemToPlaylist(QModelIndexList)));
|
||||||
connect(ui_->library_view, SIGNAL(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
|
connect(library_view_->view(), SIGNAL(ShowConfigDialog()), SLOT(ShowLibraryConfig()));
|
||||||
connect(library_->model(), SIGNAL(TotalSongCountUpdated(int)), ui_->library_view, SLOT(TotalSongCountUpdated(int)));
|
connect(library_->model(), SIGNAL(TotalSongCountUpdated(int)), library_view_->view(), SLOT(TotalSongCountUpdated(int)));
|
||||||
|
|
||||||
connect(task_manager_, SIGNAL(PauseLibraryWatchers()), library_, SLOT(PauseWatcher()));
|
connect(task_manager_, SIGNAL(PauseLibraryWatchers()), library_, SLOT(PauseWatcher()));
|
||||||
connect(task_manager_, SIGNAL(ResumeLibraryWatchers()), library_, SLOT(ResumeWatcher()));
|
connect(task_manager_, SIGNAL(ResumeLibraryWatchers()), library_, SLOT(ResumeWatcher()));
|
||||||
|
|
||||||
// Devices connections
|
// Devices connections
|
||||||
connect(devices_, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
connect(devices_, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
||||||
connect(ui_->devices_view, SIGNAL(Load(SongList)), SLOT(LoadDeviceSongsToPlaylist(SongList)));
|
connect(device_view_, SIGNAL(Load(SongList)), SLOT(LoadDeviceSongsToPlaylist(SongList)));
|
||||||
connect(ui_->devices_view, SIGNAL(AddToPlaylist(SongList)), SLOT(AddDeviceSongsToPlaylist(SongList)));
|
connect(device_view_, SIGNAL(AddToPlaylist(SongList)), SLOT(AddDeviceSongsToPlaylist(SongList)));
|
||||||
connect(ui_->devices_view, SIGNAL(DoubleClicked(SongList)), SLOT(DeviceSongsDoubleClicked(SongList)));
|
connect(device_view_, SIGNAL(DoubleClicked(SongList)), SLOT(DeviceSongsDoubleClicked(SongList)));
|
||||||
|
|
||||||
// Library filter widget
|
// Library filter widget
|
||||||
QAction* library_config_action = new QAction(
|
QAction* library_config_action = new QAction(
|
||||||
IconLoader::Load("configure"), tr("Configure library..."), this);
|
IconLoader::Load("configure"), tr("Configure library..."), this);
|
||||||
connect(library_config_action, SIGNAL(triggered()), SLOT(ShowLibraryConfig()));
|
connect(library_config_action, SIGNAL(triggered()), SLOT(ShowLibraryConfig()));
|
||||||
ui_->library_filter->SetSettingsGroup(kSettingsGroup);
|
library_view_->filter()->SetSettingsGroup(kSettingsGroup);
|
||||||
ui_->library_filter->SetLibraryModel(library_->model());
|
library_view_->filter()->SetLibraryModel(library_->model());
|
||||||
ui_->library_filter->AddMenuAction(library_config_action);
|
library_view_->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()));
|
|
||||||
|
|
||||||
// Playlist menu
|
// Playlist menu
|
||||||
playlist_play_pause_ = playlist_menu_->addAction(tr("Play"), this, SLOT(PlaylistPlay()));
|
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_, SIGNAL(AddItemsToPlaylist(PlaylistItemList)), SLOT(InsertRadioItems(PlaylistItemList)));
|
||||||
connect(radio_model_->GetLastFMService(), SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChanged(bool)));
|
connect(radio_model_->GetLastFMService(), SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChanged(bool)));
|
||||||
connect(radio_model_->GetLastFMService(), SIGNAL(ButtonVisibilityChanged(bool)), SLOT(LastFMButtonVisibilityChanged(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)));
|
connect(radio_model_->Service<MagnatuneService>(), SIGNAL(DownloadFinished(QStringList)), osd_, SLOT(MagnatuneDownloadFinished(QStringList)));
|
||||||
|
|
||||||
LastFMButtonVisibilityChanged(radio_model_->GetLastFMService()->AreButtonsVisible());
|
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()));
|
connect(global_shortcuts_, SIGNAL(ShowOSD()), player_, SLOT(ShowOSD()));
|
||||||
|
|
||||||
// Lyrics
|
// Lyrics
|
||||||
ui_->playlist->song_info()->lyric_view()->set_network(network);
|
lyric_view_->set_network(network);
|
||||||
|
|
||||||
// Analyzer
|
// Analyzer
|
||||||
ui_->analyzer->SetEngine(player_->GetEngine());
|
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_->splitter->setSizes(QList<int>() << 200 << width() - 200);
|
||||||
}
|
}
|
||||||
ui_->tabs->setCurrentIndex(settings_.value("current_tab", 0).toInt());
|
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();
|
ReloadSettings();
|
||||||
|
|
||||||
|
@ -1476,17 +1490,17 @@ void MainWindow::EnsureSettingsDialogCreated() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
settings_dialog_->SetGlobalShortcutManager(global_shortcuts_);
|
settings_dialog_->SetGlobalShortcutManager(global_shortcuts_);
|
||||||
settings_dialog_->SetLyricFetcher(ui_->playlist->song_info()->lyric_fetcher());
|
settings_dialog_->SetLyricFetcher(lyric_view_->fetcher());
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
connect(settings_dialog_.get(), SIGNAL(accepted()), SLOT(ReloadSettings()));
|
connect(settings_dialog_.get(), SIGNAL(accepted()), SLOT(ReloadSettings()));
|
||||||
connect(settings_dialog_.get(), SIGNAL(accepted()), library_, 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()), player_, SLOT(ReloadSettings()));
|
||||||
connect(settings_dialog_.get(), SIGNAL(accepted()), osd_, 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()), player_->GetEngine(), SLOT(ReloadSettings()));
|
||||||
connect(settings_dialog_.get(), SIGNAL(accepted()), ui_->playlist->view(), 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
|
#ifdef ENABLE_WIIMOTEDEV
|
||||||
connect(settings_dialog_.get(), SIGNAL(accepted()), wiimotedev_shortcuts_.get(), SLOT(ReloadSettings()));
|
connect(settings_dialog_.get(), SIGNAL(accepted()), wiimotedev_shortcuts_.get(), SLOT(ReloadSettings()));
|
||||||
connect(settings_dialog_.get(), SIGNAL(SetWiimotedevInterfaceActived(bool)), wiimotedev_shortcuts_.get(), SLOT(SetWiimotedevInterfaceActived(bool)));
|
connect(settings_dialog_.get(), SIGNAL(SetWiimotedevInterfaceActived(bool)), wiimotedev_shortcuts_.get(), SLOT(SetWiimotedevInterfaceActived(bool)));
|
||||||
|
@ -1562,3 +1576,9 @@ void MainWindow::ShowVisualisations() {
|
||||||
visualisation_->show();
|
visualisation_->show();
|
||||||
#endif // ENABLE_VISUALISATIONS
|
#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);
|
||||||
|
}
|
||||||
|
|
|
@ -36,12 +36,16 @@ class AlbumCoverManager;
|
||||||
class CommandlineOptions;
|
class CommandlineOptions;
|
||||||
class Database;
|
class Database;
|
||||||
class DeviceManager;
|
class DeviceManager;
|
||||||
|
class DeviceView;
|
||||||
class EditTagDialog;
|
class EditTagDialog;
|
||||||
class Equalizer;
|
class Equalizer;
|
||||||
class ErrorDialog;
|
class ErrorDialog;
|
||||||
|
class FileView;
|
||||||
class GlobalShortcuts;
|
class GlobalShortcuts;
|
||||||
class GroupByDialog;
|
class GroupByDialog;
|
||||||
class Library;
|
class Library;
|
||||||
|
class LibraryViewContainer;
|
||||||
|
class LyricView;
|
||||||
class MultiLoadingIndicator;
|
class MultiLoadingIndicator;
|
||||||
class NetworkAccessManager;
|
class NetworkAccessManager;
|
||||||
class OrganiseDialog;
|
class OrganiseDialog;
|
||||||
|
@ -53,6 +57,7 @@ class PlaylistParser;
|
||||||
class QueueManager;
|
class QueueManager;
|
||||||
class RadioItem;
|
class RadioItem;
|
||||||
class RadioModel;
|
class RadioModel;
|
||||||
|
class RadioViewContainer;
|
||||||
class Song;
|
class Song;
|
||||||
class SystemTrayIcon;
|
class SystemTrayIcon;
|
||||||
class TaskManager;
|
class TaskManager;
|
||||||
|
@ -190,6 +195,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||||
void AddLibrarySongsToPlaylist(bool clear_first, const SongList& songs);
|
void AddLibrarySongsToPlaylist(bool clear_first, const SongList& songs);
|
||||||
void AddDeviceSongsToPlaylist(bool clear_first, const SongList& songs);
|
void AddDeviceSongsToPlaylist(bool clear_first, const SongList& songs);
|
||||||
void AddUrls(bool play_now, const QList<QUrl>& urls);
|
void AddUrls(bool play_now, const QList<QUrl>& urls);
|
||||||
|
void AddFancyTab(QWidget* widget, const QIcon& icon, const QString& label);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui_MainWindow* ui_;
|
Ui_MainWindow* ui_;
|
||||||
|
@ -212,6 +218,12 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||||
|
|
||||||
DeviceManager* devices_;
|
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<SettingsDialog> settings_dialog_;
|
||||||
boost::scoped_ptr<AddStreamDialog> add_stream_dialog_;
|
boost::scoped_ptr<AddStreamDialog> add_stream_dialog_;
|
||||||
boost::scoped_ptr<AlbumCoverManager> cover_manager_;
|
boost::scoped_ptr<AlbumCoverManager> cover_manager_;
|
||||||
|
|
|
@ -36,131 +36,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabs">
|
<widget class="FancyTabWidget" 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>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="NowPlayingWidget" name="now_playing" native="true"/>
|
<widget class="NowPlayingWidget" name="now_playing" native="true"/>
|
||||||
|
@ -860,35 +736,12 @@
|
||||||
<extends>QSlider</extends>
|
<extends>QSlider</extends>
|
||||||
<header>widgets/sliderwidget.h</header>
|
<header>widgets/sliderwidget.h</header>
|
||||||
</customwidget>
|
</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>
|
<customwidget>
|
||||||
<class>AnalyzerContainer</class>
|
<class>AnalyzerContainer</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
<header>analyzers/analyzercontainer.h</header>
|
<header>analyzers/analyzercontainer.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</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>
|
<customwidget>
|
||||||
<class>PlaylistContainer</class>
|
<class>PlaylistContainer</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
|
@ -920,9 +773,16 @@
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>DeviceView</class>
|
<class>FancyTabWidget</class>
|
||||||
<extends>QTreeView</extends>
|
<extends>QWidget</extends>
|
||||||
<header>devices/deviceview.h</header>
|
<header>fancytabwidget.h</header>
|
||||||
|
<container>0</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>LyricView</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>lyrics/lyricview.h</header>
|
||||||
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue