Animate sidebar tabs independently

This commit is contained in:
Jens Bache-Wiig
2010-02-17 18:41:41 +01:00
parent 915923a17c
commit 7899a2733b
3 changed files with 88 additions and 43 deletions

View File

@@ -116,19 +116,19 @@ void FancyToolButton::paintEvent(QPaintEvent *event)
if (isDown() || isChecked()) { if (isDown() || isChecked()) {
painter.save(); painter.save();
QColor whiteOverlay(Qt::black); QColor color(Qt::black);
whiteOverlay.setAlpha(30); color.setAlpha(15);
QRect roundRect = rect().adjusted(5, 3, -5, -3); QRect roundRect = rect().adjusted(5, 3, -5, -3);
painter.translate(0.5, 0.5); painter.translate(0.5, 0.5);
painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QColor(255, 255, 255, 40)); painter.setPen(QColor(255, 255, 255, 20));
static int rounding = 3; static int rounding = 3;
painter.drawRoundedRect(roundRect.adjusted(-1, -1, 1, 1), rounding, rounding); painter.drawRoundedRect(roundRect.adjusted(-1, -1, 1, 1), rounding, rounding);
painter.setPen(QColor(0, 0, 0, 40)); painter.setPen(QColor(0, 0, 0, 20));
painter.setBrush(QColor(0, 0, 0, 30)); painter.setBrush(QColor(0, 0, 0, 15));
painter.drawRoundedRect(roundRect.adjusted(1, 1, 0, 0), rounding, rounding); painter.drawRoundedRect(roundRect.adjusted(1, 1, 0, 0), rounding, rounding);
whiteOverlay.setAlpha(150); color.setAlpha(75);
painter.setPen(whiteOverlay); painter.setPen(color);
painter.setBrush(Qt::NoBrush); painter.setBrush(Qt::NoBrush);
painter.drawRoundedRect(roundRect, 3, 3); painter.drawRoundedRect(roundRect, 3, 3);
painter.restore(); painter.restore();

View File

@@ -53,6 +53,24 @@ using namespace Internal;
const int FancyTabBar::m_rounding = 22; const int FancyTabBar::m_rounding = 22;
const int FancyTabBar::m_textPadding = 4; const int FancyTabBar::m_textPadding = 4;
void FancyTab::fadeIn()
{
QPropertyAnimation *animation;
animation = new QPropertyAnimation(this, "fader");
animation->setDuration(160);
animation->setEndValue(25);
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
void FancyTab::fadeOut()
{
QPropertyAnimation *animation;
animation = new QPropertyAnimation(this, "fader");
animation->setDuration(225);
animation->setEndValue(0);
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
FancyTabBar::FancyTabBar(QWidget *parent) FancyTabBar::FancyTabBar(QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
@@ -63,10 +81,6 @@ FancyTabBar::FancyTabBar(QWidget *parent)
setMinimumWidth(qMax(2 * m_rounding, 40)); setMinimumWidth(qMax(2 * m_rounding, 40));
setAttribute(Qt::WA_Hover, true); setAttribute(Qt::WA_Hover, true);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
m_hoverControl.setFrameRange(0, 20);
m_hoverControl.setDuration(130);
m_hoverControl.setCurveShape(QTimeLine::EaseInCurve);
connect(&m_hoverControl, SIGNAL(frameChanged(int)), this, SLOT(updateHover()));
setMouseTracking(true); // Needed for hover events setMouseTracking(true); // Needed for hover events
} }
@@ -115,15 +129,15 @@ void FancyTabBar::mouseMoveEvent(QMouseEvent *e)
} }
} }
m_hoverControl.stop(); if (validIndex(m_hoverIndex))
m_hoverIndex = newHover; m_tabs[m_hoverIndex]->fadeOut();
update(m_hoverRect);
m_hoverRect = QRect();
if (m_hoverIndex >=0) { m_hoverIndex = newHover;
if (validIndex(m_hoverIndex)) {
m_tabs[m_hoverIndex]->fadeIn();
QRect oldHoverRect = m_hoverRect; QRect oldHoverRect = m_hoverRect;
m_hoverRect = tabRect(m_hoverIndex); m_hoverRect = tabRect(m_hoverIndex);
m_hoverControl.start();
} }
} }
} }
@@ -131,7 +145,7 @@ void FancyTabBar::mouseMoveEvent(QMouseEvent *e)
bool FancyTabBar::event(QEvent *event) bool FancyTabBar::event(QEvent *event)
{ {
if (event->type() == QEvent::ToolTip) { if (event->type() == QEvent::ToolTip) {
if (m_hoverIndex >= 0 && m_hoverIndex < m_tabs.count()) { if (validIndex(m_hoverIndex)) {
QString tt = tabToolTip(m_hoverIndex); QString tt = tabToolTip(m_hoverIndex);
if (!tt.isEmpty()) { if (!tt.isEmpty()) {
QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), tt, this); QToolTip::showText(static_cast<QHelpEvent*>(event)->globalPos(), tt, this);
@@ -159,10 +173,14 @@ void FancyTabBar::enterEvent(QEvent *e)
void FancyTabBar::leaveEvent(QEvent *e) void FancyTabBar::leaveEvent(QEvent *e)
{ {
Q_UNUSED(e) Q_UNUSED(e)
if (m_hoverIndex >= 0) { if (validIndex(m_hoverIndex)) {
m_hoverIndex = -1; m_hoverIndex = -1;
update(m_hoverRect); update(m_hoverRect);
m_hoverRect = QRect(); m_hoverRect = QRect();
for (int i = 0 ; i < m_tabs.count() ; ++i) {
if (m_tabs[i]->fader() > 0)
m_tabs[i]->fadeOut();
}
} }
} }
@@ -202,11 +220,14 @@ void FancyTabBar::mousePressEvent(QMouseEvent *e)
void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
{ {
if (!validIndex(tabIndex)) {
qWarning("invalid index");
return;
}
painter->save(); painter->save();
QRect rect = tabRect(tabIndex); QRect rect = tabRect(tabIndex);
bool selected = (tabIndex == m_currentIndex); bool selected = (tabIndex == m_currentIndex);
bool hover = (tabIndex == m_hoverIndex);
bool enabled = isTabEnabled(tabIndex); bool enabled = isTabEnabled(tabIndex);
#ifdef Q_WS_MAC #ifdef Q_WS_MAC
@@ -214,8 +235,7 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
#endif #endif
QColor hoverColor; QColor hoverColor;
if (hover) hoverColor = QColor(255, 255, 255, m_tabs[tabIndex]->fader());
hoverColor = QColor(255, 255, 255, m_hoverControl.currentFrame());
if (selected) { if (selected) {
//background //background
@@ -245,8 +265,19 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
painter->setPen(QColor(255, 255, 255, 50)); painter->setPen(QColor(255, 255, 255, 50));
painter->drawLine(rect.bottomLeft() + QPoint(0,1), rect.bottomRight() + QPoint(0,1)); painter->drawLine(rect.bottomLeft() + QPoint(0,1), rect.bottomRight() + QPoint(0,1));
} else { } else {
if (hover && enabled) if (enabled) {
painter->fillRect(rect, hoverColor); painter->save();
QColor whiteOverlay(Qt::white);
whiteOverlay.setAlpha(int(m_tabs[tabIndex]->fader()/2));
QRect roundRect = rect.adjusted(5, 3, -5, -3);
painter->translate(0.5, 0.5);
painter->setRenderHint(QPainter::Antialiasing);
painter->setBrush(whiteOverlay);
whiteOverlay.setAlpha(int(m_tabs[tabIndex]->fader()));
painter->setPen(whiteOverlay);
painter->drawRoundedRect(roundRect, 3, 3);
painter->restore();
}
} }
QString tabText(this->tabText(tabIndex)); QString tabText(this->tabText(tabIndex));
@@ -291,7 +322,7 @@ void FancyTabBar::setTabEnabled(int index, bool enable)
Q_ASSERT(index >= 0); Q_ASSERT(index >= 0);
if (index < m_tabs.size() && index >= 0) { if (index < m_tabs.size() && index >= 0) {
m_tabs[index].enabled = enable; m_tabs[index]->enabled = enable;
update(tabRect(index)); update(tabRect(index));
} }
} }
@@ -302,7 +333,7 @@ bool FancyTabBar::isTabEnabled(int index) const
Q_ASSERT(index >= 0); Q_ASSERT(index >= 0);
if (index < m_tabs.size() && index >= 0) if (index < m_tabs.size() && index >= 0)
return m_tabs[index].enabled; return m_tabs[index]->enabled;
return false; return false;
} }

View File

@@ -44,12 +44,26 @@ QT_END_NAMESPACE
namespace Core { namespace Core {
namespace Internal { namespace Internal {
struct FancyTab{ class FancyTab : public QObject{
QIcon icon; Q_OBJECT
QString text;
QString toolTip; Q_PROPERTY(float fader READ fader WRITE setFader)
bool enabled; public:
}; FancyTab(QWidget *tabbar) : enabled(false), tabbar(tabbar), m_fader(0) {}
float fader() { return m_fader; }
void setFader(float value) { m_fader = value; tabbar->update(); }
void fadeIn();
void fadeOut();
QIcon icon;
QString text;
QString toolTip;
bool enabled;
private:
QWidget *tabbar;
float m_fader;
};
class FancyTabBar : public QWidget class FancyTabBar : public QWidget
{ {
@@ -67,6 +81,7 @@ public:
void mouseMoveEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *);
void enterEvent(QEvent *); void enterEvent(QEvent *);
void leaveEvent(QEvent *); void leaveEvent(QEvent *);
bool validIndex(int index) const { return index >= 0 && index < m_tabs.count(); }
QSize sizeHint() const; QSize sizeHint() const;
QSize minimumSizeHint() const; QSize minimumSizeHint() const;
@@ -75,24 +90,24 @@ public:
bool isTabEnabled(int index) const; bool isTabEnabled(int index) const;
void insertTab(int index, const QIcon &icon, const QString &label) { void insertTab(int index, const QIcon &icon, const QString &label) {
FancyTab tab; FancyTab *tab = new FancyTab(this);
tab.enabled = true; tab->icon = icon;
tab.icon = icon; tab->text = label;
tab.text = label;
m_tabs.insert(index, tab); m_tabs.insert(index, tab);
} }
void setEnabled(int index, bool enabled); void setEnabled(int index, bool enabled);
void removeTab(int index) { void removeTab(int index) {
m_tabs.removeAt(index); FancyTab *tab = m_tabs.takeAt(index);
delete tab;
} }
void setCurrentIndex(int index); void setCurrentIndex(int index);
int currentIndex() const { return m_currentIndex; } int currentIndex() const { return m_currentIndex; }
void setTabToolTip(int index, QString toolTip) { m_tabs[index].toolTip = toolTip; } void setTabToolTip(int index, QString toolTip) { m_tabs[index]->toolTip = toolTip; }
QString tabToolTip(int index) const { return m_tabs.at(index).toolTip; } QString tabToolTip(int index) const { return m_tabs.at(index)->toolTip; }
QIcon tabIcon(int index) const {return m_tabs.at(index).icon; } QIcon tabIcon(int index) const {return m_tabs.at(index)->icon; }
QString tabText(int index) const { return m_tabs.at(index).text; } QString tabText(int index) const { return m_tabs.at(index)->text; }
int count() const {return m_tabs.count(); } int count() const {return m_tabs.count(); }
QRect tabRect(int index) const; QRect tabRect(int index) const;
@@ -105,11 +120,10 @@ public slots:
private: private:
static const int m_rounding; static const int m_rounding;
static const int m_textPadding; static const int m_textPadding;
QTimeLine m_hoverControl;
QRect m_hoverRect; QRect m_hoverRect;
int m_hoverIndex; int m_hoverIndex;
int m_currentIndex; int m_currentIndex;
QList<FancyTab> m_tabs; QList<FancyTab*> m_tabs;
QSize tabSizeHint(bool minimum = false) const; QSize tabSizeHint(bool minimum = false) const;