Removed a few constants from panelcommon.h (that really weren't common at all) and...
[situare] / src / ui / tabbedpanel.cpp
1 /*
2     Situare - A location system for Facebook
3     Copyright (C) 2010  Ixonos Plc. Authors:
4
5         Kaj Wallin - kaj.wallin@ixonos.com
6         Pekka Nissinen - pekka.nissinen@ixonos.com
7
8     Situare is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License
10     version 2 as published by the Free Software Foundation.
11
12     Situare is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with Situare; if not, write to the Free Software
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20     USA.
21 */
22
23 #include <QDebug>
24 #include <QPropertyAnimation>
25 #include <QSignalTransition>
26 #include <QStackedWidget>
27 #include <QStateMachine>
28
29 #include "panelbar.h"
30 #include "panelcontentstack.h"
31 #include "paneltabbar.h"
32
33 #include "tabbedpanel.h"
34
35 TabbedPanel::TabbedPanel(QWidget *parent)
36     : QWidget(parent),
37       m_isOpen(false)
38 {
39     qDebug() << __PRETTY_FUNCTION__;
40
41     const int TAB_BAR_TOP_SPACING = 8;
42
43     resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH, PANEL_HEIGHT);
44     move(PANEL_CLOSED_X, PANEL_TOP_PADDING);
45
46     // --- TABS ---
47     m_panelTabBar = new PanelTabBar(this);
48     m_panelTabBar->move(0, TAB_BAR_TOP_SPACING);
49
50     connect(m_panelTabBar, SIGNAL(currentChanged(int)),
51             this, SLOT(setCurrentIndex(int)));
52
53     connect(m_panelTabBar, SIGNAL(tabCloseRequested(int)),
54              this, SLOT(closePanel()));
55
56     connect(this, SIGNAL(panelClosed()),
57             m_panelTabBar, SLOT(deselectTabs()));
58
59     // --- BAR ---
60     m_panelBar = new PanelBar(this);
61     ///< @todo magic
62     m_panelBar->move(PANEL_TAB_WIDTH, 0);
63
64     // --- PANEL CONTENT ---
65     m_panelContentStack = new PanelContentStack(this);
66     ///< @todo magic
67     m_panelContentStack->move(PANEL_TAB_WIDTH + PANEL_BAR_WIDTH, 0);
68
69     // --- PANEL ANIMATION ---
70     m_panelStateMachine = new QStateMachine(this);
71
72     m_panelStateClosed = new QState(m_panelStateMachine);
73     m_panelStateOpened = new QState(m_panelStateMachine);
74
75     m_panelAnimation = new QPropertyAnimation(this, "pos", this);
76
77     m_panelStateMachine->setInitialState(m_panelStateClosed);
78
79     m_panelTransitionOpen = m_panelStateClosed->addTransition(this, SIGNAL(toggleState()),
80                                                               m_panelStateOpened);
81     m_panelTransitionOpen->addAnimation(m_panelAnimation);
82
83     m_panelTransitionClose = m_panelStateOpened->addTransition(this, SIGNAL(toggleState()),
84                                                                m_panelStateClosed);
85     m_panelTransitionClose->addAnimation(m_panelAnimation);
86
87     connect(m_panelAnimation, SIGNAL(finished()),
88             this, SLOT(stateChanged()));
89
90     m_panelStateClosed->assignProperty(this, "pos",
91                                        QPoint(PANEL_CLOSED_X, PANEL_TOP_PADDING));
92     m_panelStateOpened->assignProperty(this, "pos",
93                                        QPoint(PANEL_OPENED_X, PANEL_TOP_PADDING));
94
95     m_panelStateMachine->start();
96 }
97
98 int TabbedPanel::addTab(QWidget *widget, const QIcon& icon)
99 {
100     qDebug() << __PRETTY_FUNCTION__;
101
102     const int APPEND_INDEX = -1;
103
104     return insertTab(APPEND_INDEX, widget, icon);
105 }
106
107 void TabbedPanel::closePanel()
108 {
109     qDebug() << __PRETTY_FUNCTION__;
110
111     if (m_isOpen)
112         emit toggleState();
113 }
114
115 int TabbedPanel::insertTab(int index, QWidget *widget, const QIcon& icon)
116 {
117     qDebug() << __PRETTY_FUNCTION__;
118
119     index = m_panelContentStack->insertWidget(index, widget);
120     m_panelTabBar->insertTab(index, icon);
121
122     return index;
123 }
124
125 void TabbedPanel::removeTab(int index)
126 {
127     qDebug() << __PRETTY_FUNCTION__;
128
129     if (QWidget *widget = m_panelContentStack->widget(index)) {
130         m_panelContentStack->removeWidget(widget);
131         m_panelTabBar->removeTab(index);
132     }
133 }
134
135 void TabbedPanel::resizePanel(const QSize &size)
136 {
137     qDebug() << __PRETTY_FUNCTION__;
138
139     resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH,
140            size.height() - PANEL_TOP_PADDING - PANEL_BOTTOM_PADDING);
141
142     if (!m_isOpen)
143         move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
144     else
145         move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH, PANEL_TOP_PADDING);
146
147     m_panelBar->resizeBar(size);
148
149     m_panelContentStack->resizeContentStack(size);
150
151     QPoint closedPosition(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
152     m_panelStateClosed->assignProperty(this, "pos", closedPosition);
153
154     QPoint openedPosition(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
155                           PANEL_TOP_PADDING);
156     m_panelStateOpened->assignProperty(this, "pos", openedPosition);
157 }
158
159 void TabbedPanel::showPanel(QWidget *widget)
160 {
161     qDebug() << __PRETTY_FUNCTION__;
162
163     m_panelTabBar->selectTab(m_panelContentStack->indexOf(widget));
164 }
165
166 void TabbedPanel::setCurrentIndex(int index)
167 {
168     qDebug() << __PRETTY_FUNCTION__;
169
170     if ((index < m_panelContentStack->count()) && (index >= 0)) {
171         m_panelContentStack->setCurrentIndex(index);
172
173         if (!m_isOpen)
174             emit toggleState();
175
176         emit currentChanged(index);
177     }
178 }
179
180 void TabbedPanel::stateChanged()
181 {
182     qDebug() << __PRETTY_FUNCTION__;
183
184     if (!m_isOpen) {
185         m_isOpen = true;
186         emit panelOpened();
187     } else {
188         m_isOpen = false;
189         emit panelClosed();
190     }
191 }