diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index ef0b80f25..5832942d7 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -255,37 +255,40 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, SLOT(AddToPlaylist(QMimeData*))); // Add tabs to the fancy tab widget - ui_->tabs->AddTab(global_search_view_, + ui_->tabs->addTab(global_search_view_, IconLoader::Load("search", IconLoader::Base), tr("Search", "Global search settings dialog title.")); - ui_->tabs->AddTab(library_view_, + ui_->tabs->addTab(library_view_, IconLoader::Load("folder-sound", IconLoader::Base), tr("Library")); - ui_->tabs->AddTab(file_view_, + ui_->tabs->addTab(file_view_, IconLoader::Load("document-open", IconLoader::Base), tr("Files")); - ui_->tabs->AddTab(playlist_list_, + ui_->tabs->addTab(playlist_list_, IconLoader::Load("view-media-playlist", IconLoader::Base), tr("Playlists")); - ui_->tabs->AddTab(internet_view_, + ui_->tabs->addTab(internet_view_, IconLoader::Load("applications-internet", IconLoader::Base), tr("Internet")); - ui_->tabs->AddTab( + ui_->tabs->addTab( device_view_container_, IconLoader::Load("multimedia-player-ipod-mini-blue", IconLoader::Base), tr("Devices")); - ui_->tabs->AddSpacer(); - ui_->tabs->AddTab(song_info_view_, + ui_->tabs->addSpacer(); + ui_->tabs->addTab(song_info_view_, IconLoader::Load("view-media-lyrics", IconLoader::Base), tr("Song info")); - ui_->tabs->AddTab(artist_info_view_, + ui_->tabs->addTab(artist_info_view_, IconLoader::Load("x-clementine-artist", IconLoader::Base), tr("Artist info")); // Add the now playing widget to the fancy tab widget - ui_->tabs->AddBottomWidget(ui_->now_playing); + ui_->tabs->addBottomWidget(ui_->now_playing); - ui_->tabs->SetBackgroundPixmap(QPixmap(":/sidebar_background.png")); + ui_->tabs->setBackgroundPixmap(QPixmap(":/sidebar_background.png")); + + // Do this only after all default tabs have been added + ui_->tabs->loadSettings(kSettingsGroup); track_position_timer_->setInterval(kTrackPositionUpdateTimeMs); connect(track_position_timer_, SIGNAL(timeout()), @@ -979,7 +982,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, settings_.value("splitter_state").toByteArray())) { ui_->splitter->setSizes(QList() << 300 << width() - 300); } - ui_->tabs->SetCurrentIndex( + ui_->tabs->setCurrentIndex( settings_.value("current_tab", 1 /* Library tab */).toInt()); FancyTabWidget::Mode default_mode = FancyTabWidget::Mode_LargeSidebar; ui_->tabs->SetMode( @@ -1265,8 +1268,10 @@ void MainWindow::SaveGeometry() { settings_.setValue("geometry", saveGeometry()); } settings_.setValue("splitter_state", ui_->splitter->saveState()); - settings_.setValue("current_tab", ui_->tabs->current_index()); + settings_.setValue("current_tab", ui_->tabs->currentIndex()); settings_.setValue("tab_mode", ui_->tabs->mode()); + + ui_->tabs->saveSettings(kSettingsGroup); } void MainWindow::SavePlaybackStatus() { @@ -2911,7 +2916,7 @@ void MainWindow::HandleNotificationPreview(OSD::Behaviour type, QString line1, void MainWindow::ScrollToInternetIndex(const QModelIndex& index) { internet_view_->ScrollToIndex(index); - ui_->tabs->SetCurrentWidget(internet_view_); + ui_->tabs->setCurrentWidget(internet_view_); } void MainWindow::AddPodcast() { @@ -2919,11 +2924,11 @@ void MainWindow::AddPodcast() { } void MainWindow::FocusLibraryTab() { - ui_->tabs->SetCurrentWidget(library_view_); + ui_->tabs->setCurrentWidget(library_view_); } void MainWindow::FocusGlobalSearchField() { - ui_->tabs->SetCurrentWidget(global_search_view_); + ui_->tabs->setCurrentWidget(global_search_view_); global_search_view_->FocusSearchField(); } diff --git a/src/widgets/fancytabwidget.cpp b/src/widgets/fancytabwidget.cpp index ccc93b119..05db6012c 100644 --- a/src/widgets/fancytabwidget.cpp +++ b/src/widgets/fancytabwidget.cpp @@ -1,31 +1,20 @@ -/************************************************************************** -** -** 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. -** -**************************************************************************/ +/* This file is part of Clementine. + Copyright 2018, Vikram Ambrose + + 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 . +*/ + #include "fancytabwidget.h" #include "stylehelper.h" @@ -33,626 +22,402 @@ #include -#include -#include -#include #include #include #include -#include #include -#include -#include -#include -#include -#include +#include +#include +#include #include -#include +#include -using namespace Core; -using namespace Internal; +const QSize FancyTabWidget::IconSize_LargeSidebar = QSize(24,24); +const QSize FancyTabWidget::IconSize_SmallSidebar = QSize(22,22); -const int FancyTabBar::m_rounding = 22; -const int FancyTabBar::m_textPadding = 4; +const QSize FancyTabWidget::TabSize_LargeSidebar = QSize(70,47); +class FancyTabBar: public QTabBar { -namespace { -static void selectTab(QPainter* p, const QRect& rect) { - // background - p->save(); - QLinearGradient grad(rect.topLeft(), rect.topRight()); - grad.setColorAt(0, QColor(255, 255, 255, 140)); - grad.setColorAt(1, QColor(255, 255, 255, 210)); - p->fillRect(rect.adjusted(0, 0, 0, -1), grad); - p->restore(); +private: + int mouseHoverTabIndex = -1; + QMap labelCache; - // shadows - p->setPen(QColor(0, 0, 0, 110)); - p->drawLine(rect.topLeft() + QPoint(1, -1), rect.topRight() - QPoint(0, 1)); - p->drawLine(rect.bottomLeft(), rect.bottomRight()); - p->setPen(QColor(0, 0, 0, 40)); - p->drawLine(rect.topLeft(), rect.bottomLeft()); - - // highlights - p->setPen(QColor(255, 255, 255, 50)); - p->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0, 2)); - p->drawLine(rect.bottomLeft() + QPoint(0, 1), - rect.bottomRight() + QPoint(0, 1)); - p->setPen(QColor(255, 255, 255, 40)); - p->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight()); - p->drawLine(rect.topRight() + QPoint(0, 1), - rect.bottomRight() - QPoint(0, 1)); - p->drawLine(rect.bottomLeft() + QPoint(0, -1), - rect.bottomRight() - QPoint(0, 1)); -} -} - -void FancyTabProxyStyle::drawControl(ControlElement element, - const QStyleOption* option, QPainter* p, - const QWidget* widget) const { - - const QStyleOptionTabV3* v_opt = - qstyleoption_cast(option); - - if (element != CE_TabBarTab || !v_opt) { - QProxyStyle::drawControl(element, option, p, widget); - return; - } - - const QRect rect = v_opt->rect; - const bool selected = v_opt->state & State_Selected; - const bool vertical_tabs = v_opt->shape == QTabBar::RoundedWest; - const QString text = v_opt->text; - - if (selected) { - selectTab(p, rect); - } - - QTransform m; - if (vertical_tabs) { - m = QTransform::fromTranslate(rect.left(), rect.bottom()); - m.rotate(-90); - } else { - m = QTransform::fromTranslate(rect.left(), rect.top()); - } - - const QRect draw_rect(QPoint(0, 0), m.mapRect(rect).size()); - - p->save(); - p->setTransform(m); - - QRect icon_rect(QPoint(8, 0), v_opt->iconSize); - QRect text_rect(icon_rect.topRight() + QPoint(4, 0), draw_rect.size()); - text_rect.setRight(draw_rect.width()); - icon_rect.translate(0, (draw_rect.height() - icon_rect.height()) / 2); - - QFont boldFont(p->font()); - boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); - boldFont.setBold(true); - p->setFont(boldFont); - p->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110)); - int textFlags = Qt::AlignHCenter | Qt::AlignVCenter; - p->drawText(text_rect, textFlags, text); - p->setPen(selected ? QColor(60, 60, 60) - : Utils::StyleHelper::panelTextColor()); -#ifndef Q_WS_MAC - if (widget) { - const QString fader_key = "tab_" + text + "_fader"; - const QString animation_key = "tab_" + text + "_animation"; - - const QString tab_hover = widget->property("tab_hover").toString(); - int fader = widget->property(fader_key.toUtf8().constData()).toInt(); - QPropertyAnimation* animation = - widget->property(animation_key.toUtf8().constData()) - .value(); - - if (!animation) { - QWidget* mut_widget = const_cast(widget); - fader = 0; - mut_widget->setProperty(fader_key.toUtf8().constData(), fader); - animation = - new QPropertyAnimation(mut_widget, fader_key.toUtf8(), mut_widget); - connect(animation, SIGNAL(valueChanged(QVariant)), mut_widget, - SLOT(update())); - mut_widget->setProperty(animation_key.toUtf8().constData(), - QVariant::fromValue(animation)); +public: + explicit FancyTabBar(QWidget* parent=0) : QTabBar(parent) { + setMouseTracking(true); } - if (text == tab_hover) { - if (animation->state() != QAbstractAnimation::Running && fader != 40) { - animation->stop(); - animation->setDuration(80); - animation->setEndValue(40); - animation->start(); - } - } else { - if (animation->state() != QAbstractAnimation::Running && fader != 0) { - animation->stop(); - animation->setDuration(160); - animation->setEndValue(0); - animation->start(); - } + QSize sizeHint() const { + QSize size(QTabBar::sizeHint()); + + FancyTabWidget *tabWidget = (FancyTabWidget*) parentWidget(); + if(tabWidget->mode() == FancyTabWidget::Mode_Tabs || + tabWidget->mode() == FancyTabWidget::Mode_IconOnlyTabs) + return size; + + QSize tabSize(tabSizeHint(0)); + size.setWidth(tabSize.width()); + int guessHeight = tabSize.height()*count(); + if(guessHeight > size.height()) + size.setHeight(guessHeight); + return size; } - if (!selected) { - p->save(); - QLinearGradient grad(draw_rect.topLeft(), vertical_tabs - ? draw_rect.bottomLeft() - : draw_rect.topRight()); - grad.setColorAt(0, Qt::transparent); - grad.setColorAt(0.5, QColor(255, 255, 255, fader)); - grad.setColorAt(1, Qt::transparent); - p->fillRect(draw_rect, grad); - p->setPen(QPen(grad, 1.0)); - p->drawLine(draw_rect.topLeft(), vertical_tabs ? draw_rect.bottomLeft() - : draw_rect.topRight()); - p->drawLine(draw_rect.bottomRight(), vertical_tabs - ? draw_rect.topRight() - : draw_rect.bottomLeft()); - p->restore(); + int width() { + return tabSizeHint(0).width(); } - } -#endif - Utils::StyleHelper::drawIconWithShadow(v_opt->icon, icon_rect, p, - QIcon::Normal); +protected: + QSize tabSizeHint(int index) const { + FancyTabWidget *tabWidget = (FancyTabWidget*) parentWidget(); + QSize size = FancyTabWidget::TabSize_LargeSidebar; - p->drawText(text_rect.translated(0, -1), textFlags, text); - - p->restore(); -} - -void FancyTabProxyStyle::polish(QWidget* widget) { - if (QString(widget->metaObject()->className()) == "QTabBar") { - widget->setMouseTracking(true); - widget->installEventFilter(this); - } - QProxyStyle::polish(widget); -} - -void FancyTabProxyStyle::polish(QApplication* app) { QProxyStyle::polish(app); } - -void FancyTabProxyStyle::polish(QPalette& palette) { - QProxyStyle::polish(palette); -} - -bool FancyTabProxyStyle::eventFilter(QObject* o, QEvent* e) { - QTabBar* bar = qobject_cast(o); - if (bar && (e->type() == QEvent::MouseMove || e->type() == QEvent::Leave)) { - QMouseEvent* event = static_cast(e); - const QString old_hovered_tab = bar->property("tab_hover").toString(); - const QString hovered_tab = e->type() == QEvent::Leave - ? QString() - : bar->tabText(bar->tabAt(event->pos())); - bar->setProperty("tab_hover", hovered_tab); - - if (old_hovered_tab != hovered_tab) bar->update(); - } - - return false; -} - -FancyTab::FancyTab(QWidget* tabbar) - : QWidget(tabbar), tabbar(tabbar), m_fader(0) { - animator.setPropertyName("fader"); - animator.setTargetObject(this); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); -} - -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) { - 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); - - QVBoxLayout* layout = new QVBoxLayout; - layout->addSpacerItem( - new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding)); - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - setLayout(layout); - - // We use a zerotimer to keep the sidebar responsive - connect(&m_triggerTimer, SIGNAL(timeout()), this, SLOT(emitCurrentIndex())); -} - -FancyTabBar::~FancyTabBar() { delete style(); } - -QSize FancyTab::sizeHint() const { - QFont boldFont(font()); - boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); - boldFont.setBold(true); - QFontMetrics fm(boldFont); - int spacing = 8; - int width = 60 + spacing + 2; - int iconHeight = 32; - QSize ret(width, iconHeight + spacing + fm.height()); - return ret; -} - -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 iconHeight = minimum ? 0 : 32; - return QSize(width, 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()); -} - -bool FancyTab::event(QEvent* event) { - if (event->type() == QEvent::ToolTip) { - QFontMetrics metrics(font()); - int text_width = metrics.width(text); - - if (text_width > sizeHint().width()) { - // The text is elided: show the tooltip - QHelpEvent* he = static_cast(event); - QToolTip::showText(he->globalPos(), text); - } else { - QToolTip::hideText(); + if(tabWidget->mode() != FancyTabWidget::Mode_LargeSidebar) { + size = QTabBar::tabSizeHint(index); + } + + return size; } - return true; - } - return QWidget::event(event); -} - -void FancyTab::enterEvent(QEvent*) { fadeIn(); } - -void FancyTab::leaveEvent(QEvent*) { 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 { - return m_tabs[index]->geometry(); -} - -QString FancyTabBar::tabToolTip(int index) const { - return m_tabs[index]->toolTip(); -} - -void FancyTabBar::setTabToolTip(int index, const QString& toolTip) { - m_tabs[index]->setToolTip(toolTip); -} - -// 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())) { - m_currentIndex = index; - update(); - m_triggerTimer.start(0); - break; + + void leaveEvent(QEvent * event) { + mouseHoverTabIndex = -1; + update(); } - } -} -void FancyTabBar::addTab(const QIcon& icon, const QString& label) { - FancyTab* tab = new FancyTab(this); - tab->icon = icon; - tab->text = label; - tab->setToolTip(label); - m_tabs.append(tab); - qobject_cast(layout()) - ->insertWidget(layout()->count() - 1, tab); -} + void mouseMoveEvent(QMouseEvent * event) { + QPoint pos = event->pos(); -void FancyTabBar::addSpacer(int size) { - qobject_cast(layout())->insertSpacerItem( - layout()->count() - 1, - new QSpacerItem(0, size, QSizePolicy::Fixed, QSizePolicy::Maximum)); -} + mouseHoverTabIndex = tabAt(pos); + if(mouseHoverTabIndex > -1) + update(); + QTabBar::mouseMoveEvent(event); + } -void FancyTabBar::paintTab(QPainter* painter, int tabIndex) const { - if (!validIndex(tabIndex)) { - qWarning("invalid index"); - return; - } - painter->save(); + void paintEvent(QPaintEvent *pe) { + FancyTabWidget *tabWidget = (FancyTabWidget*) parentWidget(); - QRect rect = tabRect(tabIndex); - bool selected = (tabIndex == m_currentIndex); + bool verticalTextTabs = false; - if (selected) { - selectTab(painter, rect); - } + if(tabWidget->mode() == FancyTabWidget::Mode_SmallSidebar) + verticalTextTabs = true; - QString tabText(painter->fontMetrics().elidedText(this->tabText(tabIndex), - Qt::ElideRight, width())); - QRect tabTextRect(tabRect(tabIndex)); - QRect tabIconRect(tabTextRect); - tabIconRect.adjust(+4, +4, -4, -4); - 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; - painter->drawText(tabTextRect, textFlags, tabText); - painter->setPen(selected ? QColor(60, 60, 60) - : Utils::StyleHelper::panelTextColor()); -#ifndef Q_WS_MAC - if (!selected) { - 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 + // Restore any label text that was hidden/cached for the IconOnlyTabs mode + if(labelCache.count() > 0 && tabWidget->mode() != FancyTabWidget::Mode_IconOnlyTabs) { + for(int i =0; i < count(); i++) { + setTabText(i,labelCache[tabWidget->widget(i)]); + } + labelCache.clear(); + } + if(tabWidget->mode() != FancyTabWidget::Mode_LargeSidebar && + tabWidget->mode() != FancyTabWidget::Mode_SmallSidebar) { + // Cache and hide label text for IconOnlyTabs mode + if(tabWidget->mode() == FancyTabWidget::Mode_IconOnlyTabs && labelCache.count() == 0) { + for(int i =0; i < count(); i++) { + labelCache[tabWidget->widget(i)] = tabText(i); + setTabText(i,""); + } + } + QTabBar::paintEvent(pe); + return; + } - const int textHeight = painter->fontMetrics().height(); - tabIconRect.adjust(0, 4, 0, -textHeight); - Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, - painter, QIcon::Normal); + QStylePainter p(this); - painter->translate(0, -1); - painter->drawText(tabTextRect, textFlags, tabText); - painter->restore(); -} + + for (int index = 0; index < count(); index++) { + const bool selected = tabWidget->currentIndex() == index;; -void FancyTabBar::setCurrentIndex(int index) { - m_currentIndex = index; - update(); - emit currentChanged(m_currentIndex); -} + QRect tabrect = tabRect(index); -////// -// FancyColorButton -////// + QRect selectionRect = tabrect; -class FancyColorButton : public QWidget { - public: - FancyColorButton(QWidget* parent) : m_parent(parent) { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); - } + if(selected) { + // Selection highlight + p.save(); + QLinearGradient grad(selectionRect.topLeft(), selectionRect.topRight()); + grad.setColorAt(0, QColor(255, 255, 255, 140)); + grad.setColorAt(1, QColor(255, 255, 255, 210)); + p.fillRect(selectionRect.adjusted(0,0,0,-1), grad); + p.restore(); - void mousePressEvent(QMouseEvent* ev) { - if (ev->modifiers() & Qt::ShiftModifier) - Utils::StyleHelper::setBaseColor(QColorDialog::getColor( - Utils::StyleHelper::requestedBaseColor(), m_parent)); - } + // shadow lines + p.setPen(QColor(0, 0, 0, 110)); + p.drawLine(selectionRect.topLeft() + QPoint(1, -1), selectionRect.topRight() - QPoint(0, 1)); + p.drawLine(selectionRect.bottomLeft(), selectionRect.bottomRight()); + p.setPen(QColor(0, 0, 0, 40)); + p.drawLine(selectionRect.topLeft(), selectionRect.bottomLeft()); - private: - QWidget* m_parent; + // highlights + p.setPen(QColor(255, 255, 255, 50)); + p.drawLine(selectionRect.topLeft() + QPoint(0, -2), selectionRect.topRight() - QPoint(0, 2)); + p.drawLine(selectionRect.bottomLeft() + QPoint(0, 1), selectionRect.bottomRight() + QPoint(0, 1)); + p.setPen(QColor(255, 255, 255, 40)); + p.drawLine(selectionRect.topLeft() + QPoint(0, 0), selectionRect.topRight()); + p.drawLine(selectionRect.topRight() + QPoint(0, 1), selectionRect.bottomRight() - QPoint(0, 1)); + p.drawLine(selectionRect.bottomLeft() + QPoint(0, -1), selectionRect.bottomRight() - QPoint(0, 1)); + + } + + // Mouse hover effect + if(!selected && index == mouseHoverTabIndex && isTabEnabled(index)) + { + p.save(); + QLinearGradient grad(selectionRect.topLeft(), selectionRect.topRight()); + grad.setColorAt(0, Qt::transparent); + grad.setColorAt(0.5, QColor(255, 255, 255, 40)); + grad.setColorAt(1, Qt::transparent); + p.fillRect(selectionRect, grad); + p.setPen(QPen(grad, 1.0)); + p.drawLine(selectionRect.topLeft(), selectionRect.topRight()); + p.drawLine(selectionRect.bottomRight(), selectionRect.bottomLeft()); + p.restore(); + } + + // Label (Icon and Text) + { + p.save(); + QTransform m; + int textFlags; + Qt::Alignment iconFlags; + + QRect tabrectText; + QRect tabrectLabel; + + if (verticalTextTabs) { + m = QTransform::fromTranslate(tabrect.left(), tabrect.bottom()); + m.rotate(-90); + textFlags = Qt::AlignLeft | Qt::AlignVCenter ; + iconFlags = Qt::AlignLeft | Qt::AlignVCenter; + + tabrectLabel = QRect(QPoint(0, 0), m.mapRect(tabrect).size()); + + tabrectText = tabrectLabel; + tabrectText.translate(30,0); + } else { + m = QTransform::fromTranslate(tabrect.left(), tabrect.top()); + textFlags = Qt::AlignHCenter | Qt::AlignBottom ; + iconFlags = Qt::AlignHCenter | Qt::AlignTop; + + tabrectLabel = QRect(QPoint(0, 0), m.mapRect(tabrect).size()); + + tabrectText = tabrectLabel; + tabrectText.translate(0,-5); + } + + p.setTransform(m); + + QFont boldFont(p.font()); + boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); + boldFont.setBold(true); + p.setFont(boldFont); + + // Text drop shadow color + p.setPen(selected ? QColor(255,255,255,160) : QColor(0,0,0,110) ); + p.translate(0, 3); + p.drawText(tabrectText, textFlags, tabText(index)); + + // Text foreground color + p.translate(0, -1); + p.setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); + p.drawText(tabrectText, textFlags, tabText(index)); + + + // Draw the icon + QRect tabrectIcon; + const int PADDING = 5; + if(verticalTextTabs) { + tabrectIcon = tabrectLabel; + tabrectIcon.setSize(FancyTabWidget::IconSize_SmallSidebar); + tabrectIcon.translate(PADDING,PADDING); + } else { + tabrectIcon = tabrectLabel; + tabrectIcon.setSize(FancyTabWidget::IconSize_LargeSidebar); + // Center the icon + const int moveRight = (FancyTabWidget::TabSize_LargeSidebar.width() - + FancyTabWidget::IconSize_LargeSidebar.width() -1)/2; + tabrectIcon.translate(moveRight,PADDING); + } + tabIcon(index).paint(&p, tabrectIcon, iconFlags); + p.restore(); + } + } + } }; + +// Spacers are just disabled pages +void FancyTabWidget::addSpacer() { + QWidget *spacer = new QWidget(); + const int index = addTab(spacer,QIcon(),QString()); + setTabEnabled(index,false); +} -////// -// FancyTabWidget -////// +void FancyTabWidget::setBackgroundPixmap(const QPixmap& pixmap) { + background_pixmap_ = pixmap; + update(); +} -FancyTabWidget::FancyTabWidget(QWidget* parent) - : QWidget(parent), - mode_(Mode_None), - tab_bar_(nullptr), - stack_(new QStackedLayout), - side_widget_(new QWidget), - side_layout_(new QVBoxLayout), - top_layout_(new QVBoxLayout), - use_background_(false), +void FancyTabWidget::setCurrentIndex(int index) { + QWidget* currentPage = widget(index); + + QLayout *layout = currentPage->layout(); + if(bottom_widget_ != nullptr) + layout->addWidget(bottom_widget_); + + QTabWidget::setCurrentIndex(index); +} + +// Slot +void FancyTabWidget::currentTabChanged(int index) { + QWidget* currentPage = currentWidget(); + + QLayout *layout = currentPage->layout(); + if(bottom_widget_ != nullptr) + layout->addWidget(bottom_widget_); +} + +FancyTabWidget::FancyTabWidget(QWidget* parent) : QTabWidget(parent), menu_(nullptr), - proxy_style_(new FancyTabProxyStyle) { - side_layout_->setSpacing(0); - side_layout_->setMargin(0); - side_layout_->addSpacerItem( - new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding)); + mode_(Mode_None), + bottom_widget_(nullptr) { + FancyTabBar *tabBar = new FancyTabBar(this); - side_widget_->setLayout(side_layout_); - side_widget_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + setTabBar(tabBar); + setTabPosition(QTabWidget::West); + setMovable(true); - top_layout_->setMargin(0); - top_layout_->setSpacing(0); - top_layout_->addLayout(stack_); - - QHBoxLayout* main_layout = new QHBoxLayout; - main_layout->setMargin(0); - main_layout->setSpacing(1); - main_layout->addWidget(side_widget_); - main_layout->addLayout(top_layout_); - setLayout(main_layout); + connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int))); } -void FancyTabWidget::AddTab(QWidget* tab, const QIcon& icon, - const QString& label) { - stack_->addWidget(tab); - items_ << Item(icon, label); -} +void FancyTabWidget::loadSettings(const char *kSettingsGroup) { + QSettings settings; + settings.beginGroup(kSettingsGroup); -void FancyTabWidget::AddSpacer(int size) { items_ << Item(size); } + for(int i =0;itabData(i).toInt(); + std::string k = "tab_index_" + std::to_string(originalIndex); -void FancyTabWidget::SetBackgroundPixmap(const QPixmap& pixmap) { - background_pixmap_ = pixmap; - update(); -} + int newIndex = settings.value(QString::fromStdString(k), i).toInt(); -void FancyTabWidget::paintEvent(QPaintEvent*) { - if (!use_background_) return; - - QPainter painter(this); - - QRect rect = side_widget_->rect().adjusted(0, 0, 1, 0); - rect = style()->visualRect(layoutDirection(), geometry(), rect); - Utils::StyleHelper::verticalGradient(&painter, rect, rect); - - if (!background_pixmap_.isNull()) { - QRect pixmap_rect(background_pixmap_.rect()); - pixmap_rect.moveTo(rect.topLeft()); - - while (pixmap_rect.top() < rect.bottom()) { - QRect source_rect(pixmap_rect.intersected(rect)); - source_rect.moveTo(0, 0); - painter.drawPixmap(pixmap_rect.topLeft(), background_pixmap_, - source_rect); - pixmap_rect.moveTop(pixmap_rect.bottom() - 10); - } - } - - 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()); -} - -int FancyTabWidget::current_index() const { return stack_->currentIndex(); } - -void FancyTabWidget::SetCurrentIndex(int index) { - if (FancyTabBar* bar = qobject_cast(tab_bar_)) { - bar->setCurrentIndex(index); - } else if (QTabBar* bar = qobject_cast(tab_bar_)) { - bar->setCurrentIndex(index); - } else { - stack_->setCurrentIndex(index); - } -} - -void FancyTabWidget::SetCurrentWidget(QWidget* widget) { - SetCurrentIndex(stack_->indexOf(widget)); -} - -void FancyTabWidget::ShowWidget(int index) { - stack_->setCurrentIndex(index); - emit CurrentChanged(index); -} - -void FancyTabWidget::AddBottomWidget(QWidget* widget) { - top_layout_->addWidget(widget); -} - -void FancyTabWidget::SetMode(Mode mode) { - // Remove previous tab bar - delete tab_bar_; - tab_bar_ = nullptr; - - use_background_ = false; - - // Create new tab bar - switch (mode) { - case Mode_None: - default: - qLog(Warning) << "Unknown fancy tab mode" << mode; - // fallthrough - - case Mode_LargeSidebar: { - FancyTabBar* bar = new FancyTabBar(this); - side_layout_->insertWidget(0, bar); - tab_bar_ = bar; - - for (const Item& item : items_) { - if (item.type_ == Item::Type_Spacer) - bar->addSpacer(item.spacer_size_); + if(newIndex >= 0) + tabBar()->moveTab(i,newIndex); else - bar->addTab(item.tab_icon_, item.tab_label_); - } + removeTab(i); // Does not delete page + } +} - bar->setCurrentIndex(stack_->currentIndex()); - connect(bar, SIGNAL(currentChanged(int)), SLOT(ShowWidget(int))); +void FancyTabWidget::saveSettings(const char *kSettingsGroup) { + QSettings settings; + settings.beginGroup(kSettingsGroup); - use_background_ = true; + for(int i =0;itabData(i).toInt(); + std::string k = "tab_index_" + std::to_string(originalIndex); - break; + settings.setValue(QString::fromStdString(k), i); + } +} + + +void FancyTabWidget::addBottomWidget(QWidget* widget) { + bottom_widget_ = widget; +} + +int FancyTabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label) { + return insertTab(count(),page,icon,label); +} + +int FancyTabWidget::insertTab(int index, QWidget * page, const QIcon & icon, const QString & label) { + // In order to achieve the same effect as the "Bottom Widget" of the + // old Nokia based FancyTabWidget a VBoxLayout is used on each page + QVBoxLayout *layout = new QVBoxLayout(); + layout->setSpacing(0); + layout->setContentsMargins(0,0,0,0); + layout->addWidget(page); + + QWidget *newPage = new QWidget(); + newPage->setLayout(layout); + + const int actualIndex = QTabWidget::insertTab(index,newPage,icon,label); + + // Remember the original index. Needed to save order of tabs + tabBar()->setTabData(actualIndex,QVariant(actualIndex)); + return actualIndex; +} + +void FancyTabWidget::paintEvent(QPaintEvent *pe) { + if(mode() != FancyTabWidget::Mode_LargeSidebar && + mode() != FancyTabWidget::Mode_SmallSidebar) { + QTabWidget::paintEvent(pe); + return; + } + QStylePainter p(this); + + // The brown color (Ubuntu) you see on the background gradient + QColor baseColor = StyleHelper::baseColor(); + + QRect backgroundRect = rect(); + backgroundRect.setWidth(((FancyTabBar*)tabBar())->width()); + p.fillRect(backgroundRect,baseColor); + + // Horizontal gradient over the sidebar from transparent to dark + Utils::StyleHelper::verticalGradient(&p,backgroundRect,backgroundRect,false); + + // Draw the translucent png graphics over the gradient fill + { + if (!background_pixmap_.isNull()) { + QRect pixmap_rect(background_pixmap_.rect()); + pixmap_rect.moveTo(backgroundRect.topLeft()); + + while (pixmap_rect.top() < backgroundRect.bottom()) { + QRect source_rect(pixmap_rect.intersected(backgroundRect)); + source_rect.moveTo(0, 0); + p.drawPixmap(pixmap_rect.topLeft(), background_pixmap_,source_rect); + pixmap_rect.moveTop(pixmap_rect.bottom() - 10); + } + } } - case Mode_Tabs: - MakeTabBar(QTabBar::RoundedNorth, true, false, false); - break; + // Shadow effect of the background + { + QColor light(255, 255, 255, 80); + p.setPen(light); + p.drawLine(backgroundRect.topRight() - QPoint(1, 0), backgroundRect.bottomRight() - QPoint(1, 0)); + QColor dark(0, 0, 0, 90); + p.setPen(dark); + p.drawLine(backgroundRect.topLeft(), backgroundRect.bottomLeft()); - case Mode_IconOnlyTabs: - MakeTabBar(QTabBar::RoundedNorth, false, true, false); - break; + p.setPen(Utils::StyleHelper::borderColor()); + p.drawLine(backgroundRect.topRight(), backgroundRect.bottomRight()); + } - case Mode_SmallSidebar: - MakeTabBar(QTabBar::RoundedWest, true, true, true); - use_background_ = true; - break; - - case Mode_PlainSidebar: - MakeTabBar(QTabBar::RoundedWest, true, true, false); - break; - } - - tab_bar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - mode_ = mode; - emit ModeChanged(mode); - update(); } -void FancyTabWidget::contextMenuEvent(QContextMenuEvent* e) { - if (!menu_) { - menu_ = new QMenu(this); - - QSignalMapper* mapper = new QSignalMapper(this); - QActionGroup* group = new QActionGroup(this); - AddMenuItem(mapper, group, tr("Large sidebar"), Mode_LargeSidebar); - AddMenuItem(mapper, group, tr("Small sidebar"), Mode_SmallSidebar); - AddMenuItem(mapper, group, tr("Plain sidebar"), Mode_PlainSidebar); - AddMenuItem(mapper, group, tr("Tabs on top"), Mode_Tabs); - AddMenuItem(mapper, group, tr("Icons on top"), Mode_IconOnlyTabs); - menu_->addActions(group->actions()); - - connect(mapper, SIGNAL(mapped(int)), SLOT(SetMode(int))); - } - - menu_->popup(e->globalPos()); +void FancyTabWidget::tabBarUpdateGeometry() { + tabBar()->updateGeometry(); } -void FancyTabWidget::AddMenuItem(QSignalMapper* mapper, QActionGroup* group, +void FancyTabWidget::SetMode(FancyTabWidget::Mode mode) { + mode_ = mode; + + if(mode == FancyTabWidget::Mode_Tabs || + mode == FancyTabWidget::Mode_IconOnlyTabs) { + setTabPosition(QTabWidget::North); + } else { + setTabPosition(QTabWidget::West); + } + + tabBar()->updateGeometry(); + updateGeometry(); + + // There appears to be a bug in QTabBar which causes tabSizeHint + // to be ignored thus the need for this second shot repaint + QTimer::singleShot(1,this,SLOT(tabBarUpdateGeometry())); + + emit ModeChanged(mode); +} + +void FancyTabWidget::addMenuItem(QSignalMapper* mapper, QActionGroup* group, const QString& text, Mode mode) { QAction* action = group->addAction(text); action->setCheckable(true); @@ -662,47 +427,22 @@ void FancyTabWidget::AddMenuItem(QSignalMapper* mapper, QActionGroup* group, if (mode == mode_) action->setChecked(true); } -void FancyTabWidget::MakeTabBar(QTabBar::Shape shape, bool text, bool icons, - bool fancy) { - QTabBar* bar = new QTabBar(this); - bar->setShape(shape); - bar->setDocumentMode(true); - bar->setUsesScrollButtons(true); - bar->setElideMode(Qt::ElideRight); - if (shape == QTabBar::RoundedWest) { - bar->setIconSize(QSize(22, 22)); +void FancyTabWidget::contextMenuEvent(QContextMenuEvent* e) { + if (!menu_) { + menu_ = new QMenu(this); + + QSignalMapper* mapper = new QSignalMapper(this); + QActionGroup* group = new QActionGroup(this); + addMenuItem(mapper, group, tr("Large sidebar"), Mode_LargeSidebar); + addMenuItem(mapper, group, tr("Small sidebar"), Mode_SmallSidebar); + addMenuItem(mapper, group, tr("Plain sidebar"), Mode_PlainSidebar); + addMenuItem(mapper, group, tr("Tabs on top"), Mode_Tabs); + addMenuItem(mapper, group, tr("Icons on top"), Mode_IconOnlyTabs); + menu_->addActions(group->actions()); + + connect(mapper, SIGNAL(mapped(int)), SLOT(SetMode(int))); } - if (fancy) { - bar->setStyle(proxy_style_.get()); - } - - if (shape == QTabBar::RoundedNorth) - top_layout_->insertWidget(0, bar); - else - side_layout_->insertWidget(0, bar); - - for (const Item& item : items_) { - if (item.type_ != Item::Type_Tab) continue; - - QString label = item.tab_label_; - if (shape == QTabBar::RoundedWest) { - label = QFontMetrics(font()).elidedText(label, Qt::ElideMiddle, 100); - } - - int tab_id = -1; - if (icons && text) - tab_id = bar->addTab(item.tab_icon_, label); - else if (icons) - tab_id = bar->addTab(item.tab_icon_, QString()); - else if (text) - tab_id = bar->addTab(label); - - bar->setTabToolTip(tab_id, item.tab_label_); - } - - bar->setCurrentIndex(stack_->currentIndex()); - connect(bar, SIGNAL(currentChanged(int)), SLOT(ShowWidget(int))); - tab_bar_ = bar; + menu_->popup(e->globalPos()); } diff --git a/src/widgets/fancytabwidget.h b/src/widgets/fancytabwidget.h index a0a3dd80a..9f9397ae7 100644 --- a/src/widgets/fancytabwidget.h +++ b/src/widgets/fancytabwidget.h @@ -1,233 +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. -** -**************************************************************************/ +/* This file is part of Clementine. + Copyright 2018, Vikram Ambrose + + 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 . +*/ #ifndef FANCYTABWIDGET_H #define FANCYTABWIDGET_H #include -#include -#include -#include -#include -#include +#include #include class QActionGroup; class QMenu; -class QPainter; class QSignalMapper; -class QStackedLayout; -class QStatusBar; -class QVBoxLayout; namespace Core { namespace Internal { -class FancyTabProxyStyle : public QProxyStyle { + +class FancyTabWidget : public QTabWidget { Q_OBJECT - public: - void drawControl(ControlElement element, const QStyleOption* option, - QPainter* painter, const QWidget* widget) const; - void polish(QWidget* widget); - void polish(QApplication* app); - void polish(QPalette& palette); + public: + FancyTabWidget(QWidget* parent = 0); + int addTab(QWidget * page, const QIcon & icon, const QString & label); + int insertTab(int index, QWidget * page, const QIcon & icon, const QString & label); + void addBottomWidget(QWidget* widget); - protected: - bool eventFilter(QObject* o, QEvent* e); -}; + void setBackgroundPixmap(const QPixmap& pixmap); + void addSpacer(); -class FancyTab : public QWidget { - Q_OBJECT + void loadSettings(const char *); + void saveSettings(const char *); + // Values are persisted - only add to the end + enum Mode { + Mode_None = 0, + Mode_LargeSidebar, + Mode_SmallSidebar, + Mode_Tabs, + Mode_IconOnlyTabs, + Mode_PlainSidebar, + }; + + static const QSize TabSize_LargeSidebar; - Q_PROPERTY(float fader READ fader WRITE setFader) - public: - FancyTab(QWidget* tabbar); - float fader() { return m_fader; } - void setFader(float value); + static const QSize IconSize_LargeSidebar; + static const QSize IconSize_SmallSidebar; + + Mode mode() { return mode_; } - QSize sizeHint() const; + signals: + void ModeChanged(FancyTabWidget::Mode mode); - void fadeIn(); - void fadeOut(); + public slots: + void setCurrentIndex(int index); + void SetMode(Mode mode); + // Mapper mapped signal needs this convenience function + void SetMode(int mode) { SetMode(Mode(mode)); } - QIcon icon; - QString text; + private slots: + void tabBarUpdateGeometry(); + void currentTabChanged(int); - protected: - bool event(QEvent*); - void enterEvent(QEvent*); - void leaveEvent(QEvent*); + protected: + void paintEvent(QPaintEvent *); + void contextMenuEvent(QContextMenuEvent* e); + private: + void addMenuItem(QSignalMapper* mapper, QActionGroup* group, + const QString& text, Mode mode); - private: - QPropertyAnimation animator; - QWidget* tabbar; - float m_fader; -}; + QPixmap background_pixmap_; + QMenu* menu_; + Mode mode_; + QWidget *bottom_widget_; -class FancyTabBar : public QWidget { - Q_OBJECT - - public: - FancyTabBar(QWidget* parent = nullptr); - ~FancyTabBar(); - - void paintEvent(QPaintEvent* event); - void paintTab(QPainter* painter, int tabIndex) const; - void mousePressEvent(QMouseEvent*); - bool validIndex(int index) const { - return index >= 0 && index < m_tabs.count(); - } - - QSize sizeHint() const; - QSize minimumSizeHint() const; - - void addTab(const QIcon& icon, const QString& label); - void addSpacer(int size = 40); - 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, const QString& toolTip); - QString tabToolTip(int index) const; - - 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; - int m_currentIndex; - QList m_tabs; - QTimer m_triggerTimer; - QSize tabSizeHint(bool minimum = false) const; -}; - -class FancyTabWidget : public QWidget { - Q_OBJECT - - public: - FancyTabWidget(QWidget* parent = nullptr); - - // Values are persisted - only add to the end - enum Mode { - Mode_None = 0, - Mode_LargeSidebar = 1, - Mode_SmallSidebar = 2, - Mode_Tabs = 3, - Mode_IconOnlyTabs = 4, - Mode_PlainSidebar = 5, - }; - - struct Item { - Item(const QIcon& icon, const QString& label) - : type_(Type_Tab), - tab_label_(label), - tab_icon_(icon), - spacer_size_(0) {} - Item(int size) : type_(Type_Spacer), spacer_size_(size) {} - - enum Type { Type_Tab, Type_Spacer, }; - - Type type_; - QString tab_label_; - QIcon tab_icon_; - int spacer_size_; - }; - - void AddTab(QWidget* tab, const QIcon& icon, const QString& label); - void AddSpacer(int size = 40); - void SetBackgroundPixmap(const QPixmap& pixmap); - - void AddBottomWidget(QWidget* widget); - - int current_index() const; - Mode mode() const { return mode_; } - - public slots: - void SetCurrentIndex(int index); - void SetCurrentWidget(QWidget* widget); - void SetMode(Mode mode); - void SetMode(int mode) { SetMode(Mode(mode)); } - -signals: - void CurrentChanged(int index); - void ModeChanged(FancyTabWidget::Mode mode); - - protected: - void paintEvent(QPaintEvent* event); - void contextMenuEvent(QContextMenuEvent* e); - - private slots: - void ShowWidget(int index); - - private: - void MakeTabBar(QTabBar::Shape shape, bool text, bool icons, bool fancy); - void AddMenuItem(QSignalMapper* mapper, QActionGroup* group, - const QString& text, Mode mode); - - Mode mode_; - QList items_; - - QWidget* tab_bar_; - QStackedLayout* stack_; - QPixmap background_pixmap_; - QWidget* side_widget_; - QVBoxLayout* side_layout_; - QVBoxLayout* top_layout_; - - bool use_background_; - - QMenu* menu_; - - std::unique_ptr proxy_style_; }; } // namespace Internal } // namespace Core -Q_DECLARE_METATYPE(QPropertyAnimation*); - -using Core::Internal::FancyTab; -using Core::Internal::FancyTabBar; using Core::Internal::FancyTabWidget; #endif // FANCYTABWIDGET_H