ok, this is a much, much easier way to approach the grouping and doesn't require QDesktopWidget either
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=873703
This commit is contained in:
parent
8005bf4a73
commit
b31b4da0ba
115
containment.cpp
115
containment.cpp
@ -59,6 +59,7 @@
|
|||||||
namespace Plasma
|
namespace Plasma
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool ContainmentPrivate::s_positioning = false;
|
||||||
static const char defaultWallpaper[] = "image";
|
static const char defaultWallpaper[] = "image";
|
||||||
static const char defaultWallpaperMode[] = "SingleImage";
|
static const char defaultWallpaperMode[] = "SingleImage";
|
||||||
|
|
||||||
@ -1086,7 +1087,7 @@ QVariant Containment::itemChange(GraphicsItemChange change, const QVariant &valu
|
|||||||
|
|
||||||
if (isContainment() &&
|
if (isContainment() &&
|
||||||
(change == QGraphicsItem::ItemSceneHasChanged ||
|
(change == QGraphicsItem::ItemSceneHasChanged ||
|
||||||
change == QGraphicsItem::ItemPositionHasChanged) && !d->positioning) {
|
change == QGraphicsItem::ItemPositionHasChanged) && !ContainmentPrivate::s_positioning) {
|
||||||
switch (containmentType()) {
|
switch (containmentType()) {
|
||||||
case PanelContainment:
|
case PanelContainment:
|
||||||
case CustomPanelContainment:
|
case CustomPanelContainment:
|
||||||
@ -1609,7 +1610,7 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constraints & Plasma::SizeConstraint) {
|
if (constraints & Plasma::SizeConstraint && !ContainmentPrivate::s_positioning) {
|
||||||
switch (q->containmentType()) {
|
switch (q->containmentType()) {
|
||||||
case Containment::PanelContainment:
|
case Containment::PanelContainment:
|
||||||
case Containment::CustomPanelContainment:
|
case Containment::CustomPanelContainment:
|
||||||
@ -1708,6 +1709,11 @@ void ContainmentPrivate::containmentAppletAnimationComplete(QGraphicsItem *item,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool containmentSortByPosition(const Containment *c1, const Containment *c2)
|
||||||
|
{
|
||||||
|
return c1->id() < c2->id();
|
||||||
|
}
|
||||||
|
|
||||||
void ContainmentPrivate::positionContainment()
|
void ContainmentPrivate::positionContainment()
|
||||||
{
|
{
|
||||||
Corona *c = q->corona();
|
Corona *c = q->corona();
|
||||||
@ -1715,102 +1721,63 @@ void ContainmentPrivate::positionContainment()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: we should avoid running this too often; consider compressing requests
|
||||||
|
// with a timer.
|
||||||
QList<Containment*> containments = c->containments();
|
QList<Containment*> containments = c->containments();
|
||||||
QMutableListIterator<Containment*> it(containments);
|
QMutableListIterator<Containment*> it(containments);
|
||||||
|
|
||||||
bool noCollissions = true;
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Containment *containment = it.next();
|
Containment *containment = it.next();
|
||||||
if (containment == q ||
|
if (containment->containmentType() == Containment::PanelContainment ||
|
||||||
containment->containmentType() == Containment::PanelContainment ||
|
|
||||||
containment->containmentType() == Containment::CustomPanelContainment) {
|
containment->containmentType() == Containment::CustomPanelContainment) {
|
||||||
// weed out all containments we don't care about at all
|
// weed out all containments we don't care about at all
|
||||||
// e.g. Panels and ourself
|
// e.g. Panels and ourself
|
||||||
it.remove();
|
it.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noCollissions && q->collidesWithItem(containment)) {
|
|
||||||
noCollissions = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noCollissions) {
|
if (containments.isEmpty()) {
|
||||||
// we made it all the way through the list, we have no
|
|
||||||
// collisions
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = 0;
|
qSort(containments.begin(), containments.end(), containmentSortByPosition);
|
||||||
int height = 0;
|
it.toFront();
|
||||||
|
|
||||||
QDesktopWidget *desktop = QApplication::desktop();
|
int column = 0;
|
||||||
int numScreens = desktop->numScreens();
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int rowHeight = 0;
|
||||||
|
//int count = 0;
|
||||||
|
ContainmentPrivate::s_positioning = true;
|
||||||
|
|
||||||
for (int i = 0; i < numScreens; ++i) {
|
//kDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++" << containments.count();
|
||||||
QRect otherScreen = desktop->screenGeometry(i);
|
while (it.hasNext()) {
|
||||||
|
Containment *containment = it.next();
|
||||||
|
containment->setPos(x, y);
|
||||||
|
//kDebug() << ++count << "setting to" << x << y;
|
||||||
|
|
||||||
if (width < otherScreen.width()) {
|
int height = containment->size().height();
|
||||||
width = otherScreen.width();
|
if (height > rowHeight) {
|
||||||
|
rowHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height < otherScreen.height()) {
|
++column;
|
||||||
height = otherScreen.height();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
width = (width + INTER_CONTAINMENT_MARGIN) * CONTAINMENT_COLUMNS;
|
if (column == CONTAINMENT_COLUMNS) {
|
||||||
height += INTER_CONTAINMENT_MARGIN;
|
column = 0;
|
||||||
|
x = 0;
|
||||||
// a mildly naive "find the first slot" approach
|
y += rowHeight + INTER_CONTAINMENT_MARGIN;
|
||||||
QRectF r = q->boundingRect();
|
rowHeight = 0;
|
||||||
QPointF topLeft(0, 0);
|
|
||||||
q->setPos(topLeft);
|
|
||||||
|
|
||||||
positioning = true;
|
|
||||||
while (true) {
|
|
||||||
it.toFront();
|
|
||||||
int shift = 0;
|
|
||||||
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Containment *containment = it.next();
|
|
||||||
|
|
||||||
if (q->collidesWithItem(containment)) {
|
|
||||||
shift = containment->geometry().right();
|
|
||||||
/*kDebug() << (QObject*)q << "collides with" << (QObject*)containment
|
|
||||||
<< containment->geometry() << "so shift to: " << shift;*/
|
|
||||||
//TODO: is it safe to remove a containment once we've
|
|
||||||
// collided with it?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF pos = containment->pos();
|
|
||||||
if (pos.x() <= topLeft.x() && pos.y() <= topLeft.y()) {
|
|
||||||
// we don't colid with this containment, and it's above
|
|
||||||
// and to the left of us, so let's not bother checking
|
|
||||||
// it again if we go through this loop again
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shift == 0) {
|
|
||||||
// success! no collisions!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shift + r.width() + INTER_CONTAINMENT_MARGIN > width) {
|
|
||||||
// we ran out of width room, try another row
|
|
||||||
topLeft = QPoint(0, topLeft.y() + height);
|
|
||||||
} else {
|
} else {
|
||||||
topLeft.setX(shift + INTER_CONTAINMENT_MARGIN);
|
x += containment->size().width() + INTER_CONTAINMENT_MARGIN;
|
||||||
}
|
}
|
||||||
|
//kDebug() << "column: " << column << "; x " << x << "; y" << y << "; width was"
|
||||||
q->setPos(topLeft);
|
// << containment->size().width();
|
||||||
//kDebug() << "trying at" << topLeft << q->geometry();
|
|
||||||
//kDebug() << collidingItems().count() << collidingItems()[0] << (QGraphicsItem*)this;
|
|
||||||
}
|
}
|
||||||
|
//kDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++";
|
||||||
|
|
||||||
positioning = false;
|
ContainmentPrivate::s_positioning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContainmentPrivate::positionPanel(bool force)
|
void ContainmentPrivate::positionPanel(bool force)
|
||||||
@ -1881,12 +1848,12 @@ void ContainmentPrivate::positionPanel(bool force)
|
|||||||
newPos = QPointF(bottom + q->size().width(), -INTER_CONTAINMENT_MARGIN - q->size().height());
|
newPos = QPointF(bottom + q->size().width(), -INTER_CONTAINMENT_MARGIN - q->size().height());
|
||||||
}
|
}
|
||||||
|
|
||||||
positioning = true;
|
ContainmentPrivate::s_positioning = true;
|
||||||
if (p != newPos) {
|
if (p != newPos) {
|
||||||
q->setPos(newPos);
|
q->setPos(newPos);
|
||||||
emit q->geometryChanged();
|
emit q->geometryChanged();
|
||||||
}
|
}
|
||||||
positioning = false;
|
ContainmentPrivate::s_positioning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Plasma namespace
|
} // Plasma namespace
|
||||||
|
@ -44,7 +44,6 @@ public:
|
|||||||
toolBox(0),
|
toolBox(0),
|
||||||
con(0),
|
con(0),
|
||||||
type(Containment::NoContainmentType),
|
type(Containment::NoContainmentType),
|
||||||
positioning(false),
|
|
||||||
drawWallpaper(true)
|
drawWallpaper(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -111,7 +110,7 @@ public:
|
|||||||
ToolBox *toolBox;
|
ToolBox *toolBox;
|
||||||
Context *con;
|
Context *con;
|
||||||
Containment::Type type;
|
Containment::Type type;
|
||||||
bool positioning;
|
static bool s_positioning;
|
||||||
bool drawWallpaper;
|
bool drawWallpaper;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user