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