Refactored panel context button bar animation and now it is implemented in a lot...
authorPekka Nissinen <pekka.nissinen@ixonos.com>
Sun, 29 Aug 2010 19:48:56 +0000 (22:48 +0300)
committerPekka Nissinen <pekka.nissinen@ixonos.com>
Sun, 29 Aug 2010 19:48:56 +0000 (22:48 +0300)
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
src/ui/panelcontextbuttonbar.h
src/ui/tabbedpanel.cpp
src/ui/tabbedpanel.h

index 03dfd1e..e6f544a 100644 (file)
 
 #include <QDebug>
 #include <QPainter>
+#include <QPropertyAnimation>
+#include <QSignalTransition>
+#include <QStateMachine>
 
 #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();
+    }
 }
index 7b4a4ba..fbdd58e 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <QWidget>
 
+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
 };
 
index 2c69d38..0b553de 100644 (file)
@@ -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<PanelBase *>(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();
     }
 }
index aaeb990..b7473cc 100644 (file)
@@ -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