keep track of what layout we belong to so that we can remove ourselves from the layout when we exit; prevents crashes when items are added then deleted later. since we aren't guaranteed a QObject, we can't do the obvious thing (e.g. listen for the destroyed() signal)

svn path=/trunk/KDE/kdebase/workspace/plasma/lib/; revision=668928
This commit is contained in:
Aaron J. Seigo 2007-05-28 05:46:24 +00:00
parent 10dd76c794
commit c300ff48bc
4 changed files with 106 additions and 63 deletions

View File

@ -17,26 +17,37 @@
*/ */
#include "layoutitem.h" #include "layoutitem.h"
#include "layout.h"
namespace Plasma namespace Plasma
{ {
class LayoutItem::Private class LayoutItem::Private
{ {
public: public:
Private() {} Private()
~Private() {} : layout(0)
{
}
~Private() {}
Layout* layout;
}; };
LayoutItem::LayoutItem() LayoutItem::LayoutItem()
: d(new Private) : d(new Private)
{ {
} }
LayoutItem::~LayoutItem() LayoutItem::~LayoutItem()
{ {
delete d; if (d->layout) {
d->layout->removeItem(this);
}
delete d;
} }
bool LayoutItem::hasHeightForWidth() const bool LayoutItem::hasHeightForWidth() const
@ -59,4 +70,18 @@ qreal LayoutItem::widthForHeight(qreal h) const
return 0.0; return 0.0;
} }
void LayoutItem::setLayout(Layout* layout)
{
if (d->layout) {
d->layout->removeItem(this);
}
d->layout = layout;
}
Layout* LayoutItem::layout()
{
return d->layout;
}
} }

View File

@ -27,34 +27,39 @@
namespace Plasma namespace Plasma
{ {
class Layout;
/** /**
* Base class for Plasma layout-managed items * Base class for Plasma layout-managed items
*/ */
class KDE_EXPORT LayoutItem class KDE_EXPORT LayoutItem
{ {
public: public:
LayoutItem(); LayoutItem();
virtual ~LayoutItem(); virtual ~LayoutItem();
virtual Qt::Orientations expandingDirections() const = 0; virtual Qt::Orientations expandingDirections() const = 0;
virtual QSizeF minimumSize() const = 0; virtual QSizeF minimumSize() const = 0;
virtual QSizeF maximumSize() const = 0; virtual QSizeF maximumSize() const = 0;
virtual bool hasHeightForWidth() const; virtual bool hasHeightForWidth() const;
virtual qreal heightForWidth(qreal w) const; virtual qreal heightForWidth(qreal w) const;
virtual bool hasWidthForHeight() const; virtual bool hasWidthForHeight() const;
virtual qreal widthForHeight(qreal h) const; virtual qreal widthForHeight(qreal h) const;
virtual QRectF geometry() const = 0; virtual QRectF geometry() const = 0;
virtual void setGeometry(const QRectF& geometry) = 0; virtual void setGeometry(const QRectF& geometry) = 0;
virtual QSizeF sizeHint() const = 0; virtual QSizeF sizeHint() const = 0;
private: void setLayout(Layout* layout);
class Private; Layout* layout();
Private *const d;
private:
class Private;
Private *const d;
}; };
} }

View File

