From fa69a979c9fca3e45d048ee67593dc48fb5b0847 Mon Sep 17 00:00:00 2001 From: Jason Stubbs Date: Sat, 22 Dec 2007 12:32:55 +0000 Subject: [PATCH] Try to place unpositioned applets in areas that aren't occupied using a very simple placement policy. BUG: 154122 svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=751607 --- containment.cpp | 59 +++++++++++++++++++++++++++++++++++++++++-------- containment.h | 3 +++ 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/containment.cpp b/containment.cpp index 6ee4b2dd3..217350894 100644 --- a/containment.cpp +++ b/containment.cpp @@ -417,15 +417,7 @@ Applet* Containment::addApplet(const QString& name, const QVariantList& args, ui applet->setGeometry(QRectF(appletGeometry.topLeft(), applet->sizeHint())); } else if (geometry().isValid()) { - //TODO: Make sure new applets don't overlap with existing ones - // Center exactly: - QSizeF size = applet->sizeHint(); - qreal appletWidth = size.width(); - qreal appletHeight = size.height(); - qreal width = geometry().width(); - qreal height = geometry().height(); - //kDebug() << "measuring geometry with" << appletWidth << appletHeight << width << height; - applet->setGeometry(QRectF(QPointF((width / 2) - (appletWidth / 2), (height / 2) - (appletHeight / 2)), size)); + applet->setGeometry(geometryForApplet(applet)); } //kDebug() << applet->name() << "sizehint:" << applet->sizeHint() << "geometry:" << applet->geometry(); @@ -443,6 +435,55 @@ Applet* Containment::addApplet(const QString& name, const QVariantList& args, ui return applet; } +QRectF Containment::geometryForApplet(Applet *applet) const +{ + // first try the top left of the containment + QRectF placement = QRectF(geometry().topLeft(), applet->sizeHint()); + if (regionIsEmpty(placement, applet)) { + return placement; + } + + QList otherApplets = d->applets; + otherApplets.removeAll(applet); + + // Then below existing applets + foreach (Applet *otherApplet, otherApplets) { + placement.moveTo(otherApplet->pos() + QPointF(0, otherApplet->size().height())); + if (!geometry().contains(placement)) { + continue; + } + if (regionIsEmpty(placement, applet)) { + return placement; + } + } + + // Then to the right + foreach (Applet *otherApplet, otherApplets) { + placement.moveTo(otherApplet->pos() + QPointF(otherApplet->size().width(), 0)); + if (!geometry().contains(placement)) { + continue; + } + if (regionIsEmpty(placement, applet)) { + return placement; + } + } + + // Otherwise place it in the centre of the screen + placement.moveLeft(geometry().width() / 2 + placement.width() / 2); + placement.moveTop(geometry().height() / 2 + placement.height() / 2); + return placement; +} + +bool Containment::regionIsEmpty(const QRectF ®ion, Applet *ignoredApplet) const +{ + foreach (Applet *applet, d->applets) { + if (applet != ignoredApplet && applet->geometry().intersects(region)) { + return false; + } + } + return true; +} + void Containment::addApplet(Applet *applet) { Containment *currentContainment = applet->containment(); diff --git a/containment.h b/containment.h index 714ceb13b..86a0f0958 100644 --- a/containment.h +++ b/containment.h @@ -314,6 +314,9 @@ class PLASMA_EXPORT Containment : public Applet void destroyApplet(); private: + QRectF geometryForApplet(Applet *applet) const; + bool regionIsEmpty(const QRectF ®ion, Applet *ignoredApplet=0) const; + Q_DISABLE_COPY(Containment) class Private;