# HG changeset patch # User unc0rr # Date 1291748529 -10800 # Node ID 63a21fac8bf757bdf2bb0b4771e8878dac7cdfa0 # Parent 54e78c40970b21e28d626dd1480763efc88f39c5 Add QAspectRatioLayout borrowed from http://wiki.forum.nokia.com/index.php/CS001309_-_Maintaining_square_form_for_a_widget_in_Qt to maintain width == height * 2 aspect ratio for map drawing widget diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/drawMapTest.pro --- a/tools/drawMapTest/drawMapTest.pro Mon Dec 06 21:15:41 2010 -0500 +++ b/tools/drawMapTest/drawMapTest.pro Tue Dec 07 22:02:09 2010 +0300 @@ -5,7 +5,11 @@ TEMPLATE = app SOURCES += main.cpp \ mainwindow.cpp \ - drawmapscene.cpp + drawmapscene.cpp \ + qaspectratiolayout.cpp \ + drawmapwidget.cpp HEADERS += mainwindow.h \ - drawmapscene.h + drawmapscene.h \ + qaspectratiolayout.h \ + drawmapwidget.h FORMS += mainwindow.ui diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/drawmapwidget.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/drawMapTest/drawmapwidget.cpp Tue Dec 07 22:02:09 2010 +0300 @@ -0,0 +1,38 @@ +#include "drawmapwidget.h" + +DrawMapWidget::DrawMapWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::DrawMapWidget) +{ + ui->setupUi(this); +} + +DrawMapWidget::~DrawMapWidget() +{ + delete ui; +} + +void DrawMapWidget::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} + +void DrawMapWidget::setScene(DrawMapScene * scene) +{ + ui->graphicsView->setScene(scene); +} + +void DrawMapWidget::resizeEvent(QResizeEvent * event) +{ + Q_UNUSED(event); + + if(ui->graphicsView && ui->graphicsView->scene()) + ui->graphicsView->fitInView(ui->graphicsView->scene()->sceneRect(), Qt::KeepAspectRatio); +} diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/drawmapwidget.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/drawMapTest/drawmapwidget.h Tue Dec 07 22:02:09 2010 +0300 @@ -0,0 +1,61 @@ +#ifndef DRAWMAPWIDGET_H +#define DRAWMAPWIDGET_H + +#include +#include +#include +#include +#include + +#include "qaspectratiolayout.h" +#include "drawmapscene.h" + +namespace Ui { + class Ui_DrawMapWidget + { + public: + QGraphicsView *graphicsView; + QPushButton *pbUndo; + + void setupUi(QWidget *drawMapWidget) + { + QAspectRatioLayout * arLayout = new QAspectRatioLayout(drawMapWidget); + arLayout->setMargin(0); + + graphicsView = new QGraphicsView(drawMapWidget); + arLayout->addWidget(graphicsView); + + retranslateUi(drawMapWidget); + + QMetaObject::connectSlotsByName(drawMapWidget); + } // setupUi + + void retranslateUi(QWidget *drawMapWidget) + { + Q_UNUSED(drawMapWidget); + } // retranslateUi + + }; + + class DrawMapWidget: public Ui_DrawMapWidget {}; +} + +class DrawMapWidget : public QWidget +{ + Q_OBJECT + +public: + explicit DrawMapWidget(QWidget *parent = 0); + ~DrawMapWidget(); + + void setScene(DrawMapScene * scene); + +protected: + void changeEvent(QEvent *e); + virtual void resizeEvent(QResizeEvent * event); + +private: + Ui::DrawMapWidget *ui; +}; + +#endif // DRAWMAPWIDGET_H diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/mainwindow.cpp --- a/tools/drawMapTest/mainwindow.cpp Mon Dec 06 21:15:41 2010 -0500 +++ b/tools/drawMapTest/mainwindow.cpp Tue Dec 07 22:02:09 2010 +0300 @@ -11,7 +11,8 @@ ui->setupUi(this); scene = new DrawMapScene(this); - ui->graphicsView->setScene(scene); + //ui->graphicsView->setScene(scene); + ui->drawMapWidget->setScene(scene); connect(ui->pbUndo, SIGNAL(clicked()), scene, SLOT(undo())); connect(scene, SIGNAL(pathChanged()), this, SLOT(scene_pathChanged())); @@ -34,14 +35,6 @@ } } -void MainWindow::resizeEvent(QResizeEvent * event) -{ - Q_UNUSED(event); - - if(ui->graphicsView) - ui->graphicsView->fitInView(ui->graphicsView->scene()->sceneRect(), Qt::KeepAspectRatio); -} - void MainWindow::scene_pathChanged() { QString str = scene->encode().toBase64(); @@ -49,11 +42,6 @@ ui->sbBytes->setValue(str.size()); } -void MainWindow::on_pbSimplify_clicked() -{ - scene->simplifyLast(); -} - void MainWindow::on_pbSave_clicked() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save map"), "."); diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/mainwindow.h --- a/tools/drawMapTest/mainwindow.h Mon Dec 06 21:15:41 2010 -0500 +++ b/tools/drawMapTest/mainwindow.h Tue Dec 07 22:02:09 2010 +0300 @@ -22,12 +22,9 @@ Ui::MainWindow *ui; DrawMapScene * scene; - virtual void resizeEvent(QResizeEvent * event); - private slots: void on_pbLoad_clicked(); void on_pbSave_clicked(); - void on_pbSimplify_clicked(); void scene_pathChanged(); }; diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/mainwindow.ui --- a/tools/drawMapTest/mainwindow.ui Mon Dec 06 21:15:41 2010 -0500 +++ b/tools/drawMapTest/mainwindow.ui Tue Dec 07 22:02:09 2010 +0300 @@ -15,9 +15,6 @@ - - - @@ -75,10 +72,21 @@ + + + + + + DrawMapWidget + QWidget +
drawmapwidget.h
+ 1 +
+
diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/qaspectratiolayout.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/drawMapTest/qaspectratiolayout.cpp Tue Dec 07 22:02:09 2010 +0300 @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2009 Nokia Corporation. + */ + +#include "qaspectratiolayout.h" + +QAspectRatioLayout::QAspectRatioLayout(QWidget* parent, int spacing) : QLayout(parent) { + init(spacing); +} + +QAspectRatioLayout::QAspectRatioLayout(int spacing) { + init(spacing); +} + +QAspectRatioLayout::~QAspectRatioLayout() { + delete item; + delete lastReceivedRect; + delete _geometry; +} + +void QAspectRatioLayout::init(int spacing) { + item = 0; + lastReceivedRect = new QRect(0, 0, 0, 0); + _geometry = new QRect(0, 0, 0, 0); + setSpacing(spacing); +} + + +/* Adds item if place isn't already taken. */ +void QAspectRatioLayout::add(QLayoutItem* item) { + if(!hasItem()) { + replaceItem(item); + } +} + +/* Adds item if place isn't already taken. */ +void QAspectRatioLayout::addItem(QLayoutItem* item) { + if(!hasItem()) { + replaceItem(item); + } +} + +/* Adds widget if place isn't already taken. */ +void QAspectRatioLayout::addWidget(QWidget* widget) { + if(!hasItem()) { + replaceItem(new QWidgetItem(widget)); + } +} + +/* Returns the item pointer and dereferences it here. */ +QLayoutItem* QAspectRatioLayout::take() { + QLayoutItem* item = 0; + if(this->hasItem()) { + item = this->item; + this->item = 0; + } + return item; +} + +/* Returns the item pointer and dereferences it here. */ +QLayoutItem* QAspectRatioLayout::takeAt(int index) { + if(index != 0) { + return 0; + } + return this->take(); +} + +/* Returns the item pointer. */ +QLayoutItem* QAspectRatioLayout::itemAt(int index) const { + if(index != 0) { + return 0; + } + if(hasItem()) { + return this->item; + } + return 0; +} + +/* Checks if we have an item. */ +bool QAspectRatioLayout::hasItem() const { + return this->item != 0; +} + +/* Returns the count of items which can be either 0 or 1. */ +int QAspectRatioLayout::count() const { + int returnValue = 0; + if(hasItem()) { + returnValue = 1; + } + return returnValue; +} + +/* Replaces the item with the new and returns the old. */ +QLayoutItem* QAspectRatioLayout::replaceItem(QLayoutItem* item) { + QLayoutItem* old = 0; + if(this->hasItem()) { + old = this->item; + } + this->item = item; + setGeometry(*this->_geometry); + return old; +} + +/* Tells which way layout expands. */ +Qt::Orientations QAspectRatioLayout::expandingDirections() const { + return Qt::Horizontal | Qt::Vertical; +} + +/* Tells which size is preferred. */ +QSize QAspectRatioLayout::sizeHint() const { + return this->item->minimumSize(); +} + +/* Tells minimum size. */ +QSize QAspectRatioLayout::minimumSize() const { + return this->item->minimumSize(); +} + +/* + * Tells if heightForWidth calculations is handled. + * It isn't since width isn't enough to calculate + * proper size. + */ +bool QAspectRatioLayout::hasHeightForWidth() const { + return false; +} + +/* Replaces lastReceivedRect. */ +void QAspectRatioLayout::setLastReceivedRect(const QRect& rect) { + QRect* oldRect = this->lastReceivedRect; + this->lastReceivedRect = new QRect(rect.topLeft(), rect.size()); + delete oldRect; +} + +/* Returns geometry */ +QRect QAspectRatioLayout::geometry() { + return QRect(*this->_geometry); +} + +/* Sets geometry to given size. */ +void QAspectRatioLayout::setGeometry(const QRect& rect) { + /* + * We check if the item is set and + * if size is the same previously received. + * If either is false nothing is done. + */ + if(!this->hasItem() || + areRectsEqual(*this->lastReceivedRect, rect)) { + return; + } + /* Replace the last received rectangle. */ + setLastReceivedRect(rect); + /* Calculate proper size for the item relative to the received size. */ + QSize properSize = calculateProperSize(rect.size()); + /* Calculate center location in the rect and with item size. */ + QPoint properLocation = calculateCenterLocation(rect.size(), properSize); + /* Set items geometry */ + this->item->setGeometry(QRect(properLocation, properSize)); + QRect* oldRect = this->_geometry; + /* Cache the calculated geometry. */ + this->_geometry = new QRect(properLocation, properSize); + delete oldRect; + /* Super classes setGeometry */ + QLayout::setGeometry(*this->_geometry); +} + +/* Takes the shortest side and creates QSize + * with the shortest side as width and height. */ +QSize QAspectRatioLayout::calculateProperSize(QSize from) const { + QSize properSize; + if(from.height() * 2 < from.width()) { + properSize.setHeight(from.height() - this->margin()); + properSize.setWidth(from.height() * 2 - this->margin()); + } + else { + properSize.setWidth(from.width() - this->margin()); + properSize.setHeight(from.width() / 2 - this->margin()); + } + return properSize; +} + +/* Calculates center location from the given height and width for item size. */ +QPoint QAspectRatioLayout::calculateCenterLocation(QSize from, + QSize itemSize) const { + QPoint centerLocation; + if((from.width() - itemSize.width()) > 0) { + centerLocation.setX((from.width() - itemSize.width())/2); + } + if((from.height() - itemSize.height()) > 0) { + centerLocation.setY((from.height() - itemSize.height())/2); + } + return centerLocation; +} + +/* Compares if two QRects are equal. */ +bool QAspectRatioLayout::areRectsEqual(const QRect& a, + const QRect& b) const { + bool result = false; + if(a.x() == b.x() && + a.y() == b.y() && + a.height() == b.height() && + a.width() == b.width()) { + result = true; + } + return result; +} diff -r 54e78c40970b -r 63a21fac8bf7 tools/drawMapTest/qaspectratiolayout.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/drawMapTest/qaspectratiolayout.h Tue Dec 07 22:02:09 2010 +0300 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2009 Nokia Corporation. + */ + +#ifndef QASPECTRATIOLAYOUT_H_ +#define QASPECTRATIOLAYOUT_H_ + +#include +#include +#include +#include +#include + + +class QAspectRatioLayout : public QLayout +{ + Q_OBJECT + +public: + QAspectRatioLayout(QWidget* parent, int spacing =-1); + QAspectRatioLayout(int spacing = -1); + ~QAspectRatioLayout(); + + /* Convenience method */ + virtual void add(QLayoutItem* item); + +/* http://doc.trolltech.com/qlayout.html#addItem */ + virtual void addItem(QLayoutItem* item); + /* http://doc.trolltech.com/qlayout.html#addWidget */ + virtual void addWidget(QWidget* widget); + /* http://doc.trolltech.com/qlayout.html#takeAt */ + virtual QLayoutItem* takeAt(int index); + /* http://doc.trolltech.com/qlayout.html#itemAt */ + virtual QLayoutItem* itemAt(int index) const; + /* http://doc.trolltech.com/qlayout.html#count */ + virtual int count() const; + + /* + * These are ours since we do have only one item. + */ + virtual QLayoutItem* replaceItem(QLayoutItem* item); + virtual QLayoutItem* take(); + virtual bool hasItem() const; + +/* http://doc.trolltech.com/qlayout.html#expandingDirections */ + virtual Qt::Orientations expandingDirections() const; + + /* + * This method contains most of the juice of this article. + * http://doc.trolltech.com/qlayoutitem.html#setGeometry + */ + virtual void setGeometry(const QRect& rect); + /* http://doc.trolltech.com/qlayoutitem.html#geometry */ + virtual QRect geometry(); + + /* http://doc.trolltech.com/qlayoutitem.html#sizeHint */ + virtual QSize sizeHint() const; + /* http://doc.trolltech.com/qlayout.html#minimumSize */ + virtual QSize minimumSize() const; + /* http://doc.trolltech.com/qlayoutitem.html#hasHeightForWidth */ + virtual bool hasHeightForWidth() const; + +private: + /* Saves the last received rect. */ + void setLastReceivedRect(const QRect& rect); + /* Used to initialize the object. */ + void init(int spacing); + /* Calculates the maximum size for the item from the assigned size. */ + QSize calculateProperSize(QSize from) const; + /* Calculates the center location from the assigned size and + * the items size. */ + QPoint calculateCenterLocation(QSize from, QSize itemSize) const; + /* Check if two QRects are equal */ + bool areRectsEqual(const QRect& a, const QRect& b) const; + /* Contains item reference */ + QLayoutItem* item; + /* + * Used for caching so we won't do calculations every time + * setGeometry is called. + */ + QRect* lastReceivedRect; + /* Contains geometry */ + QRect* _geometry; + +}; + +#endif /* QASPECTRATIOLAYOUT_H_ */