@ -20,6 +20,8 @@
#include <QtCore/QList> #include <QtCore/QList>
#include <KDebug>
namespace Plasma namespace Plasma
{ {
@ -76,57 +78,53 @@ QRectF VBoxLayout::geometry() const
void VBoxLayout::setGeometry(const QRectF& geometry) void VBoxLayout::setGeometry(const QRectF& geometry)
{ {
if(!geometry.isValid() || geometry.isEmpty()) { if (!geometry.isValid() || geometry.isEmpty()) {
qDebug("Invalid Geometry!"); kDebug() << "Invalid Geometry!" << endl;
return;
}
return; qDebug("Geometry %p : %f, %f by %f, %f", this, geometry.x(), geometry.y(), geometry.width(), geometry.height());
}
qDebug("Geometry %p : %f, %f by %f, %f", this, geometry.x(), geometry.y(), geometry.width(), geometry.height()); QList<LayoutItem *> childs;
QList<LayoutItem *> expandingChilds;
QList<QSizeF> sizes;
QSizeF available = geometry.size() - QSizeF(2 * margin(), 2 * margin());
QList<LayoutItem *> childs; foreach (LayoutItem *l, d->childList) {
QList<LayoutItem *> expandingChilds; kDebug() << "testing layout item " << l << endl;
QList<QSizeF> sizes; if (l->expandingDirections() & Qt::Vertical) {
QSizeF available = geometry.size() - QSizeF(2 * margin(), 2 * margin()); expandingChilds += l;
} else {
foreach(LayoutItem *l, d->childList) { childs += l;
}
}
if(l->expandingDirections() & Qt::Vertical) { foreach (LayoutItem *l, childs) {
QSizeF hint = l->sizeHint();
sizes.insert(indexOf(l), QSizeF(available.width(), hint.height()));
available -= QSizeF(0.0, hint.height() + spacing());
}
expandingChilds += l; qreal expandHeight = (available.height() - ((expandingChilds.count() - 1) * spacing())) / expandingChilds.count();
} else {
childs += l; foreach (LayoutItem *l, expandingChilds) {
}
}
foreach(LayoutItem *l, childs) { sizes.insert(indexOf(l),QSizeF(available.width(), expandHeight));
}
QSizeF hint = l->sizeHint(); QPointF start = geometry.topLeft();
start += QPointF(margin(), spacing());
sizes.insert(indexOf(l), QSizeF(available.width(), hint.height())); for (int i = 0; i < sizes.size(); i++) {
available -= QSizeF(0.0, hint.height() + spacing());
}
qreal expandHeight = (available.height() - ((expandingChilds.count() - 1) * spacing())) / expandingChilds.count(); LayoutItem *l = itemAt(i);
foreach(LayoutItem *l, expandingChilds) { l->setGeometry(QRectF(start, sizes[i]));
start += QPointF(0.0, sizes[i].height() + spacing());
}
sizes.insert(indexOf(l),QSizeF(available.width(), expandHeight)); d->geometry = geometry;
}
QPointF start = geometry.topLeft();
start += QPointF(margin(), spacing());
for(int i = 0; i < sizes.size(); i++) {
LayoutItem *l = itemAt(i);
l->setGeometry(QRectF(start, sizes[i]));
start += QPointF(0.0, sizes[i].height() + spacing());
}
d->geometry = geometry;
} }
QSizeF VBoxLayout::sizeHint() const QSizeF VBoxLayout::sizeHint() const
@ -155,13 +153,27 @@ bool VBoxLayout::isEmpty() const
return count() == 0; return count() == 0;
} }
void VBoxLayout::insertItem(int index, LayoutItem *l)
{
if (!l) {
return;
}
l->setLayout(this);
d->childList.insert(index, l);
setGeometry(geometry());
}
void VBoxLayout::addItem(LayoutItem *l) void VBoxLayout::addItem(LayoutItem *l)
{ {
d->childList.append(l); if (!l) {
return;
}
qDebug("Added Child LayoutItem : %p", l); l->setLayout(this);
d->childList.append(l);
setGeometry(geometry()); qDebug("Added Child LayoutItem : %p", l);
setGeometry(geometry());
} }
void VBoxLayout::removeItem(LayoutItem *l) void VBoxLayout::removeItem(LayoutItem *l)

View File

@ -57,6 +57,7 @@ class KDE_EXPORT VBoxLayout : public Layout
bool isEmpty() const; bool isEmpty() const;
void insertItem(int index, LayoutItem *l);
void addItem(LayoutItem *l); void addItem(LayoutItem *l);
void removeItem(LayoutItem *l); void removeItem(LayoutItem *l);