From e9bb16d340e621fc7561161a1bb31efcce0c544e Mon Sep 17 00:00:00 2001 From: Pekka Nissinen Date: Sun, 29 Aug 2010 22:48:56 +0300 Subject: [PATCH] Refactored panel context button bar animation and now it is implemented in a lot nicer way. All the animation stuff (statemachine, states, signal transitions etc) are relocated inside the PanelContextButtonBar class instead of TabbedPanel class. Also removed a slot (repositionContextButtonBar) that isn't needed anymore due to recent architectural changes. --- src/ui/panelcontextbuttonbar.cpp | 105 ++++++++++++++++++++++++++++++++++++-- src/ui/panelcontextbuttonbar.h | 59 ++++++++++++++++++++- src/ui/tabbedpanel.cpp | 94 ++++++++++++++++++---------------- src/ui/tabbedpanel.h | 27 +++------- 4 files changed, 216 insertions(+), 69 deletions(-) diff --git a/src/ui/panelcontextbuttonbar.cpp b/src/ui/panelcontextbuttonbar.cpp index 03dfd1e..e6f544a 100644 --- a/src/ui/panelcontextbuttonbar.cpp +++ b/src/ui/panelcontextbuttonbar.cpp @@ -21,21 +21,83 @@ #include #include +#include +#include +#include #include "panelcontextbuttonbar.h" -const int CONTEXT_BUTTON_BAR_WIDTH = 78; +const int PANEL_CONTEXT_BUTTON_BAR_WIDTH = 78; PanelContextButtonBar::PanelContextButtonBar(QWidget *parent) : QWidget(parent), + m_visible(false), m_contextButtons(0) { qDebug() << __PRETTY_FUNCTION__; + setFixedWidth(PANEL_CONTEXT_BUTTON_BAR_WIDTH); + m_barTile.load(":/res/images/panel_context_button_bar_tile.png"); m_barTop.load(":/res/images/panel_context_button_bar_top.png"); - setFixedWidth(CONTEXT_BUTTON_BAR_WIDTH); + // --- BAR ANIMATION --- + QStateMachine *stateMachine = new QStateMachine(this); + + m_stateHidden = new QState(stateMachine); + m_stateVisible = new QState(stateMachine); + + QPropertyAnimation *animation = new QPropertyAnimation(this, "pos", this); + + stateMachine->setInitialState(m_stateHidden); + + QSignalTransition *showSignalTransition = m_stateHidden->addTransition(this, + SIGNAL(toggleState()), + m_stateVisible); + showSignalTransition->addAnimation(animation); + + QSignalTransition *hideSignalTransition = m_stateVisible->addTransition(this, + SIGNAL(toggleState()), + m_stateHidden); + hideSignalTransition->addAnimation(animation); + + connect(animation, SIGNAL(finished()), + this, SLOT(contextButtonBarStateChanged())); + + QPoint hiddenPosition(this->pos().x(), this->pos().y()); + m_stateHidden->assignProperty(this, "pos", hiddenPosition); + + QPoint visiblePosition(this->pos().x(), this->pos().y() - height()); + m_stateVisible->assignProperty(this, "pos", visiblePosition); + + stateMachine->start(); +} + +void PanelContextButtonBar::contextButtonBarStateChanged() +{ + qDebug() << __PRETTY_FUNCTION__; + + if (m_visible) + emit barVisible(); + else + emit barHidden(); +} + +void PanelContextButtonBar::hideContextButtonBar() +{ + qDebug() << __PRETTY_FUNCTION__; + + if (m_visible) { + m_visible = false; + emit toggleState(); + } +} + +bool PanelContextButtonBar::isBarVisible() const +{ + qDebug() << __PRETTY_FUNCTION__; + + return m_visible; } void PanelContextButtonBar::paintEvent(QPaintEvent *event) @@ -45,7 +107,6 @@ void PanelContextButtonBar::paintEvent(QPaintEvent *event) Q_UNUSED(event); const int CONTEXT_BUTTON_BAR_RECT_X = 0; - const int CONTEXT_BUTTON_BAR_TOP_HEIGHT = 32; const int CONTEXT_BUTTON_BAR_TOP_X = 0; const int CONTEXT_BUTTON_BAR_TOP_Y = 0; @@ -53,13 +114,39 @@ void PanelContextButtonBar::paintEvent(QPaintEvent *event) QPainter painter(this); m_barRect.setRect(CONTEXT_BUTTON_BAR_RECT_X, CONTEXT_BUTTON_BAR_TOP_HEIGHT, - CONTEXT_BUTTON_BAR_WIDTH, height() - CONTEXT_BUTTON_BAR_TOP_HEIGHT); + PANEL_CONTEXT_BUTTON_BAR_WIDTH, height() - CONTEXT_BUTTON_BAR_TOP_HEIGHT); painter.drawPixmap(CONTEXT_BUTTON_BAR_TOP_X, CONTEXT_BUTTON_BAR_TOP_Y, m_barTop); painter.drawTiledPixmap(m_barRect, m_barTile); } +void PanelContextButtonBar::move(int x, int y) +{ + qDebug() << __PRETTY_FUNCTION__; + + if (m_visible) + QWidget::move(x, y - height()); + else + QWidget::move(x, y); + + QPoint hiddenPosition(x, y); + m_stateHidden->assignProperty(this, "pos", hiddenPosition); + + QPoint visiblePosition(x, y - height()); + m_stateVisible->assignProperty(this, "pos", visiblePosition); +} + +void PanelContextButtonBar::resizeEvent(QResizeEvent *event) +{ + qDebug() << __PRETTY_FUNCTION__; + + QWidget::resizeEvent(event); + + QPoint visiblePosition(pos().x(), pos().y() - height()); + m_stateVisible->assignProperty(this, "pos", visiblePosition); +} + void PanelContextButtonBar::setContextButtons(QWidget *contextButtons) { qDebug() << __PRETTY_FUNCTION__; @@ -74,6 +161,14 @@ void PanelContextButtonBar::setContextButtons(QWidget *contextButtons) m_contextButtons->setVisible(true); setFixedHeight(m_contextButtons->height()); +} + +void PanelContextButtonBar::showContextButtonBar() +{ + qDebug() << __PRETTY_FUNCTION__; - emit positionChangeRequested(); + if (!m_visible) { + m_visible = true; + emit toggleState(); + } } diff --git a/src/ui/panelcontextbuttonbar.h b/src/ui/panelcontextbuttonbar.h index 7b4a4ba..fbdd58e 100644 --- a/src/ui/panelcontextbuttonbar.h +++ b/src/ui/panelcontextbuttonbar.h @@ -24,6 +24,8 @@ #include +class QState; + class PanelContextButtonBar : public QWidget { Q_OBJECT @@ -47,35 +49,88 @@ protected: */ void paintEvent(QPaintEvent *event); + /** + * @brief Resizes the bar + * + * @param event Resize event + */ + void resizeEvent(QResizeEvent *event); + /******************************************************************************* * MEMBER FUNCTIONS AND SLOTS ******************************************************************************/ public: /** + * @brief Hides the context button bar + */ + void hideContextButtonBar(); + + /** + * @brief Returns the current state of the context button bar + * + * @return Current state + */ + bool isBarVisible() const; + + /** + * @brief Moves the context button bar to desired position + * + * @param x Horizontal position + * @param y Vertical position + */ + void move(int x, int y); + + /** * @brief Sets the context buttons to the context button bar * * @param contextButtons Pointer to context buttons */ void setContextButtons(QWidget *contextButtons); + /** + * @brief Shows the context button bar + */ + void showContextButtonBar(); + +private slots: + /** + * @brief Internal slot used to set the context button bar state + */ + void contextButtonBarStateChanged(); + /******************************************************************************* * SIGNALS ******************************************************************************/ signals: /** - * @brief This signal is called when context button bar needs to be repositioned + * @brief Signal that is sent when context button bar is hidden */ - void positionChangeRequested(); + void barHidden(); + + /** + * @brief Signal that is sent when context button bar is visible + */ + void barVisible(); + + /** + * @brief Signal that is sent when the context button bar state must be changed + */ + void toggleState(); /******************************************************************************* * DATA MEMBERS ******************************************************************************/ private: + bool m_visible; ///< Current state of the context button bar + QPixmap m_barTile; ///< Pixmap for button bar QPixmap m_barTop; ///< Pixmap for button bar top QRect m_barRect; ///< Rect for the button bar + QState *m_stateHidden; ///< State of the hidden context button bar + QState *m_stateVisible; ///< State of the visible context button bar + QWidget *m_contextButtons; ///< Widget for context buttons }; diff --git a/src/ui/tabbedpanel.cpp b/src/ui/tabbedpanel.cpp index 2c69d38..0b553de 100644 --- a/src/ui/tabbedpanel.cpp +++ b/src/ui/tabbedpanel.cpp @@ -38,7 +38,8 @@ const int PANEL_CONTEXT_BUTTON_BAR_LEFT_X = 1; TabbedPanel::TabbedPanel(QWidget *parent) : QWidget(parent), - m_open(false) + m_open(false), + m_closeRequestPending(false) { qDebug() << __PRETTY_FUNCTION__; @@ -68,44 +69,45 @@ TabbedPanel::TabbedPanel(QWidget *parent) // --- CONTEXT BUTTON BAR --- m_panelContextButtonBar = new PanelContextButtonBar(this); - m_panelContextButtonBar->setVisible(false); - m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, - PANEL_HEIGHT - m_panelContextButtonBar->height()); + m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, PANEL_HEIGHT); - connect(m_panelContextButtonBar, SIGNAL(positionChangeRequested()), - this, SLOT(repositionContextButtonBar())); + connect(m_panelContextButtonBar, SIGNAL(barHidden()), + this, SLOT(closePanel())); // --- PANEL CONTENT --- m_panelContentStack = new PanelContentStack(this); m_panelContentStack->move(PANEL_TAB_WIDTH + PANEL_BAR_WIDTH, PANEL_TOP_Y); // --- PANEL ANIMATION --- - m_panelStateMachine = new QStateMachine(this); + QStateMachine *panelStateMachine = new QStateMachine(this); - m_panelStateClosed = new QState(m_panelStateMachine); - m_panelStateOpened = new QState(m_panelStateMachine); + m_stateClosed = new QState(panelStateMachine); + m_stateOpened = new QState(panelStateMachine); - m_panelAnimation = new QPropertyAnimation(this, "pos", this); + QPropertyAnimation *panelAnimation = new QPropertyAnimation(this, "pos", this); - m_panelStateMachine->setInitialState(m_panelStateClosed); + panelStateMachine->setInitialState(m_stateClosed); - m_panelTransitionOpen = m_panelStateClosed->addTransition(this, SIGNAL(toggleState()), - m_panelStateOpened); - m_panelTransitionOpen->addAnimation(m_panelAnimation); + QSignalTransition *panelTransitionOpen = m_stateClosed->addTransition(this, + SIGNAL(toggleState()), + m_stateOpened); + panelTransitionOpen->addAnimation(panelAnimation); - m_panelTransitionClose = m_panelStateOpened->addTransition(this, SIGNAL(toggleState()), - m_panelStateClosed); - m_panelTransitionClose->addAnimation(m_panelAnimation); + QSignalTransition *panelTransitionClose = m_stateOpened->addTransition(this, + SIGNAL(toggleState()), + m_stateClosed); + panelTransitionClose->addAnimation(panelAnimation); - connect(m_panelAnimation, SIGNAL(finished()), + connect(panelAnimation, SIGNAL(finished()), this, SLOT(stateChanged())); - m_panelStateClosed->assignProperty(this, "pos", - QPoint(PANEL_CLOSED_X, PANEL_TOP_PADDING)); - m_panelStateOpened->assignProperty(this, "pos", - QPoint(PANEL_OPENED_X, PANEL_TOP_PADDING)); + QPoint closedPosition(PANEL_CLOSED_X, PANEL_TOP_PADDING); + m_stateClosed->assignProperty(this, "pos", closedPosition); - m_panelStateMachine->start(); + QPoint openedPosition(PANEL_OPENED_X, PANEL_TOP_PADDING); + m_stateOpened->assignProperty(this, "pos", openedPosition); + + panelStateMachine->start(); } int TabbedPanel::addTab(QWidget *widget, const QIcon& icon) @@ -121,8 +123,19 @@ void TabbedPanel::closePanel() { qDebug() << __PRETTY_FUNCTION__; - if (m_open) + if (m_open) { + m_open = false; + + if (m_panelContextButtonBar->isBarVisible()) { + m_closeRequestPending = true; + m_panelContextButtonBar->hideContextButtonBar(); + } else { + emit toggleState(); + } + } else if (m_closeRequestPending) { + m_closeRequestPending = false; emit toggleState(); + } } int TabbedPanel::insertTab(int index, QWidget *widget, const QIcon& icon) @@ -139,7 +152,14 @@ void TabbedPanel::openPanel(QWidget *widget) { qDebug() << __PRETTY_FUNCTION__; - m_panelTabBar->selectTab(m_panelContentStack->indexOf(widget)); + if (widget) { + m_panelTabBar->selectTab(m_panelContentStack->indexOf(widget)); + } else if (!m_open) { + if (!m_closeRequestPending) { + m_open = true; + emit toggleState(); + } + } } void TabbedPanel::removeTab(int index) @@ -152,14 +172,6 @@ void TabbedPanel::removeTab(int index) } } -void TabbedPanel::repositionContextButtonBar() -{ - qDebug() << __PRETTY_FUNCTION__; - - m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, - height() - m_panelContextButtonBar->height()); -} - void TabbedPanel::resizePanel(const QSize &size) { qDebug() << __PRETTY_FUNCTION__; @@ -174,17 +186,16 @@ void TabbedPanel::resizePanel(const QSize &size) m_panelBar->resizeBar(size); - m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, - size.height() - m_panelContextButtonBar->height()); + m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, size.height()); m_panelContentStack->resizeContentStack(size); QPoint closedPosition(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING); - m_panelStateClosed->assignProperty(this, "pos", closedPosition); + m_stateClosed->assignProperty(this, "pos", closedPosition); QPoint openedPosition(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH, PANEL_TOP_PADDING); - m_panelStateOpened->assignProperty(this, "pos", openedPosition); + m_stateOpened->assignProperty(this, "pos", openedPosition); } void TabbedPanel::setCurrentIndex(int index) @@ -195,7 +206,7 @@ void TabbedPanel::setCurrentIndex(int index) m_panelContentStack->setCurrentIndex(index); if (!m_open) - emit toggleState(); + openPanel(); m_panelContextButtonBar->setContextButtons( static_cast(m_panelContentStack->widget(index))->contextButtons()); @@ -208,13 +219,10 @@ void TabbedPanel::stateChanged() { qDebug() << __PRETTY_FUNCTION__; - if (!m_open) { - m_open = true; - m_panelContextButtonBar->setVisible(true); + if (m_open) { + m_panelContextButtonBar->showContextButtonBar(); emit panelOpened(); } else { - m_open = false; - m_panelContextButtonBar->setVisible(false); emit panelClosed(); } } diff --git a/src/ui/tabbedpanel.h b/src/ui/tabbedpanel.h index aaeb990..b7473cc 100644 --- a/src/ui/tabbedpanel.h +++ b/src/ui/tabbedpanel.h @@ -119,11 +119,6 @@ public slots: private slots: /** - * @brief Repositions context button bar - */ - void repositionContextButtonBar(); - - /** * @brief Sets the panel at current index active * * @param index Index of the panel @@ -174,22 +169,16 @@ signals: * DATA MEMBERS ******************************************************************************/ private: - bool m_open; ///< Current state of the panel - - QPropertyAnimation *m_panelAnimation; ///< Animation for panel state changes - - QSignalTransition *m_panelTransitionClose; ///< Transition signal for closing the panel - QSignalTransition *m_panelTransitionOpen; ///< Transition signal for opening the panel - - QState *m_panelStateClosed; ///< State of the closed panel - QState *m_panelStateOpened; ///< State of the opened panel + bool m_open; ///< Current state of the panel + bool m_closeRequestPending; - QStateMachine *m_panelStateMachine; ///< State machine for sliding the panel + QState *m_stateClosed; ///< State of the closed panel + QState *m_stateOpened; ///< State of the opened panel - PanelBar *m_panelBar; ///< Widget for panel bar - PanelContentStack *m_panelContentStack; ///< Stack for panel widgets - PanelContextButtonBar * m_panelContextButtonBar;///< Widget for panel context button bar - PanelTabBar *m_panelTabBar; ///< Widget for panel tab bar + PanelBar *m_panelBar; ///< Widget for panel bar + PanelContentStack *m_panelContentStack; ///< Stack for panel widgets + PanelContextButtonBar * m_panelContextButtonBar; ///< Widget for panel context button bar + PanelTabBar *m_panelTabBar; ///< Widget for panel tab bar }; #endif // TABBEDPANEL_H -- 1.7.9.5