diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp
index cebaaf0dc..3eec31d3f 100644
--- a/src/core/mainwindow.cpp
+++ b/src/core/mainwindow.cpp
@@ -260,25 +260,24 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
// Add tabs to the fancy tab widget
- ui_->tabs->addTab(context_view_, IconLoader::Load("strawberry"), tr("Context"));
- ui_->tabs->addTab(collection_view_, IconLoader::Load("vinyl"), tr("Collection"));
- ui_->tabs->addTab(file_view_, IconLoader::Load("document-open"), tr("Files"));
- ui_->tabs->addTab(playlist_list_, IconLoader::Load("view-media-playlist"), tr("Playlists"));
+ ui_->tabs->addTab(context_view_, IconLoader::Load("strawberry"), "Context");
+ ui_->tabs->addTab(collection_view_, IconLoader::Load("vinyl"), "Collection");
+ ui_->tabs->addTab(file_view_, IconLoader::Load("document-open"), "Files");
+ ui_->tabs->addTab(playlist_list_, IconLoader::Load("view-media-playlist"), "Playlists");
#ifndef Q_OS_WIN
- ui_->tabs->addTab(device_view_, IconLoader::Load("device"), tr("Devices"));
+ ui_->tabs->addTab(device_view_, IconLoader::Load("device"), "Devices");
#endif
#ifdef HAVE_STREAM_TIDAL
- ui_->tabs->addTab(tidal_search_view_, IconLoader::Load("tidal"), tr("Tidal", "Tidal"));
+ ui_->tabs->addTab(tidal_search_view_, IconLoader::Load("tidal"), "Tidal");
#endif
#ifdef HAVE_STREAM_DEEZER
- ui_->tabs->addTab(deezer_search_view_, IconLoader::Load("deezer"), tr("Deezer", "Deezer"));
+ ui_->tabs->addTab(deezer_search_view_, IconLoader::Load("deezer"), "Deezer");
#endif
- //ui_->tabs->AddSpacer();
// Add the playing widget to the fancy tab widget
ui_->tabs->addBottomWidget(ui_->widget_playing);
-
//ui_->tabs->SetBackgroundPixmap(QPixmap(":/pictures/strawberry-background.png"));
+ ui_->tabs->loadSettings(kSettingsGroup);
track_position_timer_->setInterval(kTrackPositionUpdateTimeMs);
connect(track_position_timer_, SIGNAL(timeout()), SLOT(UpdateTrackPosition()));
@@ -722,7 +721,10 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
ui_->tabs->setCurrentIndex(settings_.value("current_tab", 1 /* Collection tab */ ).toInt());
FancyTabWidget::Mode default_mode = FancyTabWidget::Mode_LargeSidebar;
- ui_->tabs->SetMode(FancyTabWidget::Mode(settings_.value("tab_mode", default_mode).toInt()));
+ int tab_mode_int = settings_.value("tab_mode", default_mode).toInt();
+ FancyTabWidget::Mode tab_mode = FancyTabWidget::Mode(tab_mode_int);
+ if (tab_mode == FancyTabWidget::Mode_None) tab_mode = default_mode;
+ ui_->tabs->SetMode(tab_mode);
file_view_->SetPath(settings_.value("file_path", QDir::homePath()).toString());
TabSwitched();
@@ -811,6 +813,28 @@ void MainWindow::ReloadSettings() {
album_cover_choice_controller_->search_cover_auto_action()->setChecked(settings.value("search_for_cover_auto", true).toBool());
settings.endGroup();
+#ifdef HAVE_STREAM_TIDAL
+ settings.beginGroup(TidalSettingsPage::kSettingsGroup);
+ bool enable_tidal = settings.value("enabled", false).toBool();
+ settings.endGroup();
+ if (enable_tidal)
+ ui_->tabs->addTab(tidal_search_view_, IconLoader::Load("tidal"), "Tidal");
+ else
+ ui_->tabs->delTab("tidal");
+#endif
+
+#ifdef HAVE_STREAM_DEEZER
+ settings.beginGroup(DeezerSettingsPage::kSettingsGroup);
+ bool enable_deezer = settings.value("enabled", false).toBool();
+ settings.endGroup();
+ if (enable_deezer)
+ ui_->tabs->addTab(deezer_search_view_, IconLoader::Load("deezer"), "Deezer");
+ else
+ ui_->tabs->delTab("deezer");
+#endif
+
+ ui_->tabs->loadSettings(kSettingsGroup);
+
}
void MainWindow::ReloadAllSettings() {
@@ -884,12 +908,14 @@ void MainWindow::MediaPlaying() {
ui_->action_play_pause->setIcon(IconLoader::Load("media-pause"));
ui_->action_play_pause->setText(tr("Pause"));
- bool enable_play_pause = !(app_->player()->GetCurrentItem()->options() & PlaylistItem::PauseDisabled);
+ bool enable_play_pause(false);
+ bool can_seek(false);
+ if (app_->player()->GetCurrentItem()) {
+ enable_play_pause = !(app_->player()->GetCurrentItem()->options() & PlaylistItem::PauseDisabled);
+ can_seek = !(app_->player()->GetCurrentItem()->options() & PlaylistItem::SeekDisabled);
+ }
ui_->action_play_pause->setEnabled(enable_play_pause);
-
- bool can_seek = !(app_->player()->GetCurrentItem()->options() & PlaylistItem::SeekDisabled);
ui_->track_slider->SetCanSeek(can_seek);
-
if (tray_icon_) tray_icon_->SetPlaying(enable_play_pause);
track_position_timer_->start();
@@ -913,6 +939,7 @@ void MainWindow::SongChanged(const Song &song) {
}
void MainWindow::TrackSkipped(PlaylistItemPtr item) {
+
// If it was a collection item then we have to increment its skipped count in the database.
if (item && item->IsLocalCollectionItem() && item->Metadata().id() != -1) {
@@ -929,6 +956,7 @@ void MainWindow::TrackSkipped(PlaylistItemPtr item) {
app_->collection_backend()->IncrementSkipCountAsync(song.id(), percentage);
}
}
+
}
void MainWindow::changeEvent(QEvent *event) {
@@ -937,16 +965,18 @@ void MainWindow::changeEvent(QEvent *event) {
}
void MainWindow::resizeEvent(QResizeEvent *event) {
+ if (!initialised_) return;
SaveGeometry();
}
void MainWindow::TabSwitched() {
- if (ui_->tabs->currentIndex() > 0)
- ui_->widget_playing->SetEnabled();
- else
+ if (ui_->tabs->tabBar()->tabData(ui_->tabs->currentIndex()).toString().toLower() == "context")
ui_->widget_playing->SetDisabled();
+ else
+ ui_->widget_playing->SetEnabled();
+ if (!initialised_) return;
SaveGeometry();
}
@@ -960,6 +990,7 @@ void MainWindow::SaveGeometry() {
settings_.setValue("splitter_state", ui_->splitter->saveState());
settings_.setValue("current_tab", ui_->tabs->currentIndex());
settings_.setValue("tab_mode", ui_->tabs->mode());
+ ui_->tabs->saveSettings(kSettingsGroup);
}
@@ -1145,6 +1176,7 @@ void MainWindow::UpdateTrackPosition() {
//Playlist *playlist = app_->playlist_manager()->active();
PlaylistItemPtr item(app_->player()->GetCurrentItem());
+ if (!item) return;
const int position = std::floor(float(app_->player()->engine()->position_nanosec()) / kNsecPerSec + 0.5);
const int length = item->Metadata().length_nanosec() / kNsecPerSec;
@@ -2216,8 +2248,8 @@ bool MainWindow::winEvent(MSG *msg, long*) {
void MainWindow::Exit() {
+ SaveGeometry();
SavePlaybackStatus();
- //settings_.setValue("show_sidebar", ui_->action_toggle_show_sidebar->isChecked());
if (app_->player()->engine()->is_fadeout_enabled()) {
// To shut down the application when fadeout will be finished
diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h
index 3f7a956fd..02dedac23 100644
--- a/src/core/mainwindow.h
+++ b/src/core/mainwindow.h
@@ -387,6 +387,13 @@ signals:
Song song_playing_;
QImage image_original_;
+#ifdef HAVE_STREAM_TIDAL
+ int tab_index_tidal_;
+#endif
+#ifdef HAVE_STREAM_DEEZER
+ int tab_index_deezer_;
+#endif
+
};
#endif // MAINWINDOW_H
diff --git a/src/settings/deezersettingspage.cpp b/src/settings/deezersettingspage.cpp
index 5beeb698a..5a29727da 100644
--- a/src/settings/deezersettingspage.cpp
+++ b/src/settings/deezersettingspage.cpp
@@ -73,6 +73,7 @@ void DeezerSettingsPage::Load() {
QSettings s;
s.beginGroup(kSettingsGroup);
+ ui_->checkbox_enable->setChecked(s.value("enabled", false).toBool());
ui_->username->setText(s.value("username").toString());
QByteArray password = s.value("password").toByteArray();
if (password.isEmpty()) ui_->password->clear();
@@ -83,7 +84,12 @@ void DeezerSettingsPage::Load() {
ui_->spinbox_songssearchlimit->setValue(s.value("songssearchlimit", 100).toInt());
ui_->checkbox_fetchalbums->setChecked(s.value("fetchalbums", false).toBool());
dialog()->ComboBoxLoadFromSettings(s, ui_->combobox_coversize, "coversize", "cover_big");
- ui_->checkbox_preview->setChecked(s.value("preview", false).toBool());
+#if defined(HAVE_DEEZER) || defined(HAVE_DZMEDIA)
+ bool preview(false);
+#else
+ bool preview(true);
+#endif
+ ui_->checkbox_preview->setChecked(s.value("preview", preview).toBool());
s.endGroup();
if (service_->authenticated()) ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn);
@@ -95,6 +101,7 @@ void DeezerSettingsPage::Save() {
QSettings s;
s.beginGroup(kSettingsGroup);
+ s.setValue("enabled", ui_->checkbox_enable->isChecked());
s.setValue("username", ui_->username->text());
s.setValue("password", QString::fromUtf8(ui_->password->text().toUtf8().toBase64()));
s.setValue("quality", ui_->combobox_quality->itemData(ui_->combobox_quality->currentIndex()));
diff --git a/src/settings/deezersettingspage.ui b/src/settings/deezersettingspage.ui
index d2938d82d..89f78bf9a 100644
--- a/src/settings/deezersettingspage.ui
+++ b/src/settings/deezersettingspage.ui
@@ -14,6 +14,13 @@
Deezer
+ -
+
+
+ Enable
+
+
+
-
diff --git a/src/settings/tidalsettingspage.cpp b/src/settings/tidalsettingspage.cpp
index f3c08b9b9..743ec062e 100644
--- a/src/settings/tidalsettingspage.cpp
+++ b/src/settings/tidalsettingspage.cpp
@@ -37,7 +37,6 @@ const char *TidalSettingsPage::kSettingsGroup = "Tidal";
TidalSettingsPage::TidalSettingsPage(SettingsDialog *parent)
: SettingsPage(parent),
ui_(new Ui::TidalSettingsPage),
- //service_(dialog()->app()->internet_model()->Service()) {
service_(dialog()->app()->internet_model()->Service()) {
ui_->setupUi(this);
@@ -75,6 +74,7 @@ void TidalSettingsPage::Load() {
QSettings s;
s.beginGroup(kSettingsGroup);
+ ui_->checkbox_enable->setChecked(s.value("enabled", false).toBool());
ui_->username->setText(s.value("username").toString());
QByteArray password = s.value("password").toByteArray();
if (password.isEmpty()) ui_->password->clear();
@@ -96,6 +96,7 @@ void TidalSettingsPage::Save() {
QSettings s;
s.beginGroup(kSettingsGroup);
+ s.setValue("enabled", ui_->checkbox_enable->isChecked());
s.setValue("username", ui_->username->text());
s.setValue("password", QString::fromUtf8(ui_->password->text().toUtf8().toBase64()));
s.setValue("quality", ui_->combobox_quality->itemData(ui_->combobox_quality->currentIndex()));
diff --git a/src/settings/tidalsettingspage.ui b/src/settings/tidalsettingspage.ui
index dc5c3f1f7..a448aab53 100644
--- a/src/settings/tidalsettingspage.ui
+++ b/src/settings/tidalsettingspage.ui
@@ -14,6 +14,13 @@
Tidal
+
-
+
+
+ Enable
+
+
+
-
diff --git a/src/widgets/fancytabwidget.cpp b/src/widgets/fancytabwidget.cpp
index 3a56beb3d..858e6033e 100644
--- a/src/widgets/fancytabwidget.cpp
+++ b/src/widgets/fancytabwidget.cpp
@@ -1,749 +1,514 @@
-/**************************************************************************
-**
-** 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 "config.h"
+/*
+ * Strawberry Music Player
+ * This file was part of Clementine.
+ * Copyright 2018, Vikram Ambrose
+ * Copyright 2018, Jonas Kvinge
+ *
+ * Strawberry 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.
+ *
+ * Strawberry 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 Strawberry. If not, see .
+ *
+ */
#include "fancytabwidget.h"
+#include "stylehelper.h"
+#include "core/logging.h"
-#include
-#include
+#include
+
+#include
#include
-#include
-#include
-#include
-#include
+#include
+#include
#include
-#include
#include
-#include
+#include
#include
-#include
#include
-#include
-#include
-#include
-#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
-#include
+#include
+#include
#include
-#include
-#include
-#include
-#include
-#include
+#include
+#include
+#include
+#include
+#include
#include
-#include
-#include
-#include
-#include
-#include
+#include
-#include "core/logging.h"
-#include "stylehelper.h"
+const QSize FancyTabWidget::IconSize_LargeSidebar = QSize(24, 24);
+const QSize FancyTabWidget::IconSize_SmallSidebar = QSize(22, 22);
+const QSize FancyTabWidget::TabSize_LargeSidebar = QSize(70, 47);
-using namespace Core;
-using namespace Internal;
+class FancyTabBar: public QTabBar {
-const int FancyTabBar::m_rounding = 22;
-const int FancyTabBar::m_textPadding = 4;
+ private:
+ int mouseHoverTabIndex = -1;
+ QMap labelCache;
+ QMap spacers;
-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;
+ public:
+ explicit FancyTabBar(QWidget* parent=0) : QTabBar(parent) {
+ setMouseTracking(true);
}
- 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;
+ QSize sizeHint() const {
- if (selected) {
- //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();
+ QSize size(QTabBar::sizeHint());
- //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());
+ 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;
- //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));
}
- QTransform m;
- if (vertical_tabs) {
- m = QTransform::fromTranslate(rect.left(), rect.bottom());
- m.rotate(-90);
- }
- else {
- m = QTransform::fromTranslate(rect.left(), rect.top());
+ int width() {
+ return tabSizeHint(0).width();
}
- const QRect draw_rect(QPoint(0, 0), m.mapRect(rect).size());
+ protected:
+ QSize tabSizeHint(int index) const {
- p->save();
- p->setTransform(m);
+ FancyTabWidget *tabWidget = (FancyTabWidget*) parentWidget();
+ QSize size = FancyTabWidget::TabSize_LargeSidebar;
- 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));
+ if(tabWidget->mode() != FancyTabWidget::Mode_LargeSidebar) {
+ size = QTabBar::tabSizeHint(index);
}
- 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();
- }
- }
+ 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();
- }
- }
-#endif
-
- Utils::StyleHelper::drawIconWithShadow(v_opt->icon, icon_rect, p, QIcon::Normal);
-
- 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 QCommonStyle);
- 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();
- }
- return true;
+ void leaveEvent(QEvent *event) {
+ mouseHoverTabIndex = -1;
+ update();
}
- return QWidget::event(event);
-}
-void FancyTab::enterEvent(QEvent*) {
- fadeIn();
-}
+ void mouseMoveEvent(QMouseEvent *event) {
-void FancyTab::leaveEvent(QEvent*) {
- fadeOut();
-}
+ QPoint pos = event->pos();
-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;
+ mouseHoverTabIndex = tabAt(pos);
+ if (mouseHoverTabIndex > -1)
update();
- m_triggerTimer.start(0);
- break;
+ QTabBar::mouseMoveEvent(event);
+
+ }
+
+ void paintEvent(QPaintEvent *pe) {
+
+ FancyTabWidget *tabWidget = (FancyTabWidget*) parentWidget();
+
+ bool verticalTextTabs = false;
+
+ if (tabWidget->mode() == FancyTabWidget::Mode_SmallSidebar)
+ verticalTextTabs = true;
+
+ // if LargeSidebar, restore spacers
+ if (spacers.count() > 0 && tabWidget->mode() == FancyTabWidget::Mode_LargeSidebar) {
+ for (int index : spacers.keys()) {
+ tabWidget->insertTab(index, spacers[index], QIcon(), QString());
+ tabWidget->setTabEnabled(index, false);
+ }
+ spacers.clear();
+ }
+ if (tabWidget->mode() != FancyTabWidget::Mode_LargeSidebar) {
+ // traverse in the opposite order to save indices of spacers
+ for (int i = count() - 1; i >= 0; --i) {
+ // spacers are disabled tabs
+ if (!isTabEnabled(i) && !spacers.contains(i)) {
+ spacers[i] = tabWidget->widget(i);
+ tabWidget->removeTab(i);
+ --i;
+ }
+ }
+ }
+
+ // 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;
+ }
+
+ QStylePainter p(this);
+
+ for (int index = 0; index < count(); index++) {
+ const bool selected = tabWidget->currentIndex() == index;
+ QRect tabrect = tabRect(index);
+ QRect selectionRect = tabrect;
+ 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();
+
+ // 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());
+
+ // 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();
+ }
}
}
-}
-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 FancyTabBar::addSpacer(int size) {
- qobject_cast(layout())->insertSpacerItem(layout()->count()-1,
- new QSpacerItem(0, size, QSizePolicy::Fixed, QSizePolicy::Maximum));
-}
-
-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);
-
- 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(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
-
- const int textHeight = painter->fontMetrics().height();
- tabIconRect.adjust(0, 4, 0, -textHeight);
- Utils::StyleHelper::drawIconWithShadow(tabIcon(tabIndex), tabIconRect, painter, QIcon::Normal);
-
- painter->translate(0, -1);
- painter->drawText(tabTextRect, textFlags, tabText);
- painter->restore();
-}
-
-void FancyTabBar::setCurrentIndex(int index) {
- m_currentIndex = index;
- update();
- emit currentChanged(m_currentIndex);
-}
-
-//////
-// 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
-//////
+// Spacers are just disabled pages
+void FancyTabWidget::addSpacer() {
-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),
- 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));
+ QWidget *spacer = new QWidget();
+ const int index = addTab(spacer, QIcon(), QString());
+ setTabEnabled(index, false);
- side_widget_->setLayout(side_layout_);
- side_widget_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
-
- 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);
}
-void FancyTabWidget::addTab(QWidget* tab, const QIcon& icon, const QString& label) {
- stack_->addWidget(tab);
- items_ << Item(icon, label);
-}
-
-void FancyTabWidget::AddSpacer(int size) {
- items_ << Item(size);
-}
-
-void FancyTabWidget::SetBackgroundPixmap(const QPixmap& pixmap) {
+void FancyTabWidget::setBackgroundPixmap(const QPixmap& pixmap) {
background_pixmap_ = pixmap;
update();
}
-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::currentIndex() 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);
- }
+
+ if (index >= count()) index = 0;
+
+ QWidget *currentPage = widget(index);
+ QLayout *layout = currentPage->layout();
+ if (bottom_widget_) layout->addWidget(bottom_widget_);
+ QTabWidget::setCurrentIndex(index);
+
}
-void FancyTabWidget::setCurrentWidget(QWidget* widget) {
- setCurrentIndex(stack_->indexOf(widget));
-}
+void FancyTabWidget::currentTabChanged(int index) {
-void FancyTabWidget::ShowWidget(int index) {
- stack_->setCurrentIndex(index);
+ QWidget *currentPage = currentWidget();
+ QLayout *layout = currentPage->layout();
+ if (bottom_widget_) layout->addWidget(bottom_widget_);
emit CurrentChanged(index);
+
+}
+
+FancyTabWidget::FancyTabWidget(QWidget* parent) : QTabWidget(parent),
+ menu_(nullptr),
+ mode_(Mode_None),
+ bottom_widget_(nullptr)
+ {
+
+ FancyTabBar *tabBar = new FancyTabBar(this);
+
+ setTabBar(tabBar);
+ setTabPosition(QTabWidget::West);
+ setMovable(true);
+
+ connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int)));
+
+}
+
+void FancyTabWidget::loadSettings(const char *kSettingsGroup) {
+
+ QSettings settings;
+ settings.beginGroup(kSettingsGroup);
+
+ for (int i = 0 ; i < count() ; i++) {
+ QString k = "tab_" + tabBar()->tabData(i).toString().toLower();
+ int index = settings.value(k, i).toInt();
+ if (index >= 0)
+ tabBar()->moveTab(i, index);
+ else
+ removeTab(i); // Does not delete page
+ }
+
+ settings.endGroup();
+
+}
+
+void FancyTabWidget::saveSettings(const char *kSettingsGroup) {
+
+ QSettings settings;
+ settings.beginGroup(kSettingsGroup);
+
+ for (int i = 0 ; i < count() ; i++) {
+ QString k = "tab_" + tabBar()->tabData(i).toString().toLower();
+ settings.setValue(k, i);
+ }
+
+ settings.endGroup();
+
}
void FancyTabWidget::addBottomWidget(QWidget* widget) {
- top_layout_->addWidget(widget);
+ bottom_widget_ = widget;
}
-void FancyTabWidget::SetMode(Mode mode) {
- // Remove previous tab bar
- delete tab_bar_;
- tab_bar_ = nullptr;
+int FancyTabWidget::addTab(QWidget *widget, const QIcon &icon, const QString &label) {
+ return insertTab(count(), widget, icon, label);
+}
- use_background_ = false;
+int FancyTabWidget::insertTab(int index, QWidget *widget, const QIcon &icon, const QString &label) {
- // 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_);
- else
- bar->addTab(item.tab_icon_, item.tab_label_);
- }
-
- bar->setCurrentIndex(stack_->currentIndex());
- connect(bar, SIGNAL(currentChanged(int)), SLOT(ShowWidget(int)));
-
- use_background_ = true;
-
- break;
- }
-
- case Mode_Tabs:
- MakeTabBar(QTabBar::RoundedNorth, true, false, false);
- break;
-
- case Mode_IconOnlyTabs:
- MakeTabBar(QTabBar::RoundedNorth, false, true, false);
- break;
-
- case Mode_SmallSidebar:
- MakeTabBar(QTabBar::RoundedWest, true, true, true);
- use_background_ = true;
- break;
-
- case Mode_PlainSidebar:
- MakeTabBar(QTabBar::RoundedWest, true, true, false);
- break;
+ QWidget *page(nullptr);
+ if (tabs_.contains(label)) page = tabs_.value(label);
+ else {
+ page = new QWidget();
+ // 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(widget);
+ page->setLayout(layout);
+ tabs_.insert(label, page);
}
- tab_bar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ for (int i = 0 ; i < count() ; i++) {
+ QString l = tabBar()->tabData(i).toString().toLower();
+ if (l == label) return i;
+ }
+
+ const int actualIndex = QTabWidget::insertTab(index, page, icon, label);
+ tabBar()->setTabData(actualIndex, QVariant(label));
+ return actualIndex;
+
+}
+
+void FancyTabWidget::delTab(const QString &label) {
+
+ for (int i = 0 ; i < count() ; i++) {
+ QString l = tabBar()->tabData(i).toString().toLower();
+ if (l == label) QTabWidget::removeTab(i);
+ }
+
+}
+
+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);
+ }
+ }
+ }
+
+ // 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());
+
+ p.setPen(Utils::StyleHelper::borderColor());
+ p.drawLine(backgroundRect.topRight(), backgroundRect.bottomRight());
+ }
+
+}
+
+void FancyTabWidget::tabBarUpdateGeometry() {
+ tabBar()->updateGeometry();
+}
+
+void FancyTabWidget::SetMode(FancyTabWidget::Mode mode) {
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)));
+ if (mode == FancyTabWidget::Mode_Tabs || mode == FancyTabWidget::Mode_IconOnlyTabs) {
+ setTabPosition(QTabWidget::North);
+ }
+ else {
+ setTabPosition(QTabWidget::West);
}
- menu_->popup(e->globalPos());
+ 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) {
+void FancyTabWidget::addMenuItem(QSignalMapper* mapper, QActionGroup* group, const QString& text, Mode mode) {
+
QAction* action = group->addAction(text);
action->setCheckable(true);
mapper->setMapping(action, mode);
connect(action, SIGNAL(triggered()), mapper, SLOT(map()));
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());
- }
+ menu_->popup(e->globalPos());
- 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;
}
diff --git a/src/widgets/fancytabwidget.h b/src/widgets/fancytabwidget.h
index df2bd9939..1a5c360b0 100644
--- a/src/widgets/fancytabwidget.h
+++ b/src/widgets/fancytabwidget.h
@@ -1,249 +1,107 @@
-/**************************************************************************
-**
-** 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.
-**
-**************************************************************************/
+/*
+ * Strawberry Music Player
+ * This file was part of Clementine.
+ * Copyright 2018, Vikram Ambrose
+ * Copyright 2018, Jonas Kvinge
+ *
+ * Strawberry 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.
+ *
+ * Strawberry 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 Strawberry. If not, see .
+ *
+ */
#ifndef FANCYTABWIDGET_H
#define FANCYTABWIDGET_H
-#include "config.h"
-
#include
-#include
#include
+#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
-#include
-#include
-#include
-#include
-#include
#include
+#include
+#include
+#include
#include
-class QEvent;
-class QMouseEvent;
-class QPaintEvent;
-class QContextMenuEvent;
-
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 *widget, const QIcon &icon, const QString &label);
+ void delTab(const QString &label);
+ int insertTab(int index, QWidget *widget, 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 *);
- Q_PROPERTY(float fader READ fader WRITE setFader)
-public:
- FancyTab(QWidget *tabbar);
- float fader() { return m_fader; }
- void setFader(float value);
-
- QSize sizeHint() const;
-
- void fadeIn();
- void fadeOut();
-
- QIcon icon;
- QString text;
-
-protected:
- bool event(QEvent *);
- void enterEvent(QEvent *);
- void leaveEvent(QEvent *);
-
-private:
- QPropertyAnimation animator;
- QWidget *tabbar;
- float m_fader;
-};
-
-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,
+ // Values are persisted - only add to the end
+ enum Mode {
+ Mode_None = 0,
+ Mode_LargeSidebar,
+ Mode_SmallSidebar,
+ Mode_Tabs,
+ Mode_IconOnlyTabs,
+ Mode_PlainSidebar,
};
- Type type_;
- QString tab_label_;
- QIcon tab_icon_;
- int spacer_size_;
- };
+ static const QSize TabSize_LargeSidebar;
- void addTab(QWidget *tab, const QIcon &icon, const QString &label);
- void AddSpacer(int size = 40);
- void SetBackgroundPixmap(const QPixmap &pixmap);
+ static const QSize IconSize_LargeSidebar;
+ static const QSize IconSize_SmallSidebar;
- void addBottomWidget(QWidget *widget);
+ Mode mode() { return mode_; }
- int currentIndex() const;
- Mode mode() const { return mode_; }
+ signals:
+ void ModeChanged(FancyTabWidget::Mode mode);
+ void CurrentChanged(int);
-public slots:
- void setCurrentIndex(int index);
- void setCurrentWidget(QWidget *widget);
- void SetMode(Mode mode);
- void SetMode(int mode) { SetMode(Mode(mode)); }
+ public slots:
+ void setCurrentIndex(int index);
+ void SetMode(Mode mode);
+ // Mapper mapped signal needs this convenience function
+ void SetMode(int mode) { SetMode(Mode(mode)); }
-signals:
- void CurrentChanged(int index);
- void ModeChanged(FancyTabWidget::Mode mode);
+ private slots:
+ void tabBarUpdateGeometry();
+ void currentTabChanged(int);
-protected:
- void paintEvent(QPaintEvent *event);
- void contextMenuEvent(QContextMenuEvent *e);
+ protected:
+ void paintEvent(QPaintEvent *);
+ void contextMenuEvent(QContextMenuEvent* e);
+ private:
+ void addMenuItem(QSignalMapper* mapper, QActionGroup* group, const QString& text, Mode mode);
-private slots:
- void ShowWidget(int index);
+ QPixmap background_pixmap_;
+ QMenu* menu_;
+ Mode mode_;
+ QWidget *bottom_widget_;
-private:
- void MakeTabBar(QTabBar::Shape shape, bool text, bool icons, bool fancy);
- void AddMenuItem(QSignalMapper *mapper, QActionGroup *group, const QString &text, Mode mode);
+ QHash tabs_;
- 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