summaryrefslogtreecommitdiff
path: root/libopie/big-screen/owidgetstack.cpp
Unidiff
Diffstat (limited to 'libopie/big-screen/owidgetstack.cpp') (more/less context) (show whitespace changes)
-rw-r--r--libopie/big-screen/owidgetstack.cpp404
1 files changed, 404 insertions, 0 deletions
diff --git a/libopie/big-screen/owidgetstack.cpp b/libopie/big-screen/owidgetstack.cpp
new file mode 100644
index 0000000..967c54b
--- a/dev/null
+++ b/libopie/big-screen/owidgetstack.cpp
@@ -0,0 +1,404 @@
1#include <qapplication.h>
2#include <qwidgetstack.h>
3
4#include "owidgetstack.h"
5
6namespace {
7 const int mode_size = 330;
8}
9
10/**
11 * This is the standard widget. For simple usage see the example. Normally this widget
12 * is the central widget of a QMainWindow.
13 * Use removeWidget before you delete a widget yourself. OWidgetStack does not
14 * yet recognize removal of children.
15 *
16 * @param parent The parent widget. It maybe 0 but then you need to take care of deletion.
17 * Or you use QPEApplication::showMainWidget().
18 * @param name Name will be passed on to QObject
19 * @param fl Additional window flags passed to QFrame. see @Qt::WFlags
20 */
21OWidgetStack::OWidgetStack( QWidget* parent, const char* name, WFlags fl)
22 : QFrame( parent, name, fl )
23{
24 m_last = m_mWidget = 0;
25 m_forced = false;
26
27 QApplication::desktop()->installEventFilter( this );
28 setFontPropagation ( AllChildren );
29 setPalettePropagation( AllChildren );
30
31 /* sets m_mode and initializes more */
32 /* if you change this call change switchTop as well */
33 m_stack = 0;
34 switchStack();
35}
36
37/**
38 * The destructor. It deletes also all added widgets.
39 *
40 */
41OWidgetStack::~OWidgetStack() {
42 if (m_mode == BigScreen && !m_list.isEmpty() ) {
43 QMap<int, QWidget*>::Iterator it = m_list.begin();
44 for ( ; it != m_list.end(); ++it )
45 delete it.data();
46 }
47 m_list.clear();
48
49}
50
51/**
52 * return the mode of the desktop. There are currently two modes. SmallScreen
53 * with a normal PDA resolution and BigScreen with resolutions greater than
54 * 330 for width and height.
55 * You can also force the mode this widget is in with forceMode()
56 * Note that NoForce will be never returned from here
57 */
58enum OWidgetStack::Mode OWidgetStack::mode()const {
59 return m_mode;
60}
61
62/**
63 * You can also force one of the modes and then
64 * this widget stops on listening to size changes. You
65 * can revert to the scanning behaviour by setting mode
66 * to NoForce
67 */
68void OWidgetStack::forceMode( enum Mode mode) {
69 m_forced = mode != NoForce;
70
71 /* we need to see which mode we're in */
72 if (!m_forced ) {
73 if ( QApplication::desktop()->width() >=
74 mode_size )
75 mode = BigScreen;
76 else
77 mode = SmallScreen;
78 }
79 switch( mode ) {
80 case NoForce:
81 case SmallScreen:
82 switchStack();
83 break;
84 case BigScreen:
85 switchTop();
86 break;
87
88 }
89
90 m_mode = mode;
91}
92
93/**
94 * Adds a widget to the stack. The first widget added is considered
95 * to be the mainwindow. This is important because if Opie is in
96 * BigScreen mode the sizeHint of the MainWindow will be returned.
97 * In Small Screen the sizeHint of the QWidgetStack is returned.
98 * See QWidgetStack::sizeHint.
99 * This widget takes ownership of the widget and may even reparent.
100 * All windows will be hidden
101 *
102 * @param wid The QWidget to be added
103 * @param id An ID for the Widget. If the ID is duplicated the
104 last set widget will be related to the id
105 *
106 */
107void OWidgetStack::addWidget( QWidget* wid, int id) {
108 if (!wid)
109 return;
110
111 /* set our main widget */
112 if (!m_mWidget)
113 m_mWidget = wid;
114
115 m_list.insert( id, wid );
116
117 /**
118 * adding does not raise any widget
119 * But for our mainwidget we prepare
120 * the right position with the right parent
121 */
122 if (m_mode == SmallScreen )
123 m_stack->addWidget( wid,id );
124 else if ( m_mWidget == wid ) {
125 wid->reparent(this, 0, contentsRect().topLeft() );
126 wid->hide();
127 }else {
128 wid->reparent(0, WType_TopLevel, QPoint(10, 10) );
129 wid->hide();
130 }
131}
132
133
134/**
135 * Remove the widget from the stack it'll be reparented to 0
136 * and ownership is dropped. You need to delete it.
137 * If the removed widget was the mainwindow consider
138 * to call setMainWindow.
139 *
140 * @param wid The QWidget to be removed
141 */
142void OWidgetStack::removeWidget( QWidget* wid) {
143 if (!wid)
144 return;
145
146 if (m_mode == SmallScreen )
147 m_stack->removeWidget( wid );
148
149
150 wid->reparent(0, 0, QPoint(0, 0) );
151 m_list.remove( id(wid) );
152
153 if ( wid == m_mWidget )
154 m_mWidget = 0;
155}
156
157#if 0
158/**
159 * @internal_resons
160 */
161QSizeHint OWidgetStack::sizeHint()const {
162
163}
164
165/**
166 * @internal_reasons
167 */
168QSizeHint OWidgetStack::minimumSizeHint()const {
169
170}
171#endif
172
173/**
174 * This function tries to find the widget with the id.
175 * You supplied a possible id in addWIdget. Note that not
176 * QWidget::winId() is used.
177 *
178 * @param id The id to search for
179 *
180 * @return The widget or null
181 * @see addWidget
182 */
183QWidget* OWidgetStack::widget( int id) const {
184 return m_list[id];
185}
186
187/**
188 * Tries to find the assigned id for the widget
189 * or returns -1 if no widget could be found
190 * @param wid The widget to look for
191 */
192int OWidgetStack::id( QWidget* wid)const{
193 if (m_list.isEmpty() )
194 return -1;
195
196 QMap<int, QWidget*>::ConstIterator it = m_list.begin();
197 for ( ; it != m_list.end(); ++it )
198 if ( it.data() == wid )
199 break;
200
201 /* if not at the end return the key */
202 return it == m_list.end() ? -1 : it.key();
203}
204
205
206/**
207 * This function returns the currently visible
208 * widget. In BigScreen mode the mainwindow
209 * is returned
210 */
211QWidget* OWidgetStack::visibleWidget()const {
212 if (m_mode == SmallScreen )
213 return m_stack->visibleWidget();
214 else
215 return m_mWidget;
216
217}
218
219/**
220 * This method raises the widget wit the specefic id.
221 * Note that in BigScreen mode the widget is made visible
222 * but the other ( previous) visible widget(s) will not
223 * be made invisible. If you need this use hideWidget().
224 *
225 * @param id Raise the widget with id
226 */
227void OWidgetStack::raiseWidget( int id) {
228 return raiseWidget( widget( id ) );
229}
230
231/**
232 * This is an overloaded function and only differs in its parameters.
233 * @see raiseWidget( int )
234 */
235void OWidgetStack::raiseWidget( QWidget* wid) {
236 m_last = wid;
237 if (m_mode == SmallScreen )
238 m_stack->raiseWidget( wid );
239 else {
240 int ide;
241 emit aboutToShow( wid );
242 /* if someone is connected and the widget is actually available */
243 if ( receivers( SIGNAL(aboutToShow(int) ) ) &&
244 ( (ide = id( wid ) ) != -1 ) )
245 emit aboutToShow( ide );
246
247 /* ### FIXME PLACE THE WIDGET right */
248 wid->show();
249 }
250}
251
252/**
253 * This will hide the currently visible widget
254 * and raise the widget specified by the parameter.
255 * Note that this method does not use visibleWIdget but remembers
256 * the last raisedWidget
257 */
258void OWidgetStack::hideWidget( int id) {
259 /* hiding our main widget wouldn't be smart */
260 if ( m_mode == BigScreen && m_last != m_mWidget )
261 m_last->hide();
262 raiseWidget( id );
263}
264
265/**
266 * This is overloaded and only differs in the parameters
267 * it takes.
268 */
269void OWidgetStack::hideWidget( QWidget* wid) {
270 /* still not smart */
271 if ( m_mode == BigScreen && m_last != m_mWidget )
272 m_last->hide();
273
274 raiseWidget( wid );
275}
276
277
278bool OWidgetStack::eventFilter( QObject* obj, QEvent* e) {
279 qWarning(" %s %s", obj->name(), obj->className() );
280 if ( e->type() == QEvent::Resize ) {
281 QResizeEvent *res = static_cast<QResizeEvent*>( e );
282 QSize size = res->size();
283 if ( size.width() >= mode_size )
284 switchTop();
285 else
286 switchStack();
287 }
288 return false;
289}
290
291
292/**
293 * @internal_resons
294 */
295void OWidgetStack::resizeEvent( QResizeEvent* ev ) {
296 QFrame::resizeEvent( ev );
297 if (m_mode == SmallScreen )
298 m_stack->setGeometry( frameRect() );
299 else
300 if (m_mWidget )
301 m_mWidget->setGeometry( frameRect() );
302
303}
304
305/**
306 * setMainWindow gives the OWidgetStack a hint which
307 * window should always stay inside the stack.
308 * Normally the first added widget is considered to be
309 * the mainwindow but you can change this with this
310 * function.
311 * If in BigScreen mode the current mainwindow will be reparented
312 * and hidden. The position will be taken by the new one.
313 * If the old MainWindow was hidden the new window will
314 * also be hidden. If the window was visible the new mainwindow
315 * will be made visible too and the old one hidden. If there
316 * was no mainwindow it will be hidden as well.
317 *
318 * @param wid The new mainwindow
319 */
320void OWidgetStack::setMainWindow( QWidget* wid ) {
321 if (m_mode == BigScreen ) {
322 bool wasVisible = false;
323 if (m_mWidget ) {
324 wasVisible = !m_mWidget->isHidden();
325 /* hidden by default */
326 m_mWidget->reparent(0, WType_TopLevel, QPoint(10, 10) );
327 }
328 wid->reparent(this, 0, frameRect().topLeft() );
329
330 if (wasVisible)
331 wid->show();
332 }
333
334 m_mWidget = wid;
335}
336
337/**
338 * this is an overloaded member and only differs
339 * in the type of arguments.
340 * @see setMainWindow(QWidget*)
341 */
342void OWidgetStack::setMainWindow( int id) {
343 setMainWindow( widget( id ) );
344}
345
346
347/*
348 * this function switches to a stack ;)
349 */
350void OWidgetStack::switchStack() {
351 if (m_stack ) {
352 m_stack->setGeometry( frameRect() );
353 return;
354 }
355
356 m_mode = SmallScreen;
357 m_stack = new QWidgetStack(this);
358
359 connect(m_stack, SIGNAL(aboutToShow(QWidget*) ),
360 this, SIGNAL(aboutToShow(QWidget*) ) );
361 connect(m_stack, SIGNAL(aboutToShow(int) ),
362 this, SIGNAL(aboutToShow(int) ) );
363
364 /* now reparent the widgets... luckily QWidgetSatck does most of the work */
365 if (m_list.isEmpty() )
366 return;
367
368 QMap<int, QWidget*>::Iterator it = m_list.begin();
369 for ( ; it != m_list.end(); ++it )
370 m_stack->addWidget( it.data(), it.key() );
371
372
373}
374
375/*
376 * we will switch to top level mode
377 * reparent the list of widgets and then delete the stack
378 */
379void OWidgetStack::switchTop() {
380 m_mode = BigScreen;
381 /* this works because it is guaranteed that switchStack was called at least once*/
382 if (!m_stack && m_mWidget) {
383 m_mWidget->setGeometry( frameRect() );
384 return;
385 }else if (!m_stack)
386 return;
387
388 if (!m_list.isEmpty() ) {
389 QMap<int, QWidget*>::Iterator it = m_list.begin();
390 for ( ; it != m_list.end(); ++it ) {
391 /* better than reparenting twice */
392 if ( it.data() == m_mWidget ) {
393 m_mWidget->reparent(this, 0, frameRect().topLeft() );
394 m_mWidget->setGeometry( frameRect() );
395 m_mWidget->show();
396 }else
397 /* ### FIXME we need to place the widget better */
398 it.data()->reparent(0, WType_TopLevel, QPoint(10, 10) );
399 }
400 }
401
402 delete m_stack;
403 m_stack = 0;
404}