Tuning the ListItemContextButtonBar look
[situare] / src / ui / tabbedpanel.cpp
index e753c68..3f130fc 100644 (file)
     USA.
 */
 
+#include <QAbstractButton>
+#include <QButtonGroup>
 #include <QDebug>
 #include <QPropertyAnimation>
+#include <QRegion>
 #include <QSignalTransition>
 #include <QStackedWidget>
 #include <QStateMachine>
 
+#include "listitemcontextbuttonbar.h"
 #include "panelbar.h"
-#include "panelcontent.h"
+#include "panelbase.h"
+#include "panelcontentstack.h"
+#include "panelcontextbuttonbar.h"
 #include "paneltabbar.h"
 
 #include "tabbedpanel.h"
 
+const int PANEL_CONTEXT_BUTTON_BAR_LEFT_X = 1;
+const int PANEL_TAB_BAR_TOP_SPACING = 8;
+
 TabbedPanel::TabbedPanel(QWidget *parent)
     : QWidget(parent),
-      m_isOpen(false)
+      m_open(false),
+      m_closeRequestPending(false)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    this->resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH, PANEL_HEIGHT);
-    this->move(PANEL_CLOSED_X, PANEL_TOP_PADDING);
+    const int PANEL_LEFT_X = 0;
+    const int PANEL_TOP_Y = 0;
 
-    // --- TABS ---
-    m_panelWidgetStack = new QStackedWidget(this);
+    resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH, PANEL_HEIGHT);
+    move(PANEL_CLOSED_X, PANEL_TOP_PADDING);
 
+    // --- TABS ---
     m_panelTabBar = new PanelTabBar(this);
+    m_panelTabBar->move(PANEL_LEFT_X, PANEL_TAB_BAR_TOP_SPACING);
 
     connect(m_panelTabBar, SIGNAL(currentChanged(int)),
             this, SLOT(setCurrentIndex(int)));
 
+    connect(m_panelTabBar, SIGNAL(sizeChangeRequested()),
+            this, SLOT(calculateMask()));
+
     connect(m_panelTabBar, SIGNAL(tabCloseRequested(int)),
              this, SLOT(closePanel()));
 
@@ -57,134 +72,232 @@ TabbedPanel::TabbedPanel(QWidget *parent)
 
     // --- BAR ---
     m_panelBar = new PanelBar(this);
-    m_panelBar->move(PANEL_TAB_WIDTH, 0);
+    m_panelBar->move(PANEL_TAB_BAR_WIDTH, PANEL_TOP_Y);
+
+    // --- GENERIC PANEL CONTEXT BUTTON BAR ---
+    m_panelContextButtonBar = new PanelContextButtonBar(this);
+    m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, PANEL_HEIGHT);
+
+    connect(m_panelContextButtonBar, SIGNAL(barHidden()),
+            this, SLOT(closePanel()));
+
+    connect(m_panelContextButtonBar, SIGNAL(positionChangeRequested()),
+            this, SLOT(repositionContextButtonBar()));
+
+    // --- LIST ITEM RELATED CONTEXT BUTTONS BAR ---
+    m_itemContextButtonBar = new ListItemContextButtonBar(this);
+    m_itemContextButtonBar->hide();
+
+    connect(this, SIGNAL(listItemSelectionChanged(bool)),
+            m_itemContextButtonBar, SLOT(onListItemSelectionChanged(bool)));
 
     // --- PANEL CONTENT ---
-    m_panelContent = new PanelContent(this);
-    m_panelContent->setContentWidget(m_panelWidgetStack);
-    m_panelContent->move(PANEL_TAB_WIDTH + PANEL_BAR_WIDTH, 0);
+    m_panelContentStack = new PanelContentStack(this);
+    m_panelContentStack->move(PANEL_TAB_BAR_WIDTH + PANEL_BAR_WIDTH, PANEL_TOP_Y);
+    m_panelContentStack->stackUnder(m_itemContextButtonBar);
 
     // --- 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);
+
+    QPoint openedPosition(PANEL_OPENED_X, PANEL_TOP_PADDING);
+    m_stateOpened->assignProperty(this, "pos", openedPosition);
 
-    m_panelStateMachine->start();
+    panelStateMachine->start();
 }
 
 int TabbedPanel::addTab(QWidget *widget, const QIcon& icon)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    return insertTab(-1, widget, icon);
+    const int APPEND_INDEX = -1;
+
+    return insertTab(APPEND_INDEX, widget, icon);
 }
 
