Move fancy tabbar classes into separate files
This commit is contained in:
@@ -230,6 +230,8 @@ set(SOURCES
|
|||||||
widgets/busyindicator.cpp
|
widgets/busyindicator.cpp
|
||||||
widgets/clickablelabel.cpp
|
widgets/clickablelabel.cpp
|
||||||
widgets/fancytabwidget.cpp
|
widgets/fancytabwidget.cpp
|
||||||
|
widgets/fancytabbar.cpp
|
||||||
|
widgets/fancytabdata.cpp
|
||||||
widgets/favoritewidget.cpp
|
widgets/favoritewidget.cpp
|
||||||
widgets/fileview.cpp
|
widgets/fileview.cpp
|
||||||
widgets/fileviewlist.cpp
|
widgets/fileviewlist.cpp
|
||||||
@@ -476,6 +478,8 @@ set(HEADERS
|
|||||||
widgets/busyindicator.h
|
widgets/busyindicator.h
|
||||||
widgets/clickablelabel.h
|
widgets/clickablelabel.h
|
||||||
widgets/fancytabwidget.h
|
widgets/fancytabwidget.h
|
||||||
|
widgets/fancytabbar.h
|
||||||
|
widgets/fancytabdata.h
|
||||||
widgets/favoritewidget.h
|
widgets/favoritewidget.h
|
||||||
widgets/fileview.h
|
widgets/fileview.h
|
||||||
widgets/fileviewlist.h
|
widgets/fileviewlist.h
|
||||||
|
|||||||
@@ -406,9 +406,9 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add the playing widget to the fancy tab widget
|
// Add the playing widget to the fancy tab widget
|
||||||
ui_->tabs->addBottomWidget(ui_->widget_playing);
|
ui_->tabs->AddBottomWidget(ui_->widget_playing);
|
||||||
ui_->tabs->setBackgroundPixmap(QPixmap(QStringLiteral(":/pictures/sidebar-background.png")));
|
ui_->tabs->SetBackgroundPixmap(QPixmap(QStringLiteral(":/pictures/sidebar-background.png")));
|
||||||
ui_->tabs->Load(QLatin1String(kSettingsGroup));
|
ui_->tabs->LoadSettings(QLatin1String(kSettingsGroup));
|
||||||
|
|
||||||
track_position_timer_->setInterval(kTrackPositionUpdateTimeMs);
|
track_position_timer_->setInterval(kTrackPositionUpdateTimeMs);
|
||||||
QObject::connect(track_position_timer_, &QTimer::timeout, this, &MainWindow::UpdateTrackPosition);
|
QObject::connect(track_position_timer_, &QTimer::timeout, this, &MainWindow::UpdateTrackPosition);
|
||||||
@@ -844,7 +844,7 @@ MainWindow::MainWindow(Application *app, SharedPtr<SystemTrayIcon> tray_icon, OS
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fancy tabs
|
// Fancy tabs
|
||||||
QObject::connect(ui_->tabs, &FancyTabWidget::CurrentChanged, this, &MainWindow::TabSwitched);
|
QObject::connect(ui_->tabs, &FancyTabWidget::CurrentTabChanged, this, &MainWindow::TabSwitched);
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, context_view_, &ContextView::SongChanged);
|
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, context_view_, &ContextView::SongChanged);
|
||||||
|
|||||||
283
src/widgets/fancytabbar.cpp
Normal file
283
src/widgets/fancytabbar.cpp
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* This file was part of Clementine.
|
||||||
|
* Copyright 2018, Vikram Ambrose <ambroseworks@gmail.com>
|
||||||
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <QTabBar>
|
||||||
|
#include <QString>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QStylePainter>
|
||||||
|
#include <QPaintEvent>
|
||||||
|
#include <QTransform>
|
||||||
|
#include <QLinearGradient>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QPen>
|
||||||
|
|
||||||
|
#include "core/stylehelper.h"
|
||||||
|
#include "fancytabbar.h"
|
||||||
|
#include "fancytabwidget.h"
|
||||||
|
#include "fancytabdata.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr int TabSize_LargeSidebarMinWidth = 70;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
FancyTabBar::FancyTabBar(QWidget *parent) :
|
||||||
|
QTabBar(parent),
|
||||||
|
mouseHoverTabIndex(-1) {
|
||||||
|
|
||||||
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FancyTabBar::TabText(const int index) const {
|
||||||
|
return tabText(index).isEmpty() ? QLatin1String("") : tabData(index).value<FancyTabData*>()->label();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize FancyTabBar::sizeHint() const {
|
||||||
|
|
||||||
|
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
||||||
|
if (tabWidget->mode() == FancyTabWidget::Mode::Tabs || tabWidget->mode() == FancyTabWidget::Mode::IconOnlyTabs) {
|
||||||
|
return QTabBar::sizeHint();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize size;
|
||||||
|
int h = 0;
|
||||||
|
for (int i = 0; i < count(); ++i) {
|
||||||
|
if (tabSizeHint(i).width() > size.width()) size.setWidth(tabSizeHint(i).width());
|
||||||
|
h += tabSizeHint(i).height();
|
||||||
|
}
|
||||||
|
size.setHeight(h);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int FancyTabBar::width() const {
|
||||||
|
|
||||||
|
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
||||||
|
if (tabWidget->mode() == FancyTabWidget::Mode::LargeSidebar || tabWidget->mode() == FancyTabWidget::Mode::SmallSidebar) {
|
||||||
|
int w = 0;
|
||||||
|
for (int i = 0; i < count(); ++i) {
|
||||||
|
if (tabSizeHint(i).width() > w) w = tabSizeHint(i).width();
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return QTabBar::width();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize FancyTabBar::tabSizeHint(const int index) const {
|
||||||
|
|
||||||
|
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
||||||
|
|
||||||
|
QSize size;
|
||||||
|
if (tabWidget->mode() == FancyTabWidget::Mode::LargeSidebar) {
|
||||||
|
|
||||||
|
QFont bold_font(font());
|
||||||
|
bold_font.setBold(true);
|
||||||
|
QFontMetrics fm(bold_font);
|
||||||
|
|
||||||
|
// If the text of any tab is wider than the set width then use that instead.
|
||||||
|
int w = std::max(TabSize_LargeSidebarMinWidth, tabWidget->iconsize_largesidebar() + 22);
|
||||||
|
for (int i = 0; i < count(); ++i) {
|
||||||
|
QRect rect = fm.boundingRect(QRect(0, 0, std::max(TabSize_LargeSidebarMinWidth, tabWidget->iconsize_largesidebar() + 22), height()), Qt::TextWordWrap, TabText(i));
|
||||||
|
rect.setWidth(rect.width() + 10);
|
||||||
|
if (rect.width() > w) w = rect.width();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect rect = fm.boundingRect(QRect(0, 0, w, height()), Qt::TextWordWrap, TabText(index));
|
||||||
|
size = QSize(w, tabWidget->iconsize_largesidebar() + rect.height() + 10);
|
||||||
|
}
|
||||||
|
else if (tabWidget->mode() == FancyTabWidget::Mode::SmallSidebar) {
|
||||||
|
|
||||||
|
QFont bold_font(font());
|
||||||
|
bold_font.setBold(true);
|
||||||
|
QFontMetrics fm(bold_font);
|
||||||
|
|
||||||
|
QRect rect = fm.boundingRect(QRect(0, 0, 100, tabWidget->height()), Qt::AlignHCenter, TabText(index));
|
||||||
|
int w = std::max(tabWidget->iconsize_smallsidebar(), rect.height()) + 15;
|
||||||
|
int h = tabWidget->iconsize_smallsidebar() + rect.width() + 20;
|
||||||
|
size = QSize(w, h);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size = QTabBar::tabSizeHint(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyTabBar::leaveEvent(QEvent *event) {
|
||||||
|
|
||||||
|
Q_UNUSED(event);
|
||||||
|
|
||||||
|
mouseHoverTabIndex = -1;
|
||||||
|
update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyTabBar::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
|
||||||
|
QPoint pos = event->pos();
|
||||||
|
|
||||||
|
mouseHoverTabIndex = tabAt(pos);
|
||||||
|
if (mouseHoverTabIndex > -1) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
QTabBar::mouseMoveEvent(event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyTabBar::paintEvent(QPaintEvent *pe) {
|
||||||
|
|
||||||
|
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
||||||
|
|
||||||
|
if (tabWidget->mode() != FancyTabWidget::Mode::LargeSidebar && tabWidget->mode() != FancyTabWidget::Mode::SmallSidebar) {
|
||||||
|
QTabBar::paintEvent(pe);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool vertical_text_tabs = tabWidget->mode() == FancyTabWidget::Mode::SmallSidebar;
|
||||||
|
|
||||||
|
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 = 0;
|
||||||
|
Qt::Alignment iconFlags;
|
||||||
|
|
||||||
|
QRect tabrectText;
|
||||||
|
QRect tabrectLabel;
|
||||||
|
|
||||||
|
if (vertical_text_tabs) {
|
||||||
|
m = QTransform::fromTranslate(tabrect.left(), tabrect.bottom());
|
||||||
|
m.rotate(-90);
|
||||||
|
textFlags = Qt::AlignVCenter;
|
||||||
|
iconFlags = Qt::AlignVCenter;
|
||||||
|
|
||||||
|
tabrectLabel = QRect(QPoint(0, 0), m.mapRect(tabrect).size());
|
||||||
|
|
||||||
|
tabrectText = tabrectLabel;
|
||||||
|
tabrectText.translate(tabWidget->iconsize_smallsidebar() + 8, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m = QTransform::fromTranslate(tabrect.left(), tabrect.top());
|
||||||
|
textFlags = Qt::AlignHCenter | Qt::AlignBottom | Qt::TextWordWrap;
|
||||||
|
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.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) : StyleHelper::panelTextColor());
|
||||||
|
p.drawText(tabrectText, textFlags, TabText(index));
|
||||||
|
|
||||||
|
|
||||||
|
// Draw the icon
|
||||||
|
QRect tabrectIcon;
|
||||||
|
if (vertical_text_tabs) {
|
||||||
|
tabrectIcon = tabrectLabel;
|
||||||
|
tabrectIcon.setSize(QSize(tabWidget->iconsize_smallsidebar(), tabWidget->iconsize_smallsidebar()));
|
||||||
|
// Center the icon
|
||||||
|
const int moveRight = (QTabBar::width() - tabWidget->iconsize_smallsidebar()) / 2;
|
||||||
|
tabrectIcon.translate(5, moveRight);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tabrectIcon = tabrectLabel;
|
||||||
|
tabrectIcon.setSize(QSize(tabWidget->iconsize_largesidebar(), tabWidget->iconsize_largesidebar()));
|
||||||
|
// Center the icon
|
||||||
|
const int moveRight = (QTabBar::width() - tabWidget->iconsize_largesidebar() - 1) / 2;
|
||||||
|
tabrectIcon.translate(moveRight, 5);
|
||||||
|
}
|
||||||
|
tabIcon(index).paint(&p, tabrectIcon, iconFlags);
|
||||||
|
p.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
52
src/widgets/fancytabbar.h
Normal file
52
src/widgets/fancytabbar.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* This file was part of Clementine.
|
||||||
|
* Copyright 2018, Vikram Ambrose <ambroseworks@gmail.com>
|
||||||
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FANCYTABBAR_H
|
||||||
|
#define FANCYTABBAR_H
|
||||||
|
|
||||||
|
#include <QTabBar>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class QEvent;
|
||||||
|
class QMouseEvent;
|
||||||
|
class QPaintEvent;
|
||||||
|
|
||||||
|
class FancyTabBar : public QTabBar {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FancyTabBar(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
QString TabText(const int index) const;
|
||||||
|
QSize sizeHint() const override;
|
||||||
|
int width() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSize tabSizeHint(const int index) const;
|
||||||
|
void leaveEvent(QEvent *event) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
void paintEvent(QPaintEvent *pe) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int mouseHoverTabIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FANCYTABBAR_H
|
||||||
43
src/widgets/fancytabdata.cpp
Normal file
43
src/widgets/fancytabdata.cpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "fancytabdata.h"
|
||||||
|
|
||||||
|
FancyTabData::FancyTabData(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label, const int idx, QWidget *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
widget_view_(widget_view),
|
||||||
|
name_(name), icon_(icon),
|
||||||
|
label_(label),
|
||||||
|
index_(idx),
|
||||||
|
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(page_);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->addWidget(widget_view_);
|
||||||
|
page_->setLayout(layout);
|
||||||
|
|
||||||
|
}
|
||||||
50
src/widgets/fancytabdata.h
Normal file
50
src/widgets/fancytabdata.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FANCYTABDATA_H
|
||||||
|
#define FANCYTABDATA_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QString>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
class FancyTabData : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit FancyTabData(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label, const int idx, QWidget *parent);
|
||||||
|
|
||||||
|
QWidget *widget_view() const { return widget_view_; }
|
||||||
|
QString name() const { return name_; }
|
||||||
|
QIcon icon() const { return icon_; }
|
||||||
|
QString label() const { return label_; }
|
||||||
|
QWidget *page() const { return page_; }
|
||||||
|
int index() const { return index_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *widget_view_;
|
||||||
|
QString name_;
|
||||||
|
QIcon icon_;
|
||||||
|
QString label_;
|
||||||
|
int index_;
|
||||||
|
QWidget *page_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FANCYTABDATA_H
|
||||||
@@ -19,403 +19,51 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QApplication>
|
|
||||||
#include <QTabBar>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QList>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStylePainter>
|
#include <QStylePainter>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QRect>
|
|
||||||
#include <QFont>
|
|
||||||
#include <QFontMetrics>
|
|
||||||
#include <QSize>
|
|
||||||
#include <QPoint>
|
|
||||||
#include <QBrush>
|
|
||||||
#include <QPen>
|
|
||||||
#include <QTransform>
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QSettings>
|
#include <QPixmap>
|
||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QtEvents>
|
#include <QContextMenuEvent>
|
||||||
#include <QStyle>
|
#include <QPaintEvent>
|
||||||
#include <QCommonStyle>
|
|
||||||
#include <QProxyStyle>
|
|
||||||
#include <QStyleOption>
|
|
||||||
#include <QStyleOptionComplex>
|
|
||||||
|
|
||||||
#include "fancytabwidget.h"
|
#include "fancytabwidget.h"
|
||||||
|
#include "fancytabbar.h"
|
||||||
|
#include "fancytabdata.h"
|
||||||
#include "core/stylehelper.h"
|
#include "core/stylehelper.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "settings/appearancesettingspage.h"
|
#include "settings/appearancesettingspage.h"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
const int FancyTabWidget::IconSize_LargeSidebar = 40;
|
namespace {
|
||||||
const int FancyTabWidget::IconSize_SmallSidebar = 32;
|
constexpr int IconSize_LargeSidebar = 40;
|
||||||
const int FancyTabWidget::TabSize_LargeSidebarMinWidth = 70;
|
constexpr int IconSize_SmallSidebar = 32;
|
||||||
|
} // namespace
|
||||||
class TabData : public QObject {
|
|
||||||
public:
|
|
||||||
TabData(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label, const int idx, QWidget *parent)
|
|
||||||
: QObject(parent),
|
|
||||||
widget_view_(widget_view),
|
|
||||||
name_(name), icon_(icon),
|
|
||||||
label_(label),
|
|
||||||
index_(idx),
|
|
||||||
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(page_);
|
|
||||||
layout->setSpacing(0);
|
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
layout->addWidget(widget_view_);
|
|
||||||
page_->setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *widget_view() const { return widget_view_; }
|
|
||||||
QString name() const { return name_; }
|
|
||||||
QIcon icon() const { return icon_; }
|
|
||||||
QString label() const { return label_; }
|
|
||||||
QWidget *page() const { return page_; }
|
|
||||||
int index() const { return index_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QWidget *widget_view_;
|
|
||||||
QString name_;
|
|
||||||
QIcon icon_;
|
|
||||||
QString label_;
|
|
||||||
int index_;
|
|
||||||
QWidget *page_;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class FancyTabBar : public QTabBar {
|
|
||||||
|
|
||||||
private:
|
|
||||||
int mouseHoverTabIndex = -1;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FancyTabBar(QWidget *parent = nullptr) : QTabBar(parent) {
|
|
||||||
setMouseTracking(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TabText(const int index) const {
|
|
||||||
return tabText(index).isEmpty() ? QLatin1String("") : tabData(index).value<TabData*>()->label();
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize sizeHint() const override {
|
|
||||||
|
|
||||||
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
|
||||||
if (tabWidget->mode() == FancyTabWidget::Mode::Tabs || tabWidget->mode() == FancyTabWidget::Mode::IconOnlyTabs) {
|
|
||||||
return QTabBar::sizeHint();
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize size;
|
|
||||||
int h = 0;
|
|
||||||
for (int i = 0; i < count(); ++i) {
|
|
||||||
if (tabSizeHint(i).width() > size.width()) size.setWidth(tabSizeHint(i).width());
|
|
||||||
h += tabSizeHint(i).height();
|
|
||||||
}
|
|
||||||
size.setHeight(h);
|
|
||||||
|
|
||||||
return size;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int width() const {
|
|
||||||
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
|
||||||
if (tabWidget->mode() == FancyTabWidget::Mode::LargeSidebar || tabWidget->mode() == FancyTabWidget::Mode::SmallSidebar) {
|
|
||||||
int w = 0;
|
|
||||||
for (int i = 0; i < count(); ++i) {
|
|
||||||
if (tabSizeHint(i).width() > w) w = tabSizeHint(i).width();
|
|
||||||
}
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return QTabBar::width();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QSize tabSizeHint(int index) const override {
|
|
||||||
|
|
||||||
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
|
||||||
|
|
||||||
QSize size;
|
|
||||||
if (tabWidget->mode() == FancyTabWidget::Mode::LargeSidebar) {
|
|
||||||
|
|
||||||
QFont bold_font(font());
|
|
||||||
bold_font.setBold(true);
|
|
||||||
QFontMetrics fm(bold_font);
|
|
||||||
|
|
||||||
// If the text of any tab is wider than the set width then use that instead.
|
|
||||||
int w = std::max(FancyTabWidget::TabSize_LargeSidebarMinWidth, tabWidget->iconsize_largesidebar() + 22);
|
|
||||||
for (int i = 0; i < count(); ++i) {
|
|
||||||
QRect rect = fm.boundingRect(QRect(0, 0, std::max(FancyTabWidget::TabSize_LargeSidebarMinWidth, tabWidget->iconsize_largesidebar() + 22), height()), Qt::TextWordWrap, TabText(i));
|
|
||||||
rect.setWidth(rect.width() + 10);
|
|
||||||
if (rect.width() > w) w = rect.width();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect rect = fm.boundingRect(QRect(0, 0, w, height()), Qt::TextWordWrap, TabText(index));
|
|
||||||
size = QSize(w, tabWidget->iconsize_largesidebar() + rect.height() + 10);
|
|
||||||
}
|
|
||||||
else if (tabWidget->mode() == FancyTabWidget::Mode::SmallSidebar) {
|
|
||||||
|
|
||||||
QFont bold_font(font());
|
|
||||||
bold_font.setBold(true);
|
|
||||||
QFontMetrics fm(bold_font);
|
|
||||||
|
|
||||||
QRect rect = fm.boundingRect(QRect(0, 0, 100, tabWidget->height()), Qt::AlignHCenter, TabText(index));
|
|
||||||
int w = std::max(tabWidget->iconsize_smallsidebar(), rect.height()) + 15;
|
|
||||||
int h = tabWidget->iconsize_smallsidebar() + rect.width() + 20;
|
|
||||||
size = QSize(w, h);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
size = QTabBar::tabSizeHint(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void leaveEvent(QEvent *event) override {
|
|
||||||
Q_UNUSED(event);
|
|
||||||
mouseHoverTabIndex = -1;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseMoveEvent(QMouseEvent *event) override {
|
|
||||||
|
|
||||||
QPoint pos = event->pos();
|
|
||||||
|
|
||||||
mouseHoverTabIndex = tabAt(pos);
|
|
||||||
if (mouseHoverTabIndex > -1) {
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
QTabBar::mouseMoveEvent(event);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *pe) override {
|
|
||||||
|
|
||||||
FancyTabWidget *tabWidget = qobject_cast<FancyTabWidget*>(parentWidget());
|
|
||||||
|
|
||||||
if (tabWidget->mode() != FancyTabWidget::Mode::LargeSidebar && tabWidget->mode() != FancyTabWidget::Mode::SmallSidebar) {
|
|
||||||
QTabBar::paintEvent(pe);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool vertical_text_tabs = tabWidget->mode() == FancyTabWidget::Mode::SmallSidebar;
|
|
||||||
|
|
||||||
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 = 0;
|
|
||||||
Qt::Alignment iconFlags;
|
|
||||||
|
|
||||||
QRect tabrectText;
|
|
||||||
QRect tabrectLabel;
|
|
||||||
|
|
||||||
if (vertical_text_tabs) {
|
|
||||||
m = QTransform::fromTranslate(tabrect.left(), tabrect.bottom());
|
|
||||||
m.rotate(-90);
|
|
||||||
textFlags = Qt::AlignVCenter;
|
|
||||||
iconFlags = Qt::AlignVCenter;
|
|
||||||
|
|
||||||
tabrectLabel = QRect(QPoint(0, 0), m.mapRect(tabrect).size());
|
|
||||||
|
|
||||||
tabrectText = tabrectLabel;
|
|
||||||
tabrectText.translate(tabWidget->iconsize_smallsidebar() + 8, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m = QTransform::fromTranslate(tabrect.left(), tabrect.top());
|
|
||||||
textFlags = Qt::AlignHCenter | Qt::AlignBottom | Qt::TextWordWrap;
|
|
||||||
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.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) : StyleHelper::panelTextColor());
|
|
||||||
p.drawText(tabrectText, textFlags, TabText(index));
|
|
||||||
|
|
||||||
|
|
||||||
// Draw the icon
|
|
||||||
QRect tabrectIcon;
|
|
||||||
if (vertical_text_tabs) {
|
|
||||||
tabrectIcon = tabrectLabel;
|
|
||||||
tabrectIcon.setSize(QSize(tabWidget->iconsize_smallsidebar(), tabWidget->iconsize_smallsidebar()));
|
|
||||||
// Center the icon
|
|
||||||
const int moveRight = (QTabBar::width() - tabWidget->iconsize_smallsidebar()) / 2;
|
|
||||||
tabrectIcon.translate(5, moveRight);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tabrectIcon = tabrectLabel;
|
|
||||||
tabrectIcon.setSize(QSize(tabWidget->iconsize_largesidebar(), tabWidget->iconsize_largesidebar()));
|
|
||||||
// Center the icon
|
|
||||||
const int moveRight = (QTabBar::width() - tabWidget->iconsize_largesidebar() - 1) / 2;
|
|
||||||
tabrectIcon.translate(moveRight, 5);
|
|
||||||
}
|
|
||||||
tabIcon(index).paint(&p, tabrectIcon, iconFlags);
|
|
||||||
p.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// Spacers are just disabled pages
|
|
||||||
void FancyTabWidget::addSpacer() {
|
|
||||||
|
|
||||||
QWidget *spacer = new QWidget(this);
|
|
||||||
const int idx = insertTab(count(), spacer, QIcon(), QString());
|
|
||||||
setTabEnabled(idx, false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FancyTabWidget::setBackgroundPixmap(const QPixmap &pixmap) {
|
|
||||||
|
|
||||||
background_pixmap_ = pixmap;
|
|
||||||
update();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FancyTabWidget::setCurrentIndex(int idx) {
|
|
||||||
|
|
||||||
Q_ASSERT(count() > 0);
|
|
||||||
|
|
||||||
if (idx >= count() || idx < 0) idx = 0;
|
|
||||||
|
|
||||||
QWidget *currentPage = widget(idx);
|
|
||||||
QLayout *layout = currentPage->layout();
|
|
||||||
if (bottom_widget_) layout->addWidget(bottom_widget_);
|
|
||||||
QTabWidget::setCurrentIndex(idx);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FancyTabWidget::currentTabChanged(const int idx) {
|
|
||||||
|
|
||||||
QWidget *currentPage = currentWidget();
|
|
||||||
QLayout *layout = currentPage->layout();
|
|
||||||
if (bottom_widget_) layout->addWidget(bottom_widget_);
|
|
||||||
emit CurrentChanged(idx);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override QStyle::subElementRect() and use QCommonStyle to fix a problem with the adwaita style.
|
|
||||||
// The adwaita style is causing the contents of the tabbar to be stretched from top to bottom with space between icons and text.
|
|
||||||
// You can see this on the default Fedora (Gnome) installation.
|
|
||||||
|
|
||||||
class FancyTabWidgetProxyStyle : public QProxyStyle {
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FancyTabWidgetProxyStyle(const QString &style) : QProxyStyle(style), common_style_(new QCommonStyle()) {}
|
|
||||||
~FancyTabWidgetProxyStyle() override { common_style_->deleteLater(); }
|
|
||||||
|
|
||||||
QRect subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget = nullptr) const override {
|
|
||||||
if (element == QStyle::SE_TabWidgetTabBar) {
|
|
||||||
QRect proxy_style_rect = QProxyStyle::subElementRect(element, option, widget);
|
|
||||||
// Fix stretched tabbar (adwaita style issue).
|
|
||||||
proxy_style_rect.setHeight(common_style_->subElementRect(element, option, widget).height());
|
|
||||||
return proxy_style_rect;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return QProxyStyle::subElementRect(element, option, widget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QCommonStyle *common_style_;
|
|
||||||
};
|
|
||||||
|
|
||||||
FancyTabWidget::FancyTabWidget(QWidget *parent)
|
FancyTabWidget::FancyTabWidget(QWidget *parent)
|
||||||
: QTabWidget(parent),
|
: QTabWidget(parent),
|
||||||
style_(nullptr),
|
|
||||||
menu_(nullptr),
|
menu_(nullptr),
|
||||||
mode_(Mode::None),
|
mode_(Mode::None),
|
||||||
bottom_widget_(nullptr),
|
bottom_widget_(nullptr),
|
||||||
bg_color_system_(true),
|
bg_color_system_(true),
|
||||||
bg_gradient_(true),
|
bg_gradient_(true),
|
||||||
iconsize_smallsidebar_(FancyTabWidget::IconSize_SmallSidebar),
|
iconsize_smallsidebar_(IconSize_SmallSidebar),
|
||||||
iconsize_largesidebar_(FancyTabWidget::IconSize_LargeSidebar) {
|
iconsize_largesidebar_(IconSize_LargeSidebar) {
|
||||||
|
|
||||||
FancyTabBar *tabBar = new FancyTabBar(this);
|
FancyTabBar *tabBar = new FancyTabBar(this);
|
||||||
setTabBar(tabBar);
|
setTabBar(tabBar);
|
||||||
@@ -423,57 +71,77 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
|
|||||||
setMovable(true);
|
setMovable(true);
|
||||||
setElideMode(Qt::ElideNone);
|
setElideMode(Qt::ElideNone);
|
||||||
setUsesScrollButtons(true);
|
setUsesScrollButtons(true);
|
||||||
if (QApplication::style() && QApplication::style()->objectName().contains(QRegularExpression(QStringLiteral("^adwaita.*$"), QRegularExpression::CaseInsensitiveOption))) {
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
style_ = new FancyTabWidgetProxyStyle(QApplication::style()->name());
|
|
||||||
#else
|
|
||||||
style_ = new FancyTabWidgetProxyStyle(QApplication::style()->objectName());
|
|
||||||
#endif
|
|
||||||
setStyle(style_);
|
|
||||||
}
|
|
||||||
|
|
||||||
QObject::connect(tabBar, &FancyTabBar::currentChanged, this, &FancyTabWidget::currentTabChanged);
|
QObject::connect(tabBar, &FancyTabBar::currentChanged, this, &FancyTabWidget::CurrentTabChangedSlot);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyTabWidget::~FancyTabWidget() {
|
FancyTabWidget::~FancyTabWidget() {}
|
||||||
if (style_) style_->deleteLater();
|
|
||||||
|
void FancyTabWidget::AddTab(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label) {
|
||||||
|
|
||||||
|
FancyTabData *tab = new FancyTabData(widget_view, name, icon, label, static_cast<int>(tabs_.count()), this);
|
||||||
|
tabs_.insert(widget_view, tab);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyTabWidget::Load(const QString &kSettingsGroup) {
|
bool FancyTabWidget::EnableTab(QWidget *widget_view) {
|
||||||
|
|
||||||
|
if (!tabs_.contains(widget_view)) return false;
|
||||||
|
FancyTabData *tab = tabs_.value(widget_view);
|
||||||
|
|
||||||
|
if (QTabWidget::indexOf(tab->page()) >= 0) return true;
|
||||||
|
const int idx = QTabWidget::insertTab(count(), tab->page(), tab->icon(), tab->label());
|
||||||
|
tabBar()->setTabData(idx, QVariant(tab->name()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FancyTabWidget::DisableTab(QWidget *widget_view) {
|
||||||
|
|
||||||
|
if (!tabs_.contains(widget_view)) return false;
|
||||||
|
FancyTabData *tab = tabs_.value(widget_view);
|
||||||
|
|
||||||
|
int idx = QTabWidget::indexOf(tab->page());
|
||||||
|
if (idx < 0) return false;
|
||||||
|
|
||||||
|
removeTab(idx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyTabWidget::LoadSettings(const QString &settings_group) {
|
||||||
|
|
||||||
Settings s;
|
Settings s;
|
||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(settings_group);
|
||||||
QMultiMap <int, TabData*> tabs;
|
QMultiMap <int, FancyTabData*> tabs;
|
||||||
for (TabData *tab : std::as_const(tabs_)) {
|
for (FancyTabData *tab : std::as_const(tabs_)) {
|
||||||
int idx = s.value(QStringLiteral("tab_") + tab->name(), tab->index()).toInt();
|
int idx = s.value(QStringLiteral("tab_") + tab->name(), tab->index()).toInt();
|
||||||
while (tabs.contains(idx)) { ++idx; }
|
while (tabs.contains(idx)) { ++idx; }
|
||||||
tabs.insert(idx, tab);
|
tabs.insert(idx, tab);
|
||||||
}
|
}
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
QMultiMap <int, TabData*> ::iterator i;
|
QMultiMap <int, FancyTabData*> ::iterator i;
|
||||||
for (i = tabs.begin(); i != tabs.end(); ++i) {
|
for (i = tabs.begin(); i != tabs.end(); ++i) {
|
||||||
TabData *tab = i.value();
|
FancyTabData *tab = i.value();
|
||||||
const int idx = insertTab(i.key(), tab->page(), tab->icon(), tab->label());
|
const int idx = insertTab(i.key(), tab->page(), tab->icon(), tab->label());
|
||||||
tabBar()->setTabData(idx, QVariant::fromValue<TabData*>(tab));
|
tabBar()->setTabData(idx, QVariant::fromValue<FancyTabData*>(tab));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FancyTabWidget::insertTab(const int idx, QWidget *page, const QIcon &icon, const QString &label) {
|
void FancyTabWidget::SaveSettings(const QString &settings_group) {
|
||||||
return QTabWidget::insertTab(idx, page, icon, label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FancyTabWidget::SaveSettings(const QString &kSettingsGroup) {
|
|
||||||
|
|
||||||
Settings s;
|
Settings s;
|
||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(settings_group);
|
||||||
|
|
||||||
s.setValue("tab_mode", static_cast<int>(mode_));
|
s.setValue("tab_mode", static_cast<int>(mode_));
|
||||||
s.setValue("current_tab", currentIndex());
|
s.setValue("current_tab", currentIndex());
|
||||||
|
|
||||||
for (TabData *tab : std::as_const(tabs_)) {
|
for (FancyTabData *tab : std::as_const(tabs_)) {
|
||||||
QString k = QStringLiteral("tab_") + tab->name();
|
QString k = QStringLiteral("tab_") + tab->name();
|
||||||
int idx = QTabWidget::indexOf(tab->page());
|
int idx = QTabWidget::indexOf(tab->page());
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
@@ -498,12 +166,12 @@ void FancyTabWidget::ReloadSettings() {
|
|||||||
if (!bg_color_system_) {
|
if (!bg_color_system_) {
|
||||||
bg_color_ = s.value(AppearanceSettingsPage::kTabBarColor, bg_color_).value<QColor>();
|
bg_color_ = s.value(AppearanceSettingsPage::kTabBarColor, bg_color_).value<QColor>();
|
||||||
}
|
}
|
||||||
iconsize_smallsidebar_ = s.value(AppearanceSettingsPage::kIconSizeTabbarSmallMode, FancyTabWidget::IconSize_SmallSidebar).toInt();
|
iconsize_smallsidebar_ = s.value(AppearanceSettingsPage::kIconSizeTabbarSmallMode, IconSize_SmallSidebar).toInt();
|
||||||
iconsize_largesidebar_ = s.value(AppearanceSettingsPage::kIconSizeTabbarLargeMode, FancyTabWidget::IconSize_LargeSidebar).toInt();
|
iconsize_largesidebar_ = s.value(AppearanceSettingsPage::kIconSizeTabbarLargeMode, IconSize_LargeSidebar).toInt();
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
#ifndef Q_OS_MACOS
|
#ifndef Q_OS_MACOS
|
||||||
if (mode() == FancyTabWidget::Mode::LargeSidebar) {
|
if (mode() == Mode::LargeSidebar) {
|
||||||
setIconSize(QSize(iconsize_largesidebar_, iconsize_largesidebar_));
|
setIconSize(QSize(iconsize_largesidebar_, iconsize_largesidebar_));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -512,56 +180,111 @@ void FancyTabWidget::ReloadSettings() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
update();
|
update();
|
||||||
tabBarUpdateGeometry();
|
TabBarUpdateGeometry();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyTabWidget::addBottomWidget(QWidget *widget_view) {
|
void FancyTabWidget::SetMode(const Mode mode) {
|
||||||
|
|
||||||
|
const Mode previous_mode = mode_;
|
||||||
|
|
||||||
|
mode_ = mode;
|
||||||
|
|
||||||
|
if (mode == Mode::Tabs || mode == Mode::IconOnlyTabs) {
|
||||||
|
setTabPosition(QTabWidget::North);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setTabPosition(QTabWidget::West);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef Q_OS_MACOS
|
||||||
|
if (mode_ == Mode::LargeSidebar) {
|
||||||
|
setIconSize(QSize(iconsize_largesidebar_, iconsize_largesidebar_));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setIconSize(QSize(iconsize_smallsidebar_, iconsize_smallsidebar_));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (previous_mode == Mode::IconOnlyTabs && mode != Mode::IconOnlyTabs) {
|
||||||
|
for (int i = 0; i < count(); ++i) {
|
||||||
|
tabBar()->setTabText(i, tabBar()->tabData(i).value<FancyTabData*>()->label());
|
||||||
|
tabBar()->setTabToolTip(i, QLatin1String(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (previous_mode != Mode::IconOnlyTabs && mode == Mode::IconOnlyTabs) {
|
||||||
|
for (int i = 0; i < count(); ++i) {
|
||||||
|
tabBar()->setTabText(i, QLatin1String(""));
|
||||||
|
tabBar()->setTabToolTip(i, tabBar()->tabData(i).value<FancyTabData*>()->label());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(1ms, this, &FancyTabWidget::TabBarUpdateGeometry);
|
||||||
|
|
||||||
|
emit ModeChanged(mode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int FancyTabWidget::InsertTab(const int idx, QWidget *page, const QIcon &icon, const QString &label) {
|
||||||
|
return QTabWidget::insertTab(idx, page, icon, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyTabWidget::AddSpacer() {
|
||||||
|
|
||||||
|
QWidget *spacer = new QWidget(this);
|
||||||
|
const int idx = insertTab(count(), spacer, QIcon(), QString());
|
||||||
|
setTabEnabled(idx, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyTabWidget::AddBottomWidget(QWidget *widget_view) {
|
||||||
bottom_widget_ = widget_view;
|
bottom_widget_ = widget_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyTabWidget::AddTab(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label) {
|
void FancyTabWidget::SetBackgroundPixmap(const QPixmap &pixmap) {
|
||||||
|
|
||||||
TabData *tab = new TabData(widget_view, name, icon, label, static_cast<int>(tabs_.count()), this);
|
background_pixmap_ = pixmap;
|
||||||
tabs_.insert(widget_view, tab);
|
update();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FancyTabWidget::EnableTab(QWidget *widget_view) {
|
void FancyTabWidget::SetCurrentIndex(int idx) {
|
||||||
|
|
||||||
if (!tabs_.contains(widget_view)) return false;
|
Q_ASSERT(count() > 0);
|
||||||
TabData *tab = tabs_.value(widget_view);
|
|
||||||
|
|
||||||
if (QTabWidget::indexOf(tab->page()) >= 0) return true;
|
if (idx >= count() || idx < 0) idx = 0;
|
||||||
const int idx = QTabWidget::insertTab(count(), tab->page(), tab->icon(), tab->label());
|
|
||||||
tabBar()->setTabData(idx, QVariant(tab->name()));
|
|
||||||
|
|
||||||
return true;
|
QWidget *currentPage = widget(idx);
|
||||||
|
QLayout *layout = currentPage->layout();
|
||||||
|
if (bottom_widget_) layout->addWidget(bottom_widget_);
|
||||||
|
QTabWidget::setCurrentIndex(idx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FancyTabWidget::DisableTab(QWidget *widget_view) {
|
void FancyTabWidget::CurrentTabChangedSlot(const int idx) {
|
||||||
|
|
||||||
if (!tabs_.contains(widget_view)) return false;
|
QWidget *currentPage = currentWidget();
|
||||||
TabData *tab = tabs_.value(widget_view);
|
QLayout *layout = currentPage->layout();
|
||||||
|
if (bottom_widget_) layout->addWidget(bottom_widget_);
|
||||||
|
|
||||||
int idx = QTabWidget::indexOf(tab->page());
|
emit CurrentTabChanged(idx);
|
||||||
if (idx < 0) return false;
|
|
||||||
|
|
||||||
removeTab(idx);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FancyTabWidget::IndexOfTab(QWidget *widget) {
|
int FancyTabWidget::IndexOfTab(QWidget *widget) {
|
||||||
|
|
||||||
if (!tabs_.contains(widget)) return -1;
|
if (!tabs_.contains(widget)) return -1;
|
||||||
return QTabWidget::indexOf(tabs_[widget]->page());
|
return QTabWidget::indexOf(tabs_[widget]->page());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyTabWidget::paintEvent(QPaintEvent *pe) {
|
void FancyTabWidget::paintEvent(QPaintEvent *pe) {
|
||||||
|
|
||||||
if (mode() != FancyTabWidget::Mode::LargeSidebar && mode() != FancyTabWidget::Mode::SmallSidebar) {
|
if (mode() != Mode::LargeSidebar && mode() != Mode::SmallSidebar) {
|
||||||
QTabWidget::paintEvent(pe);
|
QTabWidget::paintEvent(pe);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -633,55 +356,10 @@ void FancyTabWidget::paintEvent(QPaintEvent *pe) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyTabWidget::tabBarUpdateGeometry() {
|
void FancyTabWidget::TabBarUpdateGeometry() {
|
||||||
tabBar()->updateGeometry();
|
tabBar()->updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FancyTabWidget::SetMode(const FancyTabWidget::Mode mode) {
|
|
||||||
|
|
||||||
const FancyTabWidget::Mode previous_mode = mode_;
|
|
||||||
|
|
||||||
mode_ = mode;
|
|
||||||
|
|
||||||
if (mode == FancyTabWidget::Mode::Tabs || mode == FancyTabWidget::Mode::IconOnlyTabs) {
|
|
||||||
setTabPosition(QTabWidget::North);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setTabPosition(QTabWidget::West);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef Q_OS_MACOS
|
|
||||||
if (mode_ == FancyTabWidget::Mode::LargeSidebar) {
|
|
||||||
setIconSize(QSize(iconsize_largesidebar_, iconsize_largesidebar_));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setIconSize(QSize(iconsize_smallsidebar_, iconsize_smallsidebar_));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (previous_mode == FancyTabWidget::Mode::IconOnlyTabs && mode != FancyTabWidget::Mode::IconOnlyTabs) {
|
|
||||||
for (int i = 0; i < count(); ++i) {
|
|
||||||
tabBar()->setTabText(i, tabBar()->tabData(i).value<TabData*>()->label());
|
|
||||||
tabBar()->setTabToolTip(i, QLatin1String(""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (previous_mode != FancyTabWidget::Mode::IconOnlyTabs && mode == FancyTabWidget::Mode::IconOnlyTabs) {
|
|
||||||
for (int i = 0; i < count(); ++i) {
|
|
||||||
tabBar()->setTabText(i, QLatin1String(""));
|
|
||||||
tabBar()->setTabToolTip(i, tabBar()->tabData(i).value<TabData*>()->label());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(1ms, this, &FancyTabWidget::tabBarUpdateGeometry);
|
|
||||||
|
|
||||||
emit ModeChanged(mode);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FancyTabWidget::addMenuItem(QActionGroup *group, const QString &text, Mode mode) {
|
void FancyTabWidget::addMenuItem(QActionGroup *group, const QString &text, Mode mode) {
|
||||||
|
|
||||||
QAction *action = group->addAction(text);
|
QAction *action = group->addAction(text);
|
||||||
|
|||||||
@@ -22,21 +22,18 @@
|
|||||||
#ifndef FANCYTABWIDGET_H
|
#ifndef FANCYTABWIDGET_H
|
||||||
#define FANCYTABWIDGET_H
|
#define FANCYTABWIDGET_H
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QSize>
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QActionGroup;
|
class QActionGroup;
|
||||||
class QContextMenuEvent;
|
class QContextMenuEvent;
|
||||||
class QPaintEvent;
|
class QPaintEvent;
|
||||||
class QProxyStyle;
|
class FancyTabData;
|
||||||
class TabData;
|
|
||||||
|
|
||||||
class FancyTabWidget : public QTabWidget {
|
class FancyTabWidget : public QTabWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -45,21 +42,6 @@ class FancyTabWidget : public QTabWidget {
|
|||||||
explicit FancyTabWidget(QWidget *parent = nullptr);
|
explicit FancyTabWidget(QWidget *parent = nullptr);
|
||||||
~FancyTabWidget() override;
|
~FancyTabWidget() override;
|
||||||
|
|
||||||
void AddTab(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label);
|
|
||||||
bool EnableTab(QWidget *widget_view);
|
|
||||||
bool DisableTab(QWidget *widget_view);
|
|
||||||
int insertTab(const int idx, QWidget *page, const QIcon &icon, const QString &label);
|
|
||||||
void addBottomWidget(QWidget *widget_view);
|
|
||||||
int IndexOfTab(QWidget *widget);
|
|
||||||
|
|
||||||
void setBackgroundPixmap(const QPixmap &pixmap);
|
|
||||||
void addSpacer();
|
|
||||||
|
|
||||||
void Load(const QString &kSettingsGroup);
|
|
||||||
void SaveSettings(const QString &kSettingsGroup);
|
|
||||||
void ReloadSettings();
|
|
||||||
|
|
||||||
// Values are persisted - only add to the end
|
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
None = 0,
|
None = 0,
|
||||||
LargeSidebar,
|
LargeSidebar,
|
||||||
@@ -69,25 +51,31 @@ class FancyTabWidget : public QTabWidget {
|
|||||||
PlainSidebar
|
PlainSidebar
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int TabSize_LargeSidebarMinWidth;
|
|
||||||
static const int IconSize_LargeSidebar;
|
|
||||||
static const int IconSize_SmallSidebar;
|
|
||||||
|
|
||||||
Mode mode() const { return mode_; }
|
Mode mode() const { return mode_; }
|
||||||
int iconsize_smallsidebar() const { return iconsize_smallsidebar_; }
|
int iconsize_smallsidebar() const { return iconsize_smallsidebar_; }
|
||||||
int iconsize_largesidebar() const { return iconsize_largesidebar_; }
|
int iconsize_largesidebar() const { return iconsize_largesidebar_; }
|
||||||
|
|
||||||
signals:
|
void AddTab(QWidget *widget_view, const QString &name, const QIcon &icon, const QString &label);
|
||||||
void ModeChanged(const FancyTabWidget::Mode mode);
|
bool EnableTab(QWidget *widget_view);
|
||||||
void CurrentChanged(const int);
|
bool DisableTab(QWidget *widget_view);
|
||||||
|
|
||||||
|
void LoadSettings(const QString &settings_group);
|
||||||
|
void SaveSettings(const QString &settings_group);
|
||||||
|
void ReloadSettings();
|
||||||
|
|
||||||
|
int InsertTab(const int idx, QWidget *page, const QIcon &icon, const QString &label);
|
||||||
|
void AddSpacer();
|
||||||
|
void AddBottomWidget(QWidget *widget_view);
|
||||||
|
void SetBackgroundPixmap(const QPixmap &pixmap);
|
||||||
|
int IndexOfTab(QWidget *widget);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCurrentIndex(int idx);
|
void SetMode(const Mode mode);
|
||||||
void SetMode(const FancyTabWidget::Mode mode);
|
void SetCurrentIndex(int idx);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void tabBarUpdateGeometry();
|
void TabBarUpdateGeometry();
|
||||||
void currentTabChanged(int);
|
void CurrentTabChangedSlot(const int idx);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent*) override;
|
void paintEvent(QPaintEvent*) override;
|
||||||
@@ -96,20 +84,23 @@ class FancyTabWidget : public QTabWidget {
|
|||||||
private:
|
private:
|
||||||
void addMenuItem(QActionGroup *group, const QString &text, Mode mode);
|
void addMenuItem(QActionGroup *group, const QString &text, Mode mode);
|
||||||
|
|
||||||
QProxyStyle *style_;
|
signals:
|
||||||
|
void ModeChanged(const Mode mode);
|
||||||
|
void CurrentTabChanged(const int idx);
|
||||||
|
|
||||||
|
private:
|
||||||
QPixmap background_pixmap_;
|
QPixmap background_pixmap_;
|
||||||
QMenu *menu_;
|
QMenu *menu_;
|
||||||
Mode mode_;
|
Mode mode_;
|
||||||
QWidget *bottom_widget_;
|
QWidget *bottom_widget_;
|
||||||
|
|
||||||
QHash<QWidget*, TabData*> tabs_;
|
QHash<QWidget*, FancyTabData*> tabs_;
|
||||||
|
|
||||||
bool bg_color_system_;
|
bool bg_color_system_;
|
||||||
bool bg_gradient_;
|
bool bg_gradient_;
|
||||||
QColor bg_color_;
|
QColor bg_color_;
|
||||||
int iconsize_smallsidebar_;
|
int iconsize_smallsidebar_;
|
||||||
int iconsize_largesidebar_;
|
int iconsize_largesidebar_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FANCYTABWIDGET_H
|
#endif // FANCYTABWIDGET_H
|
||||||
|
|||||||
Reference in New Issue
Block a user