You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
752 lines
22 KiB
752 lines
22 KiB
/************************************************************************** |
|
** |
|
** This file is part of Qt Creator |
|
** |
|
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
** |
|
** Contact: Nokia Corporation (qt-info@nokia.com) |
|
** |
|
** Commercial Usage |
|
** |
|
** Licensees holding valid Qt Commercial licenses may use this file in |
|
** accordance with the Qt Commercial License Agreement provided with the |
|
** Software or, alternatively, in accordance with the terms contained in |
|
** a written agreement between you and Nokia. |
|
** |
|
** GNU Lesser General Public License Usage |
|
** |
|
** Alternatively, this file may be used under the terms of the GNU Lesser |
|
** General Public License version 2.1 as published by the Free Software |
|
** Foundation and appearing in the file LICENSE.LGPL included in the |
|
** packaging of this file. Please review the following information to |
|
** ensure the GNU Lesser General Public License version 2.1 requirements |
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
** |
|
** If you are unsure which license is appropriate for your use, please |
|
** contact the sales department at http://qt.nokia.com/contact. |
|
** |
|
**************************************************************************/ |
|
|
|
#include "fancytabwidget.h" |
|
#include "stylehelper.h" |
|
|
|
#include <QDebug> |
|
|
|
#include <QAnimationGroup> |
|
#include <QColorDialog> |
|
#include <QHBoxLayout> |
|
#include <QMenu> |
|
#include <QMouseEvent> |
|
#include <QPainter> |
|
#include <QSignalMapper> |
|
#include <QSplitter> |
|
#include <QStackedLayout> |
|
#include <QStyleOptionTabV3> |
|
#include <QToolButton> |
|
#include <QToolTip> |
|
#include <QVBoxLayout> |
|
#include <QWindowsStyle> |
|
|
|
using namespace Core; |
|
using namespace Internal; |
|
|
|
const int FancyTabBar::m_rounding = 22; |
|
const int FancyTabBar::m_textPadding = 4; |
|
|
|
void FancyTabProxyStyle::drawControl( |
|
ControlElement element, const QStyleOption* option, |
|
QPainter* p, const QWidget* widget) const |
|
{ |
|
|
|
const QStyleOptionTabV3* v_opt = qstyleoption_cast<const QStyleOptionTabV3*>(option); |
|
|
|
if (element != CE_TabBarTab || !v_opt) { |
|
QProxyStyle::drawControl(element, option, p, widget); |
|
return; |
|
} |
|
|
|
const QRect rect = v_opt->rect; |
|
const bool selected = v_opt->state & State_Selected; |
|
const bool vertical_tabs = v_opt->shape == QTabBar::RoundedWest; |
|
const QString text = v_opt->text; |
|
|
|
if (selected) { |
|
//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(); |
|
|
|
//shadows |
|
p->setPen(QColor(0, 0, 0, 110)); |
|
p->drawLine(rect.topLeft() + QPoint(1, -1), rect.topRight() - QPoint(0, 1)); |
|
p->drawLine(rect.bottomLeft(), rect.bottomRight()); |
|
p->setPen(QColor(0, 0, 0, 40)); |
|
p->drawLine(rect.topLeft(), rect.bottomLeft()); |
|
|
|
//highlights |
|
p->setPen(QColor(255, 255, 255, 50)); |
|
p->drawLine(rect.topLeft() + QPoint(0, -2), rect.topRight() - QPoint(0, 2)); |
|
p->drawLine(rect.bottomLeft() + QPoint(0, 1), rect.bottomRight() + QPoint(0, 1)); |
|
p->setPen(QColor(255, 255, 255, 40)); |
|
p->drawLine(rect.topLeft() + QPoint(0, 0), rect.topRight()); |
|
p->drawLine(rect.topRight() + QPoint(0, 1), rect.bottomRight() - QPoint(0, 1)); |
|
p->drawLine(rect.bottomLeft() + QPoint(0, -1), rect.bottomRight() - QPoint(0, 1)); |
|
} |
|
|
|
QTransform m; |
|
if (vertical_tabs) { |
|
m = QTransform::fromTranslate(rect.left(), rect.bottom()); |
|
m.rotate(-90); |
|
} |
|
else { |
|
m = QTransform::fromTranslate(rect.left(), rect.top()); |
|
} |
|
|
|
const QRect draw_rect(QPoint(0, 0), m.mapRect(rect).size()); |
|
|
|
p->save(); |
|
p->setTransform(m); |
|
|
|
QRect icon_rect(QPoint(8, 0), v_opt->iconSize); |
|
QRect text_rect(icon_rect.topRight() + QPoint(4, 0), draw_rect.size()); |
|
text_rect.setRight(draw_rect.width()); |
|
icon_rect.translate(0, (draw_rect.height() - icon_rect.height()) / 2); |
|
|
|
QFont boldFont(p->font()); |
|
boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); |
|
boldFont.setBold(true); |
|
p->setFont(boldFont); |
|
p->setPen(selected ? QColor(255, 255, 255, 160) : QColor(0, 0, 0, 110)); |
|
int textFlags = Qt::AlignHCenter | Qt::AlignVCenter; |
|
p->drawText(text_rect, textFlags, text); |
|
p->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); |
|
#if 0 |
|
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<QPropertyAnimation*>(); |
|
|
|
if (!animation) { |
|
QWidget* mut_widget = const_cast<QWidget*>(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 (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(); |
|
} |
|
} |
|
|
|
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<QTabBar*>(o); |
|
if (bar && (e->type() == QEvent::MouseMove || e->type() == QEvent::Leave)) { |
|
QMouseEvent* event = static_cast<QMouseEvent*>(e); |
|
const QString old_hovered_tab = bar->property("tab_hover").toString(); |
|
const QString hovered_tab = e->type() == QEvent::Leave ? QString() : bar->tabText(bar->tabAt(event->pos())); |
|
bar->setProperty("tab_hover", hovered_tab); |
|
|
|
if (old_hovered_tab != hovered_tab) { |
|
bar->update(); |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
FancyTab::FancyTab(QWidget* tabbar) |
|
: QWidget(tabbar), tabbar(tabbar), m_fader(0) |
|
{ |
|
// animator.setPropertyName("fader"); |
|
// animator.setTargetObject(this); |
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); |
|
} |
|
|
|
void FancyTab::fadeIn() |
|
{ |
|
// animator.stop(); |
|
// animator.setDuration(80); |
|
// animator.setEndValue(40); |
|
// animator.start(); |
|
} |
|
|
|
void FancyTab::fadeOut() |
|
{ |
|
// animator.stop(); |
|
// animator.setDuration(160); |
|
// animator.setEndValue(0); |
|
// animator.start(); |
|
} |
|
|
|
void FancyTab::setFader(float value) |
|
{ |
|
m_fader = value; |
|
tabbar->update(); |
|
} |
|
|
|
FancyTabBar::FancyTabBar(QWidget* parent) |
|
: QWidget(parent) |
|
{ |
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); |
|
setStyle(new QWindowsStyle); |
|
setMinimumWidth(qMax(2 * m_rounding, 40)); |
|
setAttribute(Qt::WA_Hover, true); |
|
setFocusPolicy(Qt::NoFocus); |
|
setMouseTracking(true); // Needed for hover events |
|
m_triggerTimer.setSingleShot(true); |
|
|
|
QVBoxLayout* layout = new QVBoxLayout; |
|
layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding)); |
|
layout->setSpacing(0); |
|
layout->setContentsMargins(0, 0, 0, 0); |
|
setLayout(layout); |
|
|
|
// We use a zerotimer to keep the sidebar responsive |
|
connect(&m_triggerTimer, SIGNAL(timeout()), this, SLOT(emitCurrentIndex())); |
|
} |
|
|
|
FancyTabBar::~FancyTabBar() |
|
{ |
|
delete style(); |
|
} |
|
|
|
QSize FancyTab::sizeHint() const |
|
{ |
|
QFont boldFont(font()); |
|
boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); |
|
boldFont.setBold(true); |
|
QFontMetrics fm(boldFont); |
|
int spacing = 8; |
|
int width = 60 + spacing + 2; |
|
int iconHeight = 32; |
|
QSize ret(width, iconHeight + spacing + fm.height()); |
|
return ret; |
|
} |
|
|
|
QSize FancyTabBar::tabSizeHint(bool minimum) const |
|
{ |
|
QFont boldFont(font()); |
|
boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); |
|
boldFont.setBold(true); |
|
QFontMetrics fm(boldFont); |
|
int spacing = 8; |
|
int width = 60 + spacing + 2; |
|
int iconHeight = minimum ? 0 : 32; |
|
return QSize(width, iconHeight + spacing + fm.height()); |
|
} |
|
|
|
void FancyTabBar::paintEvent(QPaintEvent* event) |
|
{ |
|
Q_UNUSED(event) |
|
QPainter p(this); |
|
|
|
for (int i = 0; i < count(); ++i) |
|
if (i != currentIndex()) { |
|
paintTab(&p, i); |
|
} |
|
|
|
// paint active tab last, since it overlaps the neighbors |
|
if (currentIndex() != -1) { |
|
paintTab(&p, currentIndex()); |
|
} |
|
} |
|
|
|
void FancyTab::enterEvent(QEvent*) |
|
{ |
|
fadeIn(); |
|
} |
|
|
|
void FancyTab::leaveEvent(QEvent*) |
|
{ |
|
fadeOut(); |
|
} |
|
|
|
QSize FancyTabBar::sizeHint() const |
|
{ |
|
QSize sh = tabSizeHint(); |
|
return QSize(sh.width(), sh.height() * m_tabs.count()); |
|
} |
|
|
|
QSize FancyTabBar::minimumSizeHint() const |
|
{ |
|
QSize sh = tabSizeHint(true); |
|
return QSize(sh.width(), sh.height() * m_tabs.count()); |
|
} |
|
|
|
QRect FancyTabBar::tabRect(int index) const |
|
{ |
|
return m_tabs[index]->geometry(); |
|
} |
|
|
|
QString FancyTabBar::tabToolTip(int index) const |
|
{ |
|
return m_tabs[index]->toolTip(); |
|
} |
|
|
|
void FancyTabBar::setTabToolTip(int index, const QString &toolTip) |
|
{ |
|
m_tabs[index]->setToolTip(toolTip); |
|
} |
|
|
|
// This keeps the sidebar responsive since |
|
// we get a repaint before loading the |
|
// mode itself |
|
void FancyTabBar::emitCurrentIndex() |
|
{ |
|
emit currentChanged(m_currentIndex); |
|
} |
|
|
|
void FancyTabBar::mousePressEvent(QMouseEvent* e) |
|
{ |
|
e->accept(); |
|
for (int index = 0; index < m_tabs.count(); ++index) { |
|
if (tabRect(index).contains(e->pos())) { |
|
m_currentIndex = index; |
|
update(); |
|
m_triggerTimer.start(0); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
void FancyTabBar::addTab(const QIcon &icon, const QString &label) |
|
{ |
|
FancyTab* tab = new FancyTab(this); |
|
tab->icon = icon; |
|
tab->text = label; |
|
m_tabs.append(tab); |
|
qobject_cast<QVBoxLayout*>(layout())->insertWidget(layout()->count() - 1, tab); |
|
} |
|
|
|
void FancyTabBar::addSpacer(int size) |
|
{ |
|
qobject_cast<QVBoxLayout*>(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::ElideMiddle, 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 QT_QUPZILLA_EXPORT FancyColorButton : public QWidget |
|
{ |
|
public: |
|
FancyColorButton(QWidget* parent) |
|
: m_parent(parent) { |
|
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); |
|
} |
|
|
|
void mousePressEvent(QMouseEvent* ev) { |
|
if (ev->modifiers() & Qt::ShiftModifier) { |
|
Utils::StyleHelper::setBaseColor(QColorDialog::getColor(Utils::StyleHelper::requestedBaseColor(), m_parent)); |
|
} |
|
} |
|
private: |
|
QWidget* m_parent; |
|
}; |
|
|
|
////// |
|
// FancyTabWidget |
|
////// |
|
|
|
FancyTabWidget::FancyTabWidget(QWidget* parent) |
|
: QWidget(parent), |
|
mode_(Mode_None), |
|
tab_bar_(NULL), |
|
stack_(new QStackedLayout), |
|
side_widget_(new QWidget), |
|
side_layout_(new QVBoxLayout), |
|
top_layout_(new QVBoxLayout), |
|
use_background_(false), |
|
menu_(NULL), |
|
proxy_style_(new FancyTabProxyStyle) |
|
{ |
|
side_layout_->setSpacing(0); |
|
side_layout_->setMargin(0); |
|
side_layout_->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding)); |
|
|
|
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) |
|
{ |
|
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::current_index() const |
|
{ |
|
return stack_->currentIndex(); |
|
} |
|
|
|
void FancyTabWidget::SetCurrentIndex(int index) |
|
{ |
|
if (FancyTabBar* bar = qobject_cast<FancyTabBar*>(tab_bar_)) { |
|
bar->setCurrentIndex(index); |
|
} |
|
else if (QTabBar* bar = qobject_cast<QTabBar*>(tab_bar_)) { |
|
bar->setCurrentIndex(index); |
|
} |
|
else { |
|
stack_->setCurrentIndex(index); |
|
} |
|
} |
|
|
|
void FancyTabWidget::ShowWidget(int index) |
|
{ |
|
stack_->setCurrentIndex(index); |
|
emit CurrentChanged(index); |
|
} |
|
|
|
void FancyTabWidget::AddBottomWidget(QWidget* widget) |
|
{ |
|
top_layout_->addWidget(widget); |
|
} |
|
|
|
void FancyTabWidget::SetMode(Mode mode) |
|
{ |
|
// Remove previous tab bar |
|
delete tab_bar_; |
|
tab_bar_ = NULL; |
|
|
|
use_background_ = false; |
|
|
|
// Create new tab bar |
|
switch (mode) { |
|
case Mode_None: |
|
default: |
|
qDebug() << "Unknown fancy tab mode" << mode; |
|
// fallthrough |
|
|
|
case Mode_LargeSidebar: { |
|
FancyTabBar* bar = new FancyTabBar(this); |
|
side_layout_->insertWidget(0, bar); |
|
tab_bar_ = bar; |
|
|
|
foreach(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; |
|
} |
|
|
|
tab_bar_->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); |
|
|
|
mode_ = mode; |
|
emit ModeChanged(mode); |
|
update(); |
|
} |
|
|
|
void FancyTabWidget::contextMenuEvent(QContextMenuEvent* e) |
|
{ |
|
Q_UNUSED(e) |
|
// if (!menu_) { |
|
// menu_ = new QMenu(this); |
|
|
|
// QSignalMapper* mapper = new QSignalMapper(this); |
|
// QActionGroup* group = new QActionGroup(this); |
|
// AddMenuItem(mapper, group, tr("Large sidebar"), Mode_LargeSidebar); |
|
// AddMenuItem(mapper, group, tr("Small sidebar"), Mode_SmallSidebar); |
|
// AddMenuItem(mapper, group, tr("Plain sidebar"), Mode_PlainSidebar); |
|
// AddMenuItem(mapper, group, tr("Tabs on top"), Mode_Tabs); |
|
// AddMenuItem(mapper, group, tr("Icons on top"), Mode_IconOnlyTabs); |
|
// menu_->addActions(group->actions()); |
|
|
|
// connect(mapper, SIGNAL(mapped(int)), SLOT(SetMode(int))); |
|
// } |
|
|
|
// menu_->popup(e->globalPos()); |
|
} |
|
|
|
void FancyTabWidget::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); |
|
|
|
if (shape == QTabBar::RoundedWest) { |
|
bar->setIconSize(QSize(22, 22)); |
|
} |
|
|
|
if (fancy) { |
|
bar->setStyle(proxy_style_); |
|
} |
|
|
|
if (shape == QTabBar::RoundedNorth) { |
|
top_layout_->insertWidget(0, bar); |
|
} |
|
else { |
|
side_layout_->insertWidget(0, bar); |
|
} |
|
|
|
foreach(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; |
|
}
|
|
|