Added images for search location button and implemented a temporary slot for repositi...
[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 "panelbase.h"
31 #include "panelcontentstack.h"
32 #include "panelcontextbuttonbar.h"
33 #include "paneltabbar.h"
34
35 #include "tabbedpanel.h"
36
37 const int PANEL_CONTEXT_BUTTON_BAR_LEFT_X = 0;
38
39 TabbedPanel::TabbedPanel(QWidget *parent)
40     : QWidget(parent),
41       m_isOpen(false)
42 {
43     qDebug() << __PRETTY_FUNCTION__;
44
45     const int PANEL_LEFT_X = 0;
46     const int PANEL_TOP_Y = 0;
47     const int PANEL_TAB_BAR_TOP_SPACING = 8;
48
49     resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH, PANEL_HEIGHT);
50     move(PANEL_CLOSED_X, PANEL_TOP_PADDING);
51
52     // --- TABS ---
53     m_panelTabBar = new PanelTabBar(this);
54     m_panelTabBar->move(PANEL_LEFT_X, PANEL_TAB_BAR_TOP_SPACING);
55
56     connect(m_panelTabBar, SIGNAL(currentChanged(int)),
57             this, SLOT(setCurrentIndex(int)));
58
59     connect(m_panelTabBar, SIGNAL(tabCloseRequested(int)),
60              this, SLOT(closePanel()));
61
62     connect(this, SIGNAL(panelClosed()),
63             m_panelTabBar, SLOT(deselectTabs()));
64
65     // --- BAR ---
66     m_panelBar = new PanelBar(this);
67     m_panelBar->move(PANEL_TAB_WIDTH, PANEL_TOP_Y);
68
69     // --- CONTEXT BUTTON BAR ---
70     m_panelContextButtonBar = new PanelContextButtonBar(this);
71     m_panelContextButtonBar->setVisible(false);
72     m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X,
73                                   PANEL_HEIGHT - m_panelContextButtonBar->height());
74
75     connect(m_panelContextButtonBar, SIGNAL(positionChangeRequested()),
76             this, SLOT(repositionContextButtonBar()));
77
78     connect(this, SIGNAL(panelOpened()),
79             this, SLOT(showContextButtonBar()));
80
81     connect(this, SIGNAL(panelClosed()),
82             this, SLOT(hideContextButtonBar()));
83
84     // --- PANEL CONTENT ---
85     m_panelContentStack = new PanelContentStack(this);
86     m_panelContentStack->move(PANEL_TAB_WIDTH + PANEL_BAR_WIDTH, PANEL_TOP_Y);
87
88     // --- PANEL ANIMATION ---
89     m_panelStateMachine = new QStateMachine(this);
90
91     m_panelStateClosed = new QState(m_panelStateMachine);
92     m_panelStateOpened = new QState(m_panelStateMachine);
93
94     m_panelAnimation = new QPropertyAnimation(this, "pos", this);
95
96     m_panelStateMachine->setInitialState(m_panelStateClosed);
97
98     m_panelTransitionOpen = m_panelStateClosed->addTransition(this, SIGNAL(toggleState()),
99                                                               m_panelStateOpened);
100     m_panelTransitionOpen->addAnimation(m_panelAnimation);
101
102     m_panelTransitionClose = m_panelStateOpened->addTransition(this, SIGNAL(toggleState()),
103                                                                m_panelStateClosed);
104     m_panelTransitionClose->addAnimation(m_panelAnimation);
105
106     connect(m_panelAnimation, SIGNAL(finished()),
107             this, SLOT(stateChanged()));
108
109     m_panelStateClosed->assignProperty(this, "pos",
110                                        QPoint(PANEL_CLOSED_X, PANEL_TOP_PADDING));
111     m_panelStateOpened->assignProperty(this, "pos",
112                                        QPoint(PANEL_OPENED_X, PANEL_TOP_PADDING));
113
114     m_panelStateMachine->start();
115 }
116
117 int TabbedPanel::addTab(QWidget *widget, const QIcon& icon)
118 {
119     qDebug() << __PRETTY_FUNCTION__;
120
121     const int APPEND_INDEX = -1;
122
123     return insertTab(APPEND_INDEX, widget, icon);
124 }
125
126 void TabbedPanel::closePanel()
127 {
128     qDebug() << __PRETTY_FUNCTION__;
129
130     if (m_isOpen)
131         emit toggleState();
132 }
133
134 int TabbedPanel::insertTab(int index, QWidget *widget, const QIcon& icon)
135 {
136     qDebug() << __PRETTY_FUNCTION__;
137
138     index = m_panelContentStack->insertWidget(index, widget);
139     m_panelTabBar->insertTab(index, icon);
140
141     return index;
142 }
143
144 void TabbedPanel::removeTab(int index)
145 {
146     qDebug() << __PRETTY_FUNCTION__;
147
148     if (QWidget *widget = m_panelContentStack->widget(index)) {
149         m_panelContentStack->removeWidget(widget);
150         m_panelTabBar->removeTab(index);
151     }
152 }
153
154 void TabbedPanel::repositionContextButtonBar()
155 {
156     qDebug() << __PRETTY_FUNCTION__;
157
158     m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X,
159                                   height() - m_panelContextButtonBar->height());
160 }
161
162 void TabbedPanel::resizePanel(const QSize &size)
163 {
164     qDebug() << __PRETTY_FUNCTION__;
165
166     resize(PANEL_BAR_TABBED_WIDTH + PANEL_WIDTH,
167            size.height() - PANEL_TOP_PADDING - PANEL_BOTTOM_PADDING);
168
169     if (!m_isOpen)
170         move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
171     else
172         move(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH, PANEL_TOP_PADDING);
173
174     m_panelBar->resizeBar(size);
175
176     m_panelContextButtonBar->move(PANEL_CONTEXT_BUTTON_BAR_LEFT_X,
177                                   size.height() - m_panelContextButtonBar->height());
178
179     m_panelContentStack->resizeContentStack(size);
180
181     QPoint closedPosition(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH, PANEL_TOP_PADDING);
182     m_panelStateClosed->assignProperty(this, "pos", closedPosition);
183
184     QPoint openedPosition(size.width() - PANEL_TAB_WIDTH - PANEL_BAR_WIDTH - PANEL_WIDTH,
185                           PANEL_TOP_PADDING);
186     m_panelStateOpened->assignProperty(this, "pos", openedPosition);
187 }
188
189 void TabbedPanel::setCurrentIndex(int index)
190 {
191     qDebug() << __PRETTY_FUNCTION__;
192
193     if ((index < m_panelContentStack->count()) && (index >= 0)) {
194         m_panelContentStack->setCurrentIndex(index);
195
196         if (!m_isOpen)
197             emit toggleState();
198
199         m_panelContextButtonBar->setContextButtons(
200                 static_cast<PanelBase *>(m_panelContentStack->widget(index))->contextButtons());
201
202         emit currentChanged(index);
203     }
204 }
205
206 void TabbedPanel::showPanel(QWidget *widget)
207 {
208     qDebug() << __PRETTY_FUNCTION__;
209
210     m_panelTabBar->selectTab(m_panelContentStack->indexOf(widget));
211 }
212
213 void TabbedPanel::stateChanged()
214 {
215     qDebug() << __PRETTY_FUNCTION__;
216
217     if (!m_isOpen) {
218         m_isOpen = true;
219         m_panelContextButtonBar->setVisible(true);
220         emit panelOpened();
221     } else {
222         m_isOpen = false;
223         m_panelContextButtonBar->setVisible(false);
224         emit panelClosed();
225     }
226 }