-int TabbedPanel::insertTab(int index, QWidget *widget, const QIcon& icon)
+void TabbedPanel::calculateMask()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QRect panelTabBarRect = m_panelTabBar->rect();
+    QRect panelContextButtonBarRect = m_panelContextButtonBar->rect();
+    int panelContextButtonBarY = height() - panelContextButtonBarRect.height();
+
+    if (!m_open)
+        panelContextButtonBarY = height();
+
+    QRegion panelTabBarRegion(0, PANEL_TAB_BAR_TOP_SPACING,
+                         panelTabBarRect.width(), panelTabBarRect.height());
+    QRegion panelContextButtonBarRegion(0, panelContextButtonBarY,
+                                      panelContextButtonBarRect.width(),
+                                      panelContextButtonBarRect.height());
+    QRegion panelContentRegion(panelTabBarRect.right() + 1, 0,
+                               PANEL_WIDTH + PANEL_BAR_WIDTH, height());
+    QRegion panelRegion = panelTabBarRegion + panelContentRegion + panelContextButtonBarRegion;
+
+    setMask(panelRegion);
+}
+
+void TabbedPanel::closePanel()
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    if(!widget)
-        return -1;
+    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__;
 
-    index = m_panelWidgetStack->insertWidget(index, widget);
+    index = m_panelContentStack->insertWidget(index, widget);
     m_panelTabBar->insertTab(index, icon);
 
     return index;
 }
 
+void TabbedPanel::openPanel(QWidget *widget)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    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)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    if(QWidget *widget = m_panelWidgetStack->widget(index)) {
-        m_panelWidgetStack->removeWidget(widget);
+    if (QWidget *widget = m_panelContentStack->widget(index)) {
+        m_panelContentStack->removeWidget(widget);
         m_panelTabBar->removeTab(index);
     }
 }
 
-void TabbedPanel::closePanel()
+void TabbedPanel::repositionContextButtonBar()
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    if(m_isOpen)
-        emit toggleState();
+    m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, height());
+
+    calculateMask();
 }
 
-void TabbedPanel::showPanel(QWidget *widget)
+void TabbedPanel::resizePanel(const QSize &size)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    m_panelTabBar->selectTab(m_panelWidgetStack->indexOf(widget));
+    resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH,
+           size.height() - PANEL_TOP_PADDING - PANEL_BOTTOM_PADDING);
+
+    if (!m_open)
+        move(size.width() - PANEL_TAB_BAR_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
+    else
+        move(size.width() - PANEL_TAB_BAR_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH, PANEL_TOP_PADDING);
+
+    m_panelBar->resizeBar(size);
+
+    m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X, size.height());
+
+    m_panelContentStack->resizeContentStack(size);
+
+    QPoint closedPosition(size.width() - PANEL_TAB_BAR_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
+    m_stateClosed->assignProperty(this, "pos", closedPosition);
+
+    QPoint openedPosition(size.width() - PANEL_TAB_BAR_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
+                          PANEL_TOP_PADDING);
+    m_stateOpened->assignProperty(this, "pos", openedPosition);
+
+    calculateMask();
 }
 
 void TabbedPanel::setCurrentIndex(int index)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    if (index < m_panelWidgetStack->count() && index >= 0) {
-        m_panelWidgetStack->setCurrentIndex(index);
+    if ((index < m_panelContentStack->count()) && (index >= 0)) {
+        m_panelContentStack->setCurrentIndex(index);
 
-        if(!m_isOpen)
-            emit toggleState();
+        if (!m_open)
+            openPanel();
+
+        m_panelContextButtonBar->setContextButtons(
+                static_cast<PanelBase *>(m_panelContentStack->widget(index))->genericPanelButtons());
+
+        QWidget *itemContextButtons = static_cast<PanelBase *>(m_panelContentStack->widget(index))->itemButtons();
+        m_itemContextButtonBar->setContextButtons(itemContextButtons);
 
         emit currentChanged(index);
     }
 }
 
-void TabbedPanel::resizePanel(const QSize &size)
+void TabbedPanel::setTabsEnabled(const QList<int> &tabIndexes, bool enabled)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    this->resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH,
-                 size.height() - PANEL_TOP_PADDING - PANEL_BOTTOM_PADDING);
+    QButtonGroup *tabs = m_panelTabBar->tabs();
 
-    if(!m_isOpen)
-        this->move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
-    else
-        this->move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
-                   PANEL_TOP_PADDING);
+    foreach (int tabIndex, tabIndexes) {
+        QAbstractButton *tabButton = tabs->button(tabIndex);
 
-    m_panelBar->resizeBar(size);
+        if (tabButton) {
+            if (tabButton->isChecked())
+                closePanel();
 
-    m_panelContent->resizePanelContent(size);
-
-    m_panelStateClosed->assignProperty(this, "pos",
-                        QPoint(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING));
-    m_panelStateOpened->assignProperty(this, "pos",
-                        QPoint(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
-                               PANEL_TOP_PADDING));
+            tabButton->setEnabled(enabled);
+        }
+    }
 }
 
 void TabbedPanel::stateChanged()
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    if(!m_isOpen) {
-        m_isOpen = true;
+    calculateMask();
+
+    if (m_open) {
+        m_panelContextButtonBar->showContextButtonBar();
         emit panelOpened();
     } else {
-        m_isOpen = false;
         emit panelClosed();
     }
 }