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