resizing layouts
authorwesleyt@symbian.org
Thu, 09 Sep 2010 11:30:41 -0700
changeset 45 b23ec2b62c45
parent 44 ca3ea89c80a3
child 46 702dd26c0f4d
resizing layouts
ListElements/ModelViewList/PLLayout.cpp
ListElements/ModelViewList/PLLayout.h
ListElements/ModelViewList/listElements.pro
ListElements/ModelViewList/main.cpp
ListElements/ModelViewList/mainwindow.cpp
ListElements/ModelViewList/mainwindow.h
ListElements/ModelViewList/mainwindow.ui
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ListElements/ModelViewList/PLLayout.cpp	Thu Sep 09 11:30:41 2010 -0700
@@ -0,0 +1,221 @@
+#include "PLLayout.h"
+
+#include <QDebug>
+#include <QApplication>
+#include <QDesktopWidget>
+
+PLLayout::PLLayout()
+{
+    m_numOfClients=0;
+    m_currentLayoutIdx=-1;
+    m_portraitLayoutIdx=-1;
+    m_landscapeLayoutIdx=-1;
+    m_hasLLayout=false;
+    m_hasPLayout=false;
+    m_isPLayout=false;
+    m_isLLayout=false;
+}
+
+PLLayout::~PLLayout()
+{
+    //take ownership and responsibility to clean up the child layouts
+    while(m_numOfClients>0) {
+        delete(m_layoutList[--m_numOfClients]);
+    }
+}
+
+/*
+  FIRST, some basic methods that implement the quite
+  universal engine of this portrait landscape manager.
+*/
+int PLLayout::newLayout(QLayout *clientlayout)
+{
+    m_layoutList.append(clientlayout);
+    if(m_currentLayoutIdx==-1)
+        m_currentLayoutIdx=0;
+    return m_numOfClients++;
+}
+
+void PLLayout::activateLayout(int idx) {
+    if((idx>-1)&&(idx<m_numOfClients)) {
+        if(m_currentLayoutIdx != idx) {
+            m_currentLayoutIdx = idx;
+            redrawParent();
+        }
+    } else
+        qDebug() << "ERROR: selecting unassigned MultLayoutClient. IDX=" << idx
+                 << " numOfClients=" << m_numOfClients;
+}
+
+int PLLayout::getLayoutIdx() const
+{
+    return m_currentLayoutIdx;
+}
+
+void PLLayout::redrawParent()
+{
+    activate(); //inherited from QLayout
+    update();   //inherited from QLayout	
+    QWidget *w = parentWidget();
+    if(!(w == 0))
+        w->updateGeometry();
+}
+
+/*
+  NOW, implement all required methods of a QLayout Subclass, and point
+  them to the actual activated layout
+*/
+void PLLayout::addItem(QLayoutItem *item)
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return;
+    }
+    m_layoutList[getLayoutIdx()]->addItem(item);
+}
+
+QSize PLLayout::sizeHint() const {
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return QSize(0,0);
+    }
+    return (m_layoutList[getLayoutIdx()]->sizeHint());
+}
+
+QSize PLLayout::minimumSize() const
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return QSize(0,0);
+    }
+    return( m_layoutList[getLayoutIdx()]->minimumSize());
+}
+
+void PLLayout::setGeometry(const QRect &rect)
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return ;
+    }
+    m_layoutList[getLayoutIdx()]->setGeometry(rect);
+}
+
+bool PLLayout::hasHeightForWidth() const
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return false;
+    }
+    return m_layoutList[getLayoutIdx()]->hasHeightForWidth();
+}
+
+int PLLayout::heightForWidth(int n) const
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return 0;
+    }
+    return m_layoutList[getLayoutIdx()]->heightForWidth(n);
+}
+
+
+QLayoutItem * PLLayout::itemAt(int index) const
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return 0;
+    }
+    return m_layoutList[getLayoutIdx()]->itemAt(index);
+}
+
+
+QLayoutItem * PLLayout::takeAt(int index)
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return 0;
+    }
+    return m_layoutList[getLayoutIdx()]->takeAt(index);
+}
+
+int PLLayout::count() const
+{
+    if (m_numOfClients<0) {
+        qDebug() << "ERROR: using MultLayout before assigning client.";
+        return 0;
+    }
+    return m_layoutList[getLayoutIdx()]->count();
+}
+
+/*
+  Now we add some convenience API methods to handle portrait/landscape comfortable
+  While the above mechanism is quite universal and may be re-used beyond portrait
+  landscape use case, these implement the dedicated API for portrait / landscape use.
+*/
+int PLLayout::setLLayout(QLayout *clientlayout)
+{
+    if(m_hasLLayout) {
+        qDebug() << "ERROR: re-assigning Layout to FthLPMultiLayout is not allowed";
+        return -1;
+    }
+    int i = newLayout(clientlayout);
+    m_hasLLayout = true;
+    m_landscapeLayoutIdx = i;
+    activateLayout(m_landscapeLayoutIdx);
+    m_isLLayout = true;
+    return i;
+}
+
+int PLLayout::setPLayout(QLayout *clientlayout)
+{
+    if(m_hasPLayout) {
+        qDebug() << "ERROR: re-assigning Layout to FthLPMultiLayout is not allowed";
+        return -1;
+    }
+    int i = newLayout(clientlayout);
+    m_hasPLayout = true;
+    m_portraitLayoutIdx = i;
+    activateLayout(m_portraitLayoutIdx);
+    m_isPLayout = true;
+    return i;
+}
+
+void PLLayout::activatePLayout()
+{
+    if((m_isLLayout)&&(m_hasPLayout)) {
+        activateLayout(m_portraitLayoutIdx);
+        m_isPLayout = true;
+    } else {
+        qDebug() << "ERROR: first assign portrait and landscape layouts to FthLPMultiLayout";
+    }
+}
+
+void PLLayout::activateLLayout()
+{
+    if((m_isPLayout)&&(m_hasLLayout)) {
+        activateLayout(m_landscapeLayoutIdx);
+        m_isLLayout = true;
+    } else {
+        qDebug() << "ERROR: first assign portrait and landscape layouts to FthLPMultiLayout";
+    }
+}
+
+/*
+    and finally a convenience function for the parent widgets event handler
+*/
+
+void PLLayout::resizeEvent(QResizeEvent* event)
+{
+    QRect qs=QApplication::desktop()->availableGeometry();
+    if(qs.height() > qs.width())
+        activatePLayout();
+    else
+        activateLLayout();
+}
+
+/*
+  REFERENCES
+        http://lists.trolltech.com/qt-interest/2004-01/thread00746-0.html
+        http://wiki.forum.nokia.com/index.php/CS001437_-_Listening_for_screen_orientation_changes_in_Qt
+        http://wiki.forum.nokia.com/index.php/Dynamic_Layout_handling_with_QWidget
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ListElements/ModelViewList/PLLayout.h	Thu Sep 09 11:30:41 2010 -0700
@@ -0,0 +1,59 @@
+#ifndef PLLAYOUT_H
+#define PLLAYOUT_H
+
+#include <QLayout>
+#include <QResizeEvent>
+
+
+
+
+class PLLayout : public QLayout
+{
+    Q_OBJECT
+
+public:
+    PLLayout();
+    ~PLLayout();
+    //the main API methods
+    int setLLayout(QLayout *clientlayout);
+    int setPLayout(QLayout *clientlayout);
+    void activatePLayout();
+    void activateLLayout();
+    //re-implementation of QLayout Methods, as needed
+    void addItem(QLayoutItem *item);
+    QSize sizeHint() const;
+    QSize minimumSize() const;
+    void setGeometry(const QRect &rect);
+    bool hasHeightForWidth() const;
+    int heightForWidth( int ) const;
+    QLayoutItem * itemAt(int index ) const;
+    QLayoutItem * takeAt ( int index );
+    int count() const;
+
+    //a convenience method for the parent widgets event handler
+    void resizeEvent(QResizeEvent* event);
+
+protected:
+    //these two may be promoted to public, when extending to more generic use cases
+    void activateLayout(int idx);
+    int newLayout(QLayout *clientlayout);
+
+private:
+
+    QList<QLayout*> m_layoutList;
+    int m_numOfClients;
+    int m_currentLayoutIdx;
+
+    int m_portraitLayoutIdx;
+    int m_landscapeLayoutIdx;
+    int getLayoutIdx()const ;
+
+    bool m_hasPLayout;
+    bool m_hasLLayout;
+    bool m_isPLayout;
+    bool m_isLLayout;
+
+    void redrawParent();
+};
+
+#endif // PLLAYOUT_H
--- a/ListElements/ModelViewList/listElements.pro	Wed Sep 08 15:36:31 2010 -0700
+++ b/ListElements/ModelViewList/listElements.pro	Thu Sep 09 11:30:41 2010 -0700
@@ -14,13 +14,15 @@
     zodiacsign.cpp \
     mainwindow.cpp \
     zodiacmodel.cpp \
-    zodiacdelegate.cpp
+    zodiacdelegate.cpp \
+    PLLayout.cpp
 
 
 HEADERS  += mainwindow.h \
     zodiacsign.h \
     zodiacmodel.h \
-    zodiacdelegate.h
+    zodiacdelegate.h \
+    PLLayout.h
 
 FORMS    += mainwindow.ui
 
--- a/ListElements/ModelViewList/main.cpp	Wed Sep 08 15:36:31 2010 -0700
+++ b/ListElements/ModelViewList/main.cpp	Thu Sep 09 11:30:41 2010 -0700
@@ -1,16 +1,27 @@
+
+
 #include <QtGui/QApplication>
 #include "mainwindow.h"
+#include <QApplication>
+#include <QPushButton>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
 
 int main(int argc, char *argv[])
 {
+    QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes);
     QApplication a(argc, argv);
     MainWindow w;
     w.setWindowTitle("Zodiac");
 #if defined(Q_WS_S60)
-    w.showMaximized();
+    // w.showMaximized();
+    w.showFullScreen();
 #else
     w.show();
 #endif
+    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );
 
     return a.exec();
+
+
 }
--- a/ListElements/ModelViewList/mainwindow.cpp	Wed Sep 08 15:36:31 2010 -0700
+++ b/ListElements/ModelViewList/mainwindow.cpp	Thu Sep 09 11:30:41 2010 -0700
@@ -1,23 +1,62 @@
 #include <QMenuBar>
+#include <QMessageBox>
+#include <QResizeEvent>
+#include <QtGlobal>
 
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
 #include "zodiacmodel.h"
 #include "zodiacdelegate.h"
 
+
 MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::MainWindow)
 {
     ui->setupUi(this);
 
+    // Create widgets.
+    listView = new QListView;
+    listView->setFrameStyle(QFrame::Panel | QFrame::Raised);
+    listView->setLineWidth(4);
+    exitButton = new QPushButton(this);
+    exitButton->setText("Exit");
+
+    // define the model
     ZodiacModel *zModel = new ZodiacModel(this);
-    ui->listView->setModel(zModel);
+    listView->setModel(zModel);
     ZodiacDelegate *delegate = new ZodiacDelegate(this);
-    ui->listView->setItemDelegate(delegate);
+    listView->setItemDelegate(delegate);
+
+    // create landscape layout
+    layoutLandscape = new QHBoxLayout(this);
+    layoutLandscape->addWidget(listView);
+    layoutLandscape->addWidget(exitButton);
+
+    //create portrait layout
+    layoutPortrait = new QVBoxLayout(this);
+    layoutPortrait->addWidget(listView);
+    layoutPortrait->addWidget(exitButton);
+
+    portLandLayout = new PLLayout();
+    portLandLayout->setPLayout(layoutPortrait);
+    portLandLayout->setLLayout(layoutLandscape);
+
+    centralWidget = new QWidget();
+    centralWidget->setLayout(portLandLayout);
+    this->setCentralWidget(centralWidget);
+
 }
 
+
 MainWindow::~MainWindow()
 {
     delete ui;
 }
+
+void MainWindow::resizeEvent(QResizeEvent *e)
+{
+    portLandLayout->resizeEvent(e);
+    // Call base class impl
+    QWidget::resizeEvent(e);
+}
--- a/ListElements/ModelViewList/mainwindow.h	Wed Sep 08 15:36:31 2010 -0700
+++ b/ListElements/ModelViewList/mainwindow.h	Thu Sep 09 11:30:41 2010 -0700
@@ -1,8 +1,16 @@
 #ifndef MAINWINDOW_H
 #define MAINWINDOW_H
 
+#include <QFrame>
+#include <QListView>
 #include <QMainWindow>
+#include <QPushButton>
+#include <QStackedWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
 
+#include <QWidget>
+#include "PLLayout.h"
 #include "zodiacsign.h"
 
 namespace Ui {
@@ -17,8 +25,20 @@
     explicit MainWindow(QWidget *parent = 0);
     ~MainWindow();
 
+    void resizeEvent(QResizeEvent *e);
+
 private:
     Ui::MainWindow *ui;
+
+    QHBoxLayout *layoutLandscape;
+    QWidget *centralWidget;
+    QVBoxLayout *layoutPortrait;
+
+    QPushButton *exitButton;
+    QListView *listView;
+    PLLayout *portLandLayout;
+
+
 };
 
 #endif // MAINWINDOW_H
--- a/ListElements/ModelViewList/mainwindow.ui	Wed Sep 08 15:36:31 2010 -0700
+++ b/ListElements/ModelViewList/mainwindow.ui	Thu Sep 09 11:30:41 2010 -0700
@@ -13,42 +13,7 @@
   <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QWidget" name="centralWidget">
-   <widget class="QFrame" name="frame">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>0</y>
-      <width>361</width>
-      <height>411</height>
-     </rect>
-    </property>
-    <property name="frameShape">
-     <enum>QFrame::Panel</enum>
-    </property>
-    <property name="frameShadow">
-     <enum>QFrame::Raised</enum>
-    </property>
-    <property name="lineWidth">
-     <number>4</number>
-    </property>
-    <widget class="QListView" name="listView">
-     <property name="geometry">
-      <rect>
-       <x>10</x>
-       <y>10</y>
-       <width>341</width>
-       <height>391</height>
-      </rect>
-     </property>
-     <property name="font">
-      <font>
-       <pointsize>14</pointsize>
-      </font>
-     </property>
-    </widget>
-   </widget>
-  </widget>
+  <widget class="QWidget" name="centralWidget"/>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <resources/>