Reviewed new files
[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 <QButtonGroup>
24 #include <QDebug>
25 #include <QPropertyAnimation>
26 #include <QSignalTransition>
27 #include <QStackedWidget>
28 #include <QStateMachine>
29
30 #include "panelbar.h"
31 #include "panelcontent.h"
32 #include "paneltab.h"
33 #include "userinfo.h"
34
35 #include "tabbedpanel.h"
36
37 TabbedPanel::TabbedPanel(QWidget *parent)
38     : QWidget(parent),
39       m_isOpen(false),
40       m_activeTab(-1) ///< @todo magic
41 {
42     qDebug() << __PRETTY_FUNCTION__;
43
44     ///< @todo Do not use this, REMOVE ALL OCCURENCES!
45     this->resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH, PANEL_HEIGHT);
46     this->move(PANEL_CLOSED_X, PANEL_TOP_PADDING);
47
48     // --- TABS ---
49     m_panelWidgetStack = new QStackedWidget(this);
50
51     m_tabButtonGroup = new QButtonGroup(this);
52
53     connect(m_tabButtonGroup, SIGNAL(buttonPressed(int)),
54             this, SLOT(setActiveTab(int)));
55
56     // --- BAR ---
57     m_panelBar = new PanelBar(this);
58     m_panelBar->move(PANEL_TAB_WIDTH, 0);
59
60     // --- PANEL CONTENT ---
61     m_panelContent = new PanelContent(this);
62     m_panelContent->setContentWidget(m_panelWidgetStack);
63     m_panelContent->move(PANEL_TAB_WIDTH + PANEL_BAR_WIDTH, 0);
64
65     // --- PANEL ANIMATION ---
66     m_panelStateMachine = new QStateMachine(this);
67
68     m_panelStateClosed = new QState(m_panelStateMachine);
69     m_panelStateOpened = new QState(m_panelStateMachine);
70
71     m_panelAnimation = new QPropertyAnimation(this, "pos", this);
72
73     m_panelStateMachine->setInitialState(m_panelStateClosed);
74
75     m_panelTransitionOpen = m_panelStateClosed->addTransition(this, SIGNAL(toggleState()),
76                                                               m_panelStateOpened);
77     m_panelTransitionOpen->addAnimation(m_panelAnimation);
78
79     m_panelTransitionClose = m_panelStateOpened->addTransition(this, SIGNAL(toggleState()),
80                                                                m_panelStateClosed);
81     m_panelTransitionClose->addAnimation(m_panelAnimation);
82
83     connect(m_panelAnimation, SIGNAL(finished()),
84             this, SLOT(stateChanged()));
85
86     m_panelStateClosed->assignProperty(this, "pos",
87                                        QPoint(PANEL_CLOSED_X, PANEL_TOP_PADDING));
88     m_panelStateOpened->assignProperty(this, "pos",
89                                        QPoint(PANEL_OPENED_X, PANEL_TOP_PADDING));
90
91     m_panelStateMachine->start();
92 }
93
94 int TabbedPanel::addTab(QWidget *widget, const QIcon& icon)
95 {
96     qDebug() << __PRETTY_FUNCTION__;
97
98     ///< @todo magic
99     return insertTab(-1, widget, icon);
100 }
101
102 int TabbedPanel::insertTab(int index, QWidget *widget, const QIcon& icon)
103 {
104     qDebug() << __PRETTY_FUNCTION__;
105
106     ///< @todo callers responsibility to call with right parameters
107     if(!widget)
108         return -1;
109
110     ///< @todo magic
111     int verticalStartPoint = 8;
112
113     index = m_panelWidgetStack->insertWidget(index, widget);
114     m_tabButtonGroup->addButton(new PanelTab(this), index);
115     m_tabButtonGroup->button(index)->setIcon(icon);
116
117     ///< @todo [BEGIN]: Purkkaa (to be removed ASAP!!!)
118     if(index > 0)
119         verticalStartPoint += 65 * index;
120
121     m_tabButtonGroup->button(index)->move(0, verticalStartPoint);
122     // [END]: Purkkaa
123
124     return index;
125 }
126
127 void TabbedPanel::removeTab(int index)
128 {
129     qDebug() << __PRETTY_FUNCTION__;
130
131     if(QWidget *widget = m_panelWidgetStack->widget(index)) {
132         m_panelWidgetStack->removeWidget(widget);
133
134         QAbstractButton *tab = m_tabButtonGroup->button(index);
135         m_tabButtonGroup->removeButton(tab);
136         delete tab;
137     }
138 }
139
140 ///< @todo sort alphabetically (other methods too)
141 void TabbedPanel::closePanel()
142 {
143     qDebug() << __PRETTY_FUNCTION__;
144
145     if(m_isOpen)
146         emit toggleState();
147 }
148
149 void TabbedPanel::openPanel()
150 {
151     qDebug() << __PRETTY_FUNCTION__;
152
153     if(!m_isOpen)
154         emit toggleState();
155 }
156
157 void TabbedPanel::resizePanel(const QSize &size)
158 {
159     qDebug() << __PRETTY_FUNCTION__;
160
161     this->resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH,
162                  size.height() - PANEL_TOP_PADDING - PANEL_BOTTOM_PADDING);
163
164     if(!m_isOpen) {
165         this->move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
166     }
167     else {
168         this->move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
169                    PANEL_TOP_PADDING);
170     }
171
172     m_panelBar->resizeBar(size);
173
174     m_panelContent->resizePanelContent(size);
175
176     ///< @todo alignment
177     m_panelStateClosed->assignProperty(this, "pos",
178                         QPoint(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING));
179     m_panelStateOpened->assignProperty(this, "pos",
180                         QPoint(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
181                                PANEL_TOP_PADDING));
182 }
183
184 void TabbedPanel::setActiveTab(int index)
185 {
186     qDebug() << __PRETTY_FUNCTION__;
187
188     ///< @todo magic
189     ///< @todo short comments?
190     if(m_activeTab == -1) {
191         m_activeTab = index;
192         m_panelWidgetStack->setCurrentIndex(index);
193         emit tabChanged();
194         emit toggleState();
195     } else if(m_activeTab == index) {
196         m_activeTab = -1;
197         emit toggleState();
198     } else {
199         m_activeTab = index;
200         m_panelWidgetStack->setCurrentIndex(index);
201         emit tabChanged();
202     }
203 }
204
205 void TabbedPanel::stateChanged()
206 {
207     qDebug() << __PRETTY_FUNCTION__;
208
209     if(!m_isOpen) {
210         m_isOpen = true;
211         emit panelOpened();
212     } else {
213         m_isOpen = false;
214
215         m_tabButtonGroup->setExclusive(false);
216         m_tabButtonGroup->button(m_tabButtonGroup->checkedId())->setChecked(false);
217         m_tabButtonGroup->setExclusive(true);
218
219         emit panelClosed();
220     }
221 }