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.
#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)
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;
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__;
m_contextButtons->setVisible(true);
setFixedHeight(m_contextButtons->height());
+}
+
+void PanelContextButtonBar::showContextButtonBar()
+{
+ qDebug() << __PRETTY_FUNCTION__;
- emit positionChangeRequested();
+ if (!m_visible) {
+ m_visible = true;
+ emit toggleState();
+ }
}
#include <QWidget>
+class QState;
+
class PanelContextButtonBar : public QWidget
{
Q_OBJECT
*/
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
};
TabbedPanel::TabbedPanel(QWidget *parent)
: QWidget(parent),
- m_open(false)
+ m_open(false),
+ m_closeRequestPending(false)
{
qDebug() << __PRETTY_FUNCTION__;
// --- 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)
{
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)
{
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)
}
}
-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__;
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)
m_panelContentStack->setCurrentIndex(index);
if (!m_open)
- emit toggleState();
+ openPanel();
m_panelContextButtonBar->setContextButtons(
static_cast<PanelBase *>(m_panelContentStack->widget(index))->contextButtons());
{
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();
}
}
private slots:
/**
- * @brief Repositions context button bar
- */
- void repositionContextButtonBar();
-
- /**
* @brief Sets the panel at current index active
*
* @param index Index of the panel
* 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