summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/big-screen/example/owidgetstack_example.cpp131
-rw-r--r--libopie/big-screen/example/owidgetstack_example.h27
-rw-r--r--libopie/big-screen/example/owidgetstack_example.pro13
-rw-r--r--libopie/big-screen/owidgetstack.cpp404
-rw-r--r--libopie/big-screen/owidgetstack.h127
5 files changed, 702 insertions, 0 deletions
diff --git a/libopie/big-screen/example/owidgetstack_example.cpp b/libopie/big-screen/example/owidgetstack_example.cpp
new file mode 100644
index 0000000..a6b8201
--- a/dev/null
+++ b/libopie/big-screen/example/owidgetstack_example.cpp
@@ -0,0 +1,131 @@
1/*
2 * You may use, modify and distribute this example without any limitation
3 */
4
5#include <qaction.h>
6#include <qtoolbar.h>
7#include <qpopupmenu.h>
8#include <qmenubar.h>
9#include <qlayout.h>
10#include <qlabel.h>
11#include <qpushbutton.h>
12#include <qsignalmapper.h>
13
14#include <qpe/resource.h>
15
16#include "../owidgetstack.h"
17
18#include "owidgetstack_example.h"
19
20#include <qpe/qpeapplication.h>
21#include <opie/oapplicationfactory.h>
22
23OPIE_EXPORT_APP( OApplicationFactory<StackExample> )
24
25StackExample::StackExample( QWidget* parent, const char* name, WFlags fl )
26 : QMainWindow( parent, name, fl )
27{
28 m_stack = new OWidgetStack( this );
29 setCentralWidget( m_stack );
30
31 /* nice Signal Mapper ;) */
32 QSignalMapper *sm = new QSignalMapper(this);
33 connect(sm, SIGNAL(mapped(int) ), m_stack, SLOT(raiseWidget(int)) );
34
35 /* toolbar first but this should be known from the other examples */
36 setToolBarsMovable( false );
37
38 /* only a menubar here */
39 QToolBar* holder = new QToolBar( this );
40 holder->setHorizontalStretchable( true );
41
42 QMenuBar *bar = new QMenuBar( holder );
43 QPopupMenu *menu = new QPopupMenu( this );
44
45 QAction* a = new QAction( tr("Show MainWidget"), Resource::loadPixmap("zoom"),
46 QString::null, 0, this, 0 );
47 sm->setMapping(a, 1 );
48 connect(a, SIGNAL(activated() ),
49 sm, SLOT(map() ) );
50 a->addTo( menu );
51
52 a = new QAction( tr("Show Details Small"), Resource::loadPixmap("zoom"),
53 QString::null, 0, this, 0 );
54 sm->setMapping(a, 2 );
55 connect(a, SIGNAL(activated() ),
56 sm, SLOT(map() ) );
57 a->addTo( menu );
58
59 a = new QAction( tr("Show Details More"), Resource::loadPixmap("zoom"),
60 QString::null, 0, this, 0 );
61 sm->setMapping(a, 3 );
62 connect(a, SIGNAL(activated() ),
63 sm, SLOT(map() ) );
64 a->addTo( menu );
65
66 a = new QAction( tr("Show Details All"), Resource::loadPixmap("zoom"),
67 QString::null, 0, this, 0 );
68 sm->setMapping(a, 4 );
69 connect(a, SIGNAL(activated() ),
70 sm, SLOT(map() ) );
71
72 bar->insertItem( tr("Actions"), menu );
73
74 /* now the gui */
75
76 /* first widget, main widget */
77 QWidget * wid = new QWidget( m_stack );
78 QGridLayout *grid = new QGridLayout(wid, 2, 2 );
79
80 QPushButton *btn = new QPushButton( tr("Show Details Small"), wid, "details1" );
81 sm->setMapping(btn, 2 );
82 connect(btn, SIGNAL(clicked()), sm, SLOT(map() ) );
83 grid->addWidget( btn, 0, 0 );
84
85 btn = new QPushButton( tr("Show Details Medium"), wid, "details2");
86 sm->setMapping(btn, 3 );
87 connect(btn, SIGNAL(clicked()), sm, SLOT(map() ) );
88 grid->addWidget( btn, 0, 1 );
89
90 btn = new QPushButton( tr("Show Details All"), wid, "details3");
91 sm->setMapping(btn, 4 );
92 connect(btn, SIGNAL(clicked()), sm, SLOT(map() ) );
93 grid->addWidget( btn, 1, 1 );
94
95 m_stack->addWidget( wid, 1 );
96 m_main = wid;
97
98 QLabel *lbl = new QLabel(m_stack );
99 lbl->setText(tr("Only small Details are shown here. Määh") );
100 m_stack->addWidget( lbl, 2 );
101
102 lbl = new QLabel( m_stack );
103 lbl->setText( tr("Some more details....Wo ist das Schaf?") );
104 m_stack->addWidget( lbl, 3 );
105
106 lbl = new QLabel( m_stack );
107 lbl->setText( tr("<qt>Ne nicht in Bayerisch Gmain sondern in Berlin<br>Vermiss und meine Augen werden nicht eckig, da mein Bildschirm abgerundet ist<br>Es lebe Hamburg Süd,weiss du, verstehst du? ;)<br>Susi ist dOOf, es lebe die Ofenecke...", "hard to translate that") );
108 m_stack->addWidget( lbl, 4 );
109
110
111 /* THE signal mapper does all the magic */
112 m_stack->raiseWidget( m_main );
113}
114
115
116StackExample::~StackExample() {
117
118}
119
120
121
122void StackExample::closeEvent( QCloseEvent* ev) {
123 /* if the close even came when we displayed a details */
124 if (m_stack->visibleWidget() != m_main ) {
125 m_stack->raiseWidget( m_main );
126 ev->ignore();
127 return;
128 }
129
130 ev->accept();
131}
diff --git a/libopie/big-screen/example/owidgetstack_example.h b/libopie/big-screen/example/owidgetstack_example.h
new file mode 100644
index 0000000..7977b48
--- a/dev/null
+++ b/libopie/big-screen/example/owidgetstack_example.h
@@ -0,0 +1,27 @@
1/*
2 * You may use, modify and distribute this example without any limitation
3 */
4
5#ifndef O_STACK_EXAMPLE_SIMPLE_H
6#define O_STACK_EXAMPLE_SIMPLE_H
7
8#include <qmainwindow.h>
9
10
11class OWidgetStack;
12class StackExample : public QMainWindow {
13 Q_OBJECT
14public:
15 StackExample( QWidget* paren, const char* name, WFlags fl );
16 ~StackExample();
17 static QString appName() { return QString::fromLatin1("owidgetstack-example"); }
18
19protected:
20 void closeEvent( QCloseEvent* e );
21private:
22 OWidgetStack* m_stack;
23 QWidget* m_main;
24
25};
26
27#endif
diff --git a/libopie/big-screen/example/owidgetstack_example.pro b/libopie/big-screen/example/owidgetstack_example.pro
new file mode 100644
index 0000000..ad1dc09
--- a/dev/null
+++ b/libopie/big-screen/example/owidgetstack_example.pro
@@ -0,0 +1,13 @@
1CONFIG += qt warn_on
2TEMPLATE = app
3TARGET = owidgetstack-example
4
5SOURCES = ../owidgetstack.cpp owidgetstack_example.cpp
6HEADERS = ../owidgetstack.h owidgetstack_example.h
7
8INCLUDEPATH += $(OPIEDIR)/include
9DEPENDSPATH += $(OPIEDIR)/include
10
11LIBS += -lqpe
12
13include ( $(OPIEDIR)/include.pro )
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}
diff --git a/libopie/big-screen/owidgetstack.h b/libopie/big-screen/owidgetstack.h
new file mode 100644
index 0000000..5179213
--- a/dev/null
+++ b/libopie/big-screen/owidgetstack.h
@@ -0,0 +1,127 @@
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#ifndef OPIE_BIG_WIDGET_STACK_H
30#define OPIE_BIG_WIDGET_STACK_H
31
32#include <qframe.h>
33#include <qmap.h>
34
35class QWidgetStack;
36/**
37 *
38 * OWidgetStack is the answer to the problem of using Opie at different screen
39 * sizes and to have a different behaviour. Most applications use a QWidgetStack
40 * to supply a view on click. And by clicking the (X) you go back but this
41 * behaviour feels strange on bigger screens. It's ok on smaller one because
42 * one can't determine the difference.
43 * This stack reads the default out of the size of the desktop widget but
44 * can be forced to have either the one or the other behaviour.
45 * The first widget added is considered the 'main' widget and its
46 * sizeHint will be taking if in BigScreen mode.
47 * In small screen mode this widget behaves exactly like a QWidgetStack and in BigScreen
48 * mode it'll use the MainWindow as child of this widget and arranges the others as
49 * hidden top level widgets.
50 *
51 * @version 0.1
52 * @author hOlgAr F.
53 * @short Either a true stack or a list of top Level widgets
54 */
55class OWidgetStack : public QFrame {
56 Q_OBJECT
57public:
58 enum Mode { SmallScreen, BigScreen, NoForce };
59 OWidgetStack( QWidget* parent, const char* name = 0, WFlags fl = 0 );
60 ~OWidgetStack();
61
62 enum Mode mode()const;
63 void forceMode( enum Mode );
64
65 void addWidget( QWidget* , int );
66 void removeWidget( QWidget* );
67
68// QSizeHint sizeHint()const;
69// QSizeHint minimumSizeHint()const;
70
71 QWidget *widget( int )const;
72 int id( QWidget* )const;
73
74
75
76 QWidget* visibleWidget() const;
77
78 bool eventFilter( QObject*, QEvent* );
79signals:
80 /**
81 * OWidgetStack monitors the Desktop Widget for
82 * size changes if it recignizes a change size it'll
83 * send a signal and adjust its mode. After the signal
84 * was emitted. During the signal a call to mode() the
85 * old mode will be returned. Note that if a size change happens
86 * but no modeChange no signal will be emitted
87 *
88 *
89 * @param mode The new mode of the desktop
90 */
91 void modeChanged( enum Mode mode);
92
93 /**
94 * These two signals are emitted whenever we're about to
95 * show one of the widgets
96 */
97 void aboutToShow( QWidget* );
98 void aboutToShow( int );
99
100public slots:
101 void raiseWidget( int );
102 void raiseWidget( QWidget* );
103 void hideWidget( int );
104 void hideWidget( QWidget* );
105 void setMainWindow( QWidget* );
106 void setMainWindow( int );
107
108protected:
109 void resizeEvent( QResizeEvent* );
110
111private:
112 void switchStack();
113 void switchTop();
114 QMap<int, QWidget*> m_list;
115 QWidgetStack *m_stack;
116 QWidget *m_mWidget;
117 QWidget *m_last;
118
119 enum Mode m_mode;
120 bool m_forced : 1;
121
122 struct Private;
123 Private *d;
124};
125
126
127#endif