diff --git a/components/tab.cpp b/components/tab.cpp index 7f57be7..8cef378 100644 --- a/components/tab.cpp +++ b/components/tab.cpp @@ -1,18 +1,19 @@ -#include "tab.h" - -Tab::Tab(QWidget *parent) - : FlatButton(parent) -{ - setMinimumHeight(50); -} - -Tab::Tab(QString text, QWidget *parent) - : FlatButton(parent) -{ - setMinimumHeight(50); - setText(text); -} - -Tab::~Tab() -{ -} +//#include "tab.h" +// +//Tab::Tab(QWidget *parent) +// : FlatButton(parent) +//{ +// setMinimumHeight(50); +//} +// +//Tab::Tab(QString text, QWidget *parent) +// : FlatButton(parent) +//{ +// setMinimumHeight(50); +// setText(text); +//} +// +//Tab::~Tab() +//{ +//} +// diff --git a/components/tab.h b/components/tab.h index 3a312a6..b8e6063 100644 --- a/components/tab.h +++ b/components/tab.h @@ -1,18 +1,19 @@ -#ifndef TAB_H -#define TAB_H - -#include "flatbutton.h" - -class QWidget; - -class Tab : public FlatButton -{ - Q_OBJECT - -public: - explicit Tab(QWidget *parent = 0); - explicit Tab(QString text, QWidget *parent = 0); - ~Tab(); -}; - -#endif // TAB_H +//#ifndef TAB_H +//#define TAB_H +// +//#include "flatbutton.h" +// +//class QWidget; +// +//class Tab : public FlatButton +//{ +// Q_OBJECT +// +//public: +// explicit Tab(QWidget *parent = 0); +// explicit Tab(QString text, QWidget *parent = 0); +// ~Tab(); +//}; +// +//#endif // TAB_H +// diff --git a/components/tabs.cpp b/components/tabs.cpp index c2be51e..5253802 100644 --- a/components/tabs.cpp +++ b/components/tabs.cpp @@ -1,86 +1,193 @@ +#include "tabs.h" #include #include #include -#include "tabs.h" -#include "tab.h" +#include "tabs_p.h" +#include "tabs_internal.h" + +TabsPrivate::TabsPrivate(Tabs *q) + : q_ptr(q), + tab(-1) +{ +} + +void TabsPrivate::init() +{ + Q_Q(Tabs); + + delegate = new TabsDelegate(q); + + tabLayout = new QHBoxLayout; + q->setLayout(tabLayout); + tabLayout->setSpacing(0); + tabLayout->setMargin(0); +} Tabs::Tabs(QWidget *parent) : QWidget(parent), - _tabLayout(new QHBoxLayout), - _animation(new QPropertyAnimation(this)), - _tab(0), - _tween(1) + d_ptr(new TabsPrivate(this)) { - _animation->setPropertyName("tween"); - _animation->setEasingCurve(QEasingCurve::OutCirc); - _animation->setTargetObject(this); - _animation->setDuration(700); - - setLayout(_tabLayout); - _tabLayout->setSpacing(0); - _tabLayout->setMargin(0); + d_func()->init(); } Tabs::~Tabs() { } -void Tabs::addTab(Tab *tab) +void Tabs::addTab(const QString &text) { - _tabLayout->addWidget(tab); - connect(tab, SIGNAL(clicked()), this, SLOT(switchActiveTab())); + Q_D(Tabs); + + Tab *tab = new Tab(text); + tab->setCornerRadius(0); + d->tabLayout->addWidget(tab); + + if (-1 == d->tab) { + d->tab = 0; + d->delegate->updateInkBar(); + } + + connect(tab, SIGNAL(clicked()), this, SLOT(switchTab())); +} + +const QLayout *Tabs::tabLayout() const +{ + Q_D(const Tabs); + + return d->tabLayout; +} + +int Tabs::currentIndex() const +{ + Q_D(const Tabs); + + return d->tab; } void Tabs::paintEvent(QPaintEvent *event) { - Q_UNUSED(event) + Q_D(Tabs); QPainter painter(this); - painter.fillRect(_inkBarGeometry, Qt::black); -} + painter.fillRect(d->delegate->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); - } + QWidget::paintEvent(event); } void Tabs::moveEvent(QMoveEvent *event) { Q_UNUSED(event) - updateInkBar(); + Q_D(Tabs); + + d->delegate->updateInkBar(); } void Tabs::resizeEvent(QResizeEvent *event) { Q_UNUSED(event) - updateInkBar(); + Q_D(Tabs); + + d->delegate->updateInkBar(); } -void Tabs::updateInkBar() +void Tabs::switchTab() { - 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()-1, r.width(), 2); - } else { - const qreal left = _previousGeometry.left()*s + r.left()*_tween; - const qreal width = _previousGeometry.width()*s + r.width()*_tween; - _inkBarGeometry = QRect(left, r.bottom()-1, width, 2); - } - update(); + Q_D(Tabs); + + Tab *tab = static_cast(sender()); + if (tab) { + d->tab = d->tabLayout->indexOf(tab); + d->delegate->setInkBarGeometry(d->tabLayout->itemAt(d->tab)->geometry()); + emit currentChanged(d->tab); } } + +//#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()-1, r.width(), 2); +// } else { +// const qreal left = _previousGeometry.left()*s + r.left()*_tween; +// const qreal width = _previousGeometry.width()*s + r.width()*_tween; +// _inkBarGeometry = QRect(left, r.bottom()-1, width, 2); +// } +// update(); +// } +//} +// diff --git a/components/tabs.h b/components/tabs.h index 6213074..f357f63 100644 --- a/components/tabs.h +++ b/components/tabs.h @@ -3,45 +3,83 @@ #include -class QHBoxLayout; -class QPropertyAnimation; -class Tab; +class TabsPrivate; 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(const QString &text); - void addTab(Tab *tab); + const QLayout *tabLayout() const; + int currentIndex() const; + +signals: + void currentChanged(int); 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(); + const QScopedPointer d_ptr; -signals: - void currentChanged(int); +private slots: + void switchTab(); private: - void updateInkBar(); - - QHBoxLayout *const _tabLayout; - QPropertyAnimation *const _animation; - QRect _inkBarGeometry; - QRect _previousGeometry; - int _tab; - qreal _tween; + Q_DISABLE_COPY(Tabs) + Q_DECLARE_PRIVATE(Tabs) }; #endif // 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 +// diff --git a/components/tabs_internal.cpp b/components/tabs_internal.cpp index e69de29..c99ec5d 100644 --- a/components/tabs_internal.cpp +++ b/components/tabs_internal.cpp @@ -0,0 +1,78 @@ +#include "tabs_internal.h" +#include +#include +#include "tabs.h" + +TabsDelegate::TabsDelegate(Tabs *parent) + : QObject(parent), + tabs(parent), + _animation(new QPropertyAnimation(parent)), + _tween(0) +{ + _animation->setPropertyName("tween"); + _animation->setEasingCurve(QEasingCurve::OutCirc); + _animation->setTargetObject(this); + _animation->setDuration(700); +} + +TabsDelegate::~TabsDelegate() +{ +} + +void TabsDelegate::setTween(qreal tween) +{ + _tween = tween; + updateInkBar(); +} + +void TabsDelegate::setInkBarGeometry(const QRect &newGeometry) +{ + _previousGeometry = _inkBarGeometry; + _inkBarGeometry = newGeometry; + + _animation->stop(); + _animation->setStartValue(0); + _animation->setEndValue(1); + _animation->start(); +} + +void TabsDelegate::updateInkBar() +{ + QLayoutItem *item = tabs->tabLayout()->itemAt(tabs->currentIndex()); + if (item) { + const QRect &r = item->geometry(); + const qreal s = 1-_tween; + if (QAbstractAnimation::Running != _animation->state()) { + _inkBarGeometry = QRect(r.left(), r.bottom()-1, r.width(), 2); + } else { + const qreal left = _previousGeometry.left()*s + r.left()*_tween; + const qreal width = _previousGeometry.width()*s + r.width()*_tween; + _inkBarGeometry = QRect(left, r.bottom()-1, width, 2); + } + tabs->update(); + } +} + + +Tab::Tab(QWidget *parent) + : FlatButton(parent) +{ + init(); +} + +Tab::Tab(QString text, QWidget *parent) + : FlatButton(parent) +{ + init(); + + setText(text); +} + +Tab::~Tab() +{ +} + +void Tab::init() +{ + setMinimumHeight(50); +} diff --git a/components/tabs_internal.h b/components/tabs_internal.h index 596f49f..6ce1eae 100644 --- a/components/tabs_internal.h +++ b/components/tabs_internal.h @@ -1,4 +1,53 @@ #ifndef TABS_INTERNAL_H #define TABS_INTERNAL_H +#include +#include "flatbutton.h" + +class QPropertyAnimation; +class Tabs; + +class TabsDelegate : public QObject +{ + Q_OBJECT + + Q_PROPERTY(qreal tween WRITE setTween READ tween) + +public: + TabsDelegate(Tabs *parent); + ~TabsDelegate(); + + void setTween(qreal tween); + inline qreal tween() const { return _tween; } + + void setInkBarGeometry(const QRect &newGeometry); + inline QRect inkBarGeometry() const { return _inkBarGeometry; } + \ + void updateInkBar(); + +private: + Q_DISABLE_COPY(TabsDelegate) + + Tabs *const tabs; + QPropertyAnimation *_animation; + qreal _tween; + QRect _inkBarGeometry; + QRect _previousGeometry; +}; + +class Tab : public FlatButton +{ + Q_OBJECT + +public: + explicit Tab(QWidget *parent = 0); + explicit Tab(QString text, QWidget *parent = 0); + ~Tab(); + +private: + Q_DISABLE_COPY(Tab) + + void init(); +}; + #endif // TABS_INTERNAL_H diff --git a/components/tabs_p.h b/components/tabs_p.h index a9d2354..a2c1880 100644 --- a/components/tabs_p.h +++ b/components/tabs_p.h @@ -1,4 +1,26 @@ #ifndef TABS_P_H #define TABS_P_H +#include + +class QHBoxLayout; +class Tabs; +class TabsDelegate; + +class TabsPrivate +{ + Q_DISABLE_COPY(TabsPrivate) + Q_DECLARE_PUBLIC(Tabs) + +public: + TabsPrivate(Tabs *q); + + void init(); + + Tabs *const q_ptr; + TabsDelegate *delegate; + QHBoxLayout *tabLayout; + int tab; +}; + #endif // TABS_P_H diff --git a/examples/tabsexamples.cpp b/examples/tabsexamples.cpp index 72c2741..48cd2bd 100644 --- a/examples/tabsexamples.cpp +++ b/examples/tabsexamples.cpp @@ -27,9 +27,13 @@ TabsExamples::TabsExamples(QWidget *parent) layout->addLayout(stack); layout->setContentsMargins(0, 0, 0, 0); - tabs->addTab(new Tab("First")); - tabs->addTab(new Tab("Second")); - tabs->addTab(new Tab("Third")); + tabs->addTab("First"); + tabs->addTab("Second"); + tabs->addTab("Third"); + + //tabs->addTab(new Tab("First")); + //tabs->addTab(new Tab("Second")); + //tabs->addTab(new Tab("Third")); QScrollArea *area = new QScrollArea; area->setWidget(widget); diff --git a/qt-material-widgets.pro b/qt-material-widgets.pro index 1352628..1045721 100644 --- a/qt-material-widgets.pro +++ b/qt-material-widgets.pro @@ -55,7 +55,8 @@ SOURCES += main.cpp\ lib/theme.cpp \ components/slider_internal.cpp \ components/flatbutton_internal.cpp \ - components/toggle_internal.cpp + components/toggle_internal.cpp \ + components/tabs_internal.cpp HEADERS += mainwindow.h \ components/appbar.h \ @@ -110,7 +111,9 @@ HEADERS += mainwindow.h \ components/raisedbutton_p.h \ components/toggle_p.h \ components/toggle_internal.h \ - components/iconbutton_p.h + components/iconbutton_p.h \ + components/tabs_p.h \ + components/tabs_internal.h RESOURCES += \ resources.qrc