From 754d01b3c27d78f4cf8b4563d2eb77544a739543 Mon Sep 17 00:00:00 2001 From: laserpants Date: Sat, 19 Mar 2016 13:52:53 +0300 Subject: [PATCH] implement Tabs --- tabs.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tabs.h | 47 +++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/tabs.cpp b/tabs.cpp index 4aec7af..a5073d8 100644 --- a/tabs.cpp +++ b/tabs.cpp @@ -1 +1,86 @@ +#include +#include +#include #include "tabs.h" +#include "tab.h" + +Tabs::Tabs(QWidget *parent) + : QWidget(parent), + _tabLayout(new QHBoxLayout), + _animation(new QPropertyAnimation(this)), + _tab(0), + _tween(1) +{ + _animation->setPropertyName("tween"); + _animation->setEasingCurve(QEasingCurve::OutCirc); + _animation->setTargetObject(this); + _animation->setDuration(700); + + setLayout(_tabLayout); + _tabLayout->setSpacing(0); + _tabLayout->setMargin(0); +} + +Tabs::~Tabs() +{ +} + +void Tabs::addTab(Tab *tab) +{ + _tabLayout->addWidget(tab); + connect(tab, SIGNAL(clicked()), this, SLOT(switchActiveTab())); +} + +void Tabs::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + painter.fillRect(_inkBarGeometry, Qt::black); +} + +void Tabs::switchActiveTab() +{ + Tab *tab = static_cast(sender()); + if (tab) { + _previousGeometry = _inkBarGeometry; + _tab = _tabLayout->indexOf(tab); + _inkBarGeometry = _tabLayout->itemAt(_tab)->geometry(); + _animation->stop(); + _animation->setStartValue(0); + _animation->setEndValue(1); + _animation->start(); + emit currentChanged(_tab); + } +} + +void Tabs::moveEvent(QMoveEvent *event) +{ + Q_UNUSED(event) + + updateInkBar(); +} + +void Tabs::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + + updateInkBar(); +} + +void Tabs::updateInkBar() +{ + QLayoutItem *item = _tabLayout->itemAt(_tab); + if (item) { + const QRect &r = item->geometry(); + const qreal s = 1-_tween; + if (QAbstractAnimation::Running != _animation->state()) { + _inkBarGeometry = QRect(r.left(), r.bottom()-3, r.width(), 4); + } else { + const qreal left = _previousGeometry.left()*s + r.left()*_tween; + const qreal width = _previousGeometry.width()*s + r.width()*_tween; + _inkBarGeometry = QRect(left, r.bottom()-3, width, 4); + } + update(); + } +} diff --git a/tabs.h b/tabs.h index e69de29..6213074 100644 --- a/tabs.h +++ b/tabs.h @@ -0,0 +1,47 @@ +#ifndef TABS_H +#define TABS_H + +#include + +class QHBoxLayout; +class QPropertyAnimation; +class Tab; + +class Tabs : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal tween WRITE setTween READ tween) + +public: + explicit Tabs(QWidget *parent = 0); + ~Tabs(); + + inline void setTween(qreal tween) { _tween = tween; updateInkBar(); } + inline qreal tween() const { return _tween; } + + void addTab(Tab *tab); + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void moveEvent(QMoveEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + +protected slots: + void switchActiveTab(); + +signals: + void currentChanged(int); + +private: + void updateInkBar(); + + QHBoxLayout *const _tabLayout; + QPropertyAnimation *const _animation; + QRect _inkBarGeometry; + QRect _previousGeometry; + int _tab; + qreal _tween; +}; + +#endif // TABS_H