summaryrefslogtreecommitdiff
path: root/libopie/big-screen
Side-by-side diff
Diffstat (limited to 'libopie/big-screen') (more/less context) (show 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 @@
+/*
+ * You may use, modify and distribute this example without any limitation
+ */
+
+#include <qaction.h>
+#include <qtoolbar.h>
+#include <qpopupmenu.h>
+#include <qmenubar.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qsignalmapper.h>
+
+#include <qpe/resource.h>
+
+#include "../owidgetstack.h"
+
+#include "owidgetstack_example.h"
+
+#include <qpe/qpeapplication.h>
+#include <opie/oapplicationfactory.h>
+
+OPIE_EXPORT_APP( OApplicationFactory<StackExample> )
+
+StackExample::StackExample( QWidget* parent, const char* name, WFlags fl )
+ : QMainWindow( parent, name, fl )
+{
+ m_stack = new OWidgetStack( this );
+ setCentralWidget( m_stack );
+
+ /* nice Signal Mapper ;) */
+ QSignalMapper *sm = new QSignalMapper(this);
+ connect(sm, SIGNAL(mapped(int) ), m_stack, SLOT(raiseWidget(int)) );
+
+ /* toolbar first but this should be known from the other examples */
+ setToolBarsMovable( false );
+
+ /* only a menubar here */
+ QToolBar* holder = new QToolBar( this );
+ holder->setHorizontalStretchable( true );
+
+ QMenuBar *bar = new QMenuBar( holder );
+ QPopupMenu *menu = new QPopupMenu( this );
+
+ QAction* a = new QAction( tr("Show MainWidget"), Resource::loadPixmap("zoom"),
+ QString::null, 0, this, 0 );
+ sm->setMapping(a, 1 );
+ connect(a, SIGNAL(activated() ),
+ sm, SLOT(map() ) );
+ a->addTo( menu );
+
+ a = new QAction( tr("Show Details Small"), Resource::loadPixmap("zoom"),
+ QString::null, 0, this, 0 );
+ sm->setMapping(a, 2 );
+ connect(a, SIGNAL(activated() ),
+ sm, SLOT(map() ) );
+ a->addTo( menu );
+
+ a = new QAction( tr("Show Details More"), Resource::loadPixmap("zoom"),
+ QString::null, 0, this, 0 );
+ sm->setMapping(a, 3 );
+ connect(a, SIGNAL(activated() ),
+ sm, SLOT(map() ) );
+ a->addTo( menu );
+
+ a = new QAction( tr("Show Details All"), Resource::loadPixmap("zoom"),
+ QString::null, 0, this, 0 );
+ sm->setMapping(a, 4 );
+ connect(a, SIGNAL(activated() ),
+ sm, SLOT(map() ) );
+
+ bar->insertItem( tr("Actions"), menu );
+
+ /* now the gui */
+
+ /* first widget, main widget */
+ QWidget * wid = new QWidget( m_stack );
+ QGridLayout *grid = new QGridLayout(wid, 2, 2 );
+
+ QPushButton *btn = new QPushButton( tr("Show Details Small"), wid, "details1" );
+ sm->setMapping(btn, 2 );
+ connect(btn, SIGNAL(clicked()), sm, SLOT(map() ) );
+ grid->addWidget( btn, 0, 0 );
+
+ btn = new QPushButton( tr("Show Details Medium"), wid, "details2");
+ sm->setMapping(btn, 3 );
+ connect(btn, SIGNAL(clicked()), sm, SLOT(map() ) );
+ grid->addWidget( btn, 0, 1 );
+
+ btn = new QPushButton( tr("Show Details All"), wid, "details3");
+ sm->setMapping(btn, 4 );
+ connect(btn, SIGNAL(clicked()), sm, SLOT(map() ) );
+ grid->addWidget( btn, 1, 1 );
+
+ m_stack->addWidget( wid, 1 );
+ m_main = wid;
+
+ QLabel *lbl = new QLabel(m_stack );
+ lbl->setText(tr("Only small Details are shown here. Määh") );
+ m_stack->addWidget( lbl, 2 );
+
+ lbl = new QLabel( m_stack );
+ lbl->setText( tr("Some more details....Wo ist das Schaf?") );
+ m_stack->addWidget( lbl, 3 );
+
+ lbl = new QLabel( m_stack );
+ 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") );
+ m_stack->addWidget( lbl, 4 );
+
+
+ /* THE signal mapper does all the magic */
+ m_stack->raiseWidget( m_main );
+}
+
+
+StackExample::~StackExample() {
+
+}
+
+
+
+void StackExample::closeEvent( QCloseEvent* ev) {
+ /* if the close even came when we displayed a details */
+ if (m_stack->visibleWidget() != m_main ) {
+ m_stack->raiseWidget( m_main );
+ ev->ignore();
+ return;
+ }
+
+ ev->accept();
+}
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 @@
+/*
+ * You may use, modify and distribute this example without any limitation
+ */
+
+#ifndef O_STACK_EXAMPLE_SIMPLE_H
+#define O_STACK_EXAMPLE_SIMPLE_H
+
+#include <qmainwindow.h>
+
+
+class OWidgetStack;
+class StackExample : public QMainWindow {
+ Q_OBJECT
+public:
+ StackExample( QWidget* paren, const char* name, WFlags fl );
+ ~StackExample();
+ static QString appName() { return QString::fromLatin1("owidgetstack-example"); }
+
+protected:
+ void closeEvent( QCloseEvent* e );
+private:
+ OWidgetStack* m_stack;
+ QWidget* m_main;
+
+};
+
+#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 @@
+CONFIG += qt warn_on
+TEMPLATE = app
+TARGET = owidgetstack-example
+
+SOURCES = ../owidgetstack.cpp owidgetstack_example.cpp
+HEADERS = ../owidgetstack.h owidgetstack_example.h
+
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDSPATH += $(OPIEDIR)/include
+
+LIBS += -lqpe
+
+include ( $(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 @@
+#include <qapplication.h>
+#include <qwidgetstack.h>
+
+#include "owidgetstack.h"
+
+namespace {
+ const int mode_size = 330;
+}
+
+/**
+ * This is the standard widget. For simple usage see the example. Normally this widget
+ * is the central widget of a QMainWindow.
+ * Use removeWidget before you delete a widget yourself. OWidgetStack does not
+ * yet recognize removal of children.
+ *
+ * @param parent The parent widget. It maybe 0 but then you need to take care of deletion.
+ * Or you use QPEApplication::showMainWidget().
+ * @param name Name will be passed on to QObject
+ * @param fl Additional window flags passed to QFrame. see @Qt::WFlags
+ */
+OWidgetStack::OWidgetStack( QWidget* parent, const char* name, WFlags fl)
+ : QFrame( parent, name, fl )
+{
+ m_last = m_mWidget = 0;
+ m_forced = false;
+
+ QApplication::desktop()->installEventFilter( this );
+ setFontPropagation ( AllChildren );
+ setPalettePropagation( AllChildren );
+
+ /* sets m_mode and initializes more */
+ /* if you change this call change switchTop as well */
+ m_stack = 0;
+ switchStack();
+}
+
+/**
+ * The destructor. It deletes also all added widgets.
+ *
+ */
+OWidgetStack::~OWidgetStack() {
+ if (m_mode == BigScreen && !m_list.isEmpty() ) {
+ QMap<int, QWidget*>::Iterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it )
+ delete it.data();
+ }
+ m_list.clear();
+
+}
+
+/**
+ * return the mode of the desktop. There are currently two modes. SmallScreen
+ * with a normal PDA resolution and BigScreen with resolutions greater than
+ * 330 for width and height.
+ * You can also force the mode this widget is in with forceMode()
+ * Note that NoForce will be never returned from here
+ */
+enum OWidgetStack::Mode OWidgetStack::mode()const {
+ return m_mode;
+}
+
+/**
+ * You can also force one of the modes and then
+ * this widget stops on listening to size changes. You
+ * can revert to the scanning behaviour by setting mode
+ * to NoForce
+ */
+void OWidgetStack::forceMode( enum Mode mode) {
+ m_forced = mode != NoForce;
+
+ /* we need to see which mode we're in */
+ if (!m_forced ) {
+ if ( QApplication::desktop()->width() >=
+ mode_size )
+ mode = BigScreen;
+ else
+ mode = SmallScreen;
+ }
+ switch( mode ) {
+ case NoForce:
+ case SmallScreen:
+ switchStack();
+ break;
+ case BigScreen:
+ switchTop();
+ break;
+
+ }
+
+ m_mode = mode;
+}
+
+/**
+ * Adds a widget to the stack. The first widget added is considered
+ * to be the mainwindow. This is important because if Opie is in
+ * BigScreen mode the sizeHint of the MainWindow will be returned.
+ * In Small Screen the sizeHint of the QWidgetStack is returned.
+ * See QWidgetStack::sizeHint.
+ * This widget takes ownership of the widget and may even reparent.
+ * All windows will be hidden
+ *
+ * @param wid The QWidget to be added
+ * @param id An ID for the Widget. If the ID is duplicated the
+ last set widget will be related to the id
+ *
+ */
+void OWidgetStack::addWidget( QWidget* wid, int id) {
+ if (!wid)
+ return;
+
+ /* set our main widget */
+ if (!m_mWidget)
+ m_mWidget = wid;
+
+ m_list.insert( id, wid );
+
+ /**
+ * adding does not raise any widget
+ * But for our mainwidget we prepare
+ * the right position with the right parent
+ */
+ if (m_mode == SmallScreen )
+ m_stack->addWidget( wid,id );
+ else if ( m_mWidget == wid ) {
+ wid->reparent(this, 0, contentsRect().topLeft() );
+ wid->hide();
+ }else {
+ wid->reparent(0, WType_TopLevel, QPoint(10, 10) );
+ wid->hide();
+ }
+}
+
+
+/**
+ * Remove the widget from the stack it'll be reparented to 0
+ * and ownership is dropped. You need to delete it.
+ * If the removed widget was the mainwindow consider
+ * to call setMainWindow.
+ *
+ * @param wid The QWidget to be removed
+ */
+void OWidgetStack::removeWidget( QWidget* wid) {
+ if (!wid)
+ return;
+
+ if (m_mode == SmallScreen )
+ m_stack->removeWidget( wid );
+
+
+ wid->reparent(0, 0, QPoint(0, 0) );
+ m_list.remove( id(wid) );
+
+ if ( wid == m_mWidget )
+ m_mWidget = 0;
+}
+
+#if 0
+/**
+ * @internal_resons
+ */
+QSizeHint OWidgetStack::sizeHint()const {
+
+}
+
+/**
+ * @internal_reasons
+ */
+QSizeHint OWidgetStack::minimumSizeHint()const {
+
+}
+#endif
+
+/**
+ * This function tries to find the widget with the id.
+ * You supplied a possible id in addWIdget. Note that not
+ * QWidget::winId() is used.
+ *
+ * @param id The id to search for
+ *
+ * @return The widget or null
+ * @see addWidget
+ */
+QWidget* OWidgetStack::widget( int id) const {
+ return m_list[id];
+}
+
+/**
+ * Tries to find the assigned id for the widget
+ * or returns -1 if no widget could be found
+ * @param wid The widget to look for
+ */
+int OWidgetStack::id( QWidget* wid)const{
+ if (m_list.isEmpty() )
+ return -1;
+
+ QMap<int, QWidget*>::ConstIterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it )
+ if ( it.data() == wid )
+ break;
+
+ /* if not at the end return the key */
+ return it == m_list.end() ? -1 : it.key();
+}
+
+
+/**
+ * This function returns the currently visible
+ * widget. In BigScreen mode the mainwindow
+ * is returned
+ */
+QWidget* OWidgetStack::visibleWidget()const {
+ if (m_mode == SmallScreen )
+ return m_stack->visibleWidget();
+ else
+ return m_mWidget;
+
+}
+
+/**
+ * This method raises the widget wit the specefic id.
+ * Note that in BigScreen mode the widget is made visible
+ * but the other ( previous) visible widget(s) will not
+ * be made invisible. If you need this use hideWidget().
+ *
+ * @param id Raise the widget with id
+ */
+void OWidgetStack::raiseWidget( int id) {
+ return raiseWidget( widget( id ) );
+}
+
+/**
+ * This is an overloaded function and only differs in its parameters.
+ * @see raiseWidget( int )
+ */
+void OWidgetStack::raiseWidget( QWidget* wid) {
+ m_last = wid;
+ if (m_mode == SmallScreen )
+ m_stack->raiseWidget( wid );
+ else {
+ int ide;
+ emit aboutToShow( wid );
+ /* if someone is connected and the widget is actually available */
+ if ( receivers( SIGNAL(aboutToShow(int) ) ) &&
+ ( (ide = id( wid ) ) != -1 ) )
+ emit aboutToShow( ide );
+
+ /* ### FIXME PLACE THE WIDGET right */
+ wid->show();
+ }
+}
+
+/**
+ * This will hide the currently visible widget
+ * and raise the widget specified by the parameter.
+ * Note that this method does not use visibleWIdget but remembers
+ * the last raisedWidget
+ */
+void OWidgetStack::hideWidget( int id) {
+ /* hiding our main widget wouldn't be smart */
+ if ( m_mode == BigScreen && m_last != m_mWidget )
+ m_last->hide();
+ raiseWidget( id );
+}
+
+/**
+ * This is overloaded and only differs in the parameters
+ * it takes.
+ */
+void OWidgetStack::hideWidget( QWidget* wid) {
+ /* still not smart */
+ if ( m_mode == BigScreen && m_last != m_mWidget )
+ m_last->hide();
+
+ raiseWidget( wid );
+}
+
+
+bool OWidgetStack::eventFilter( QObject* obj, QEvent* e) {
+ qWarning(" %s %s", obj->name(), obj->className() );
+ if ( e->type() == QEvent::Resize ) {
+ QResizeEvent *res = static_cast<QResizeEvent*>( e );
+ QSize size = res->size();
+ if ( size.width() >= mode_size )
+ switchTop();
+ else
+ switchStack();
+ }
+ return false;
+}
+
+
+/**
+ * @internal_resons
+ */
+void OWidgetStack::resizeEvent( QResizeEvent* ev ) {
+ QFrame::resizeEvent( ev );
+ if (m_mode == SmallScreen )
+ m_stack->setGeometry( frameRect() );
+ else
+ if (m_mWidget )
+ m_mWidget->setGeometry( frameRect() );
+
+}
+
+/**
+ * setMainWindow gives the OWidgetStack a hint which
+ * window should always stay inside the stack.
+ * Normally the first added widget is considered to be
+ * the mainwindow but you can change this with this
+ * function.
+ * If in BigScreen mode the current mainwindow will be reparented
+ * and hidden. The position will be taken by the new one.
+ * If the old MainWindow was hidden the new window will
+ * also be hidden. If the window was visible the new mainwindow
+ * will be made visible too and the old one hidden. If there
+ * was no mainwindow it will be hidden as well.
+ *
+ * @param wid The new mainwindow
+ */
+void OWidgetStack::setMainWindow( QWidget* wid ) {
+ if (m_mode == BigScreen ) {
+ bool wasVisible = false;
+ if (m_mWidget ) {
+ wasVisible = !m_mWidget->isHidden();
+ /* hidden by default */
+ m_mWidget->reparent(0, WType_TopLevel, QPoint(10, 10) );
+ }
+ wid->reparent(this, 0, frameRect().topLeft() );
+
+ if (wasVisible)
+ wid->show();
+ }
+
+ m_mWidget = wid;
+}
+
+/**
+ * this is an overloaded member and only differs
+ * in the type of arguments.
+ * @see setMainWindow(QWidget*)
+ */
+void OWidgetStack::setMainWindow( int id) {
+ setMainWindow( widget( id ) );
+}
+
+
+/*
+ * this function switches to a stack ;)
+ */
+void OWidgetStack::switchStack() {
+ if (m_stack ) {
+ m_stack->setGeometry( frameRect() );
+ return;
+ }
+
+ m_mode = SmallScreen;
+ m_stack = new QWidgetStack(this);
+
+ connect(m_stack, SIGNAL(aboutToShow(QWidget*) ),
+ this, SIGNAL(aboutToShow(QWidget*) ) );
+ connect(m_stack, SIGNAL(aboutToShow(int) ),
+ this, SIGNAL(aboutToShow(int) ) );
+
+ /* now reparent the widgets... luckily QWidgetSatck does most of the work */
+ if (m_list.isEmpty() )
+ return;
+
+ QMap<int, QWidget*>::Iterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it )
+ m_stack->addWidget( it.data(), it.key() );
+
+
+}
+
+/*
+ * we will switch to top level mode
+ * reparent the list of widgets and then delete the stack
+ */
+void OWidgetStack::switchTop() {
+ m_mode = BigScreen;
+ /* this works because it is guaranteed that switchStack was called at least once*/
+ if (!m_stack && m_mWidget) {
+ m_mWidget->setGeometry( frameRect() );
+ return;
+ }else if (!m_stack)
+ return;
+
+ if (!m_list.isEmpty() ) {
+ QMap<int, QWidget*>::Iterator it = m_list.begin();
+ for ( ; it != m_list.end(); ++it ) {
+ /* better than reparenting twice */
+ if ( it.data() == m_mWidget ) {
+ m_mWidget->reparent(this, 0, frameRect().topLeft() );
+ m_mWidget->setGeometry( frameRect() );
+ m_mWidget->show();
+ }else
+ /* ### FIXME we need to place the widget better */
+ it.data()->reparent(0, WType_TopLevel, QPoint(10, 10) );
+ }
+ }
+
+ delete m_stack;
+ m_stack = 0;
+}
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 @@
+/*
+               =. This file is part of the OPIE Project
+             .=l. Copyright (c) 2003 hOlgAr <zecke@handhelds.org>
+           .>+-=
+ _;:,     .>    :=|. This library is free software; you can
+.> <`_,   >  .   <= redistribute it and/or modify it under
+:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
+.="- .-=="i,     .._ License as published by the Free Software
+ - .   .-<_>     .<> Foundation; either version 2 of the License,
+     ._= =}       : or (at your option) any later version.
+    .%`+i>       _;_.
+    .i_,=:_.      -<s. This library is distributed in the hope that
+     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
+    : ..    .:,     . . . without even the implied warranty of
+    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
+  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
+..}^=.=       =       ; Library General Public License for more
+++=   -.     .`     .: details.
+ :     =  ...= . :.=-
+ -.   .:....=;==+<; You should have received a copy of the GNU
+  -_. . .   )=.  = Library General Public License along with
+    --        :-=` this library; see the file COPYING.LIB.
+ If not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef OPIE_BIG_WIDGET_STACK_H
+#define OPIE_BIG_WIDGET_STACK_H
+
+#include <qframe.h>
+#include <qmap.h>
+
+class QWidgetStack;
+/**
+ *
+ * OWidgetStack is the answer to the problem of using Opie at different screen
+ * sizes and to have a different behaviour. Most applications use a QWidgetStack
+ * to supply a view on click. And by clicking the (X) you go back but this
+ * behaviour feels strange on bigger screens. It's ok on smaller one because
+ * one can't determine the difference.
+ * This stack reads the default out of the size of the desktop widget but
+ * can be forced to have either the one or the other behaviour.
+ * The first widget added is considered the 'main' widget and its
+ * sizeHint will be taking if in BigScreen mode.
+ * In small screen mode this widget behaves exactly like a QWidgetStack and in BigScreen
+ * mode it'll use the MainWindow as child of this widget and arranges the others as
+ * hidden top level widgets.
+ *
+ * @version 0.1
+ * @author hOlgAr F.
+ * @short Either a true stack or a list of top Level widgets
+ */
+class OWidgetStack : public QFrame {
+ Q_OBJECT
+public:
+ enum Mode { SmallScreen, BigScreen, NoForce };
+ OWidgetStack( QWidget* parent, const char* name = 0, WFlags fl = 0 );
+ ~OWidgetStack();
+
+ enum Mode mode()const;
+ void forceMode( enum Mode );
+
+ void addWidget( QWidget* , int );
+ void removeWidget( QWidget* );
+
+// QSizeHint sizeHint()const;
+// QSizeHint minimumSizeHint()const;
+
+ QWidget *widget( int )const;
+ int id( QWidget* )const;
+
+
+
+ QWidget* visibleWidget() const;
+
+ bool eventFilter( QObject*, QEvent* );
+signals:
+ /**
+ * OWidgetStack monitors the Desktop Widget for
+ * size changes if it recignizes a change size it'll
+ * send a signal and adjust its mode. After the signal
+ * was emitted. During the signal a call to mode() the
+ * old mode will be returned. Note that if a size change happens
+ * but no modeChange no signal will be emitted
+ *
+ *
+ * @param mode The new mode of the desktop
+ */
+ void modeChanged( enum Mode mode);
+
+ /**
+ * These two signals are emitted whenever we're about to
+ * show one of the widgets
+ */
+ void aboutToShow( QWidget* );
+ void aboutToShow( int );
+
+public slots:
+ void raiseWidget( int );
+ void raiseWidget( QWidget* );
+ void hideWidget( int );
+ void hideWidget( QWidget* );
+ void setMainWindow( QWidget* );
+ void setMainWindow( int );
+
+protected:
+ void resizeEvent( QResizeEvent* );
+
+private:
+ void switchStack();
+ void switchTop();
+ QMap<int, QWidget*> m_list;
+ QWidgetStack *m_stack;
+ QWidget *m_mWidget;
+ QWidget *m_last;
+
+ enum Mode m_mode;
+ bool m_forced : 1;
+
+ struct Private;
+ Private *d;
+};
+
+
+#endif