No longer use a QGraphicsGridLayout to manage offscreen widgets in corona. Instead position them manually and give each one a spot where they can grow up to QWIDGETSIZEMAX. This has the advantage of not requiring hacks to work around QGL problems, and it avoids having to move all views when one item resizes. It feels snappier and the code looks cleaner.
svn path=/trunk/KDE/kdelibs/; revision=895118
This commit is contained in:
parent
a6140d5a27
commit
72eaf8c5f7
87
corona.cpp
87
corona.cpp
@ -55,8 +55,7 @@ public:
|
||||
: q(corona),
|
||||
immutability(Mutable),
|
||||
mimetype("text/x-plasmoidservicename"),
|
||||
config(0),
|
||||
offscreenLayout(0)
|
||||
config(0)
|
||||
{
|
||||
if (KGlobal::hasMainComponent()) {
|
||||
configName = KGlobal::mainComponent().componentName() + "-appletsrc";
|
||||
@ -189,7 +188,7 @@ public:
|
||||
KSharedConfigPtr config;
|
||||
QTimer configSyncTimer;
|
||||
QList<Containment*> containments;
|
||||
QGraphicsGridLayout *offscreenLayout;
|
||||
QHash<uint, QGraphicsWidget*> offscreenWidgets;
|
||||
};
|
||||
|
||||
Corona::Corona(QObject *parent)
|
||||
@ -368,73 +367,47 @@ Containment *Corona::addContainmentDelayed(const QString &name, const QVariantLi
|
||||
|
||||
void Corona::addOffscreenWidget(QGraphicsWidget *widget)
|
||||
{
|
||||
widget->setParentItem(0);
|
||||
if (!d->offscreenLayout) {
|
||||
kDebug() << "adding offscreen widget.";
|
||||
QGraphicsWidget *offscreenWidget = new QGraphicsWidget(0);
|
||||
addItem(offscreenWidget);
|
||||
d->offscreenLayout = new QGraphicsGridLayout(offscreenWidget);
|
||||
//FIXME: do this a nice way.
|
||||
offscreenWidget->setPos(-10000, -10000);
|
||||
offscreenWidget->setLayout(d->offscreenLayout);
|
||||
}
|
||||
|
||||
//check if the layout already contains this widget.
|
||||
//XXX: duplicated from removeOffscreenWidget()
|
||||
for (int i = 0; i < d->offscreenLayout->count(); i++) {
|
||||
QGraphicsWidget *foundWidget = dynamic_cast<QGraphicsWidget*>(d->offscreenLayout->itemAt(i));
|
||||
if (foundWidget == widget) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
d->offscreenLayout->addItem(widget, d->offscreenLayout->rowCount() + 1,
|
||||
d->offscreenLayout->columnCount() + 1);
|
||||
// this is lame: adding a widget to a layout and then deleting it
|
||||
// doesn't automatically remove it from the layout, so we have to watch for that ourselves
|
||||
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(offscreenWidgetDestroyed(QObject*)));
|
||||
widget->update();
|
||||
}
|
||||
|
||||
//FIXME: remove the offscreenWidgetDestroyed method when QGraphicsLayout no longer
|
||||
// craps up when an item in the layout is deleted!
|
||||
void CoronaPrivate::offscreenWidgetDestroyed(QObject *o)
|
||||
{
|
||||
if (!offscreenLayout) {
|
||||
if (d->offscreenWidgets.values().contains(widget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// at this point, it's just a QObject, not a QGraphicsWidget, but we still need
|
||||
// a pointer of the appropriate type.
|
||||
// WARNING: DO NOT USE THE WIDGET POINTER FOR ANYTHING OTHER THAN POINTER COMPARISONS
|
||||
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(o);
|
||||
for (int i = 0; i < offscreenLayout->count(); i++) {
|
||||
// we have to static_cast here as well, even though that's not overly correct
|
||||
// or wonderful; but it's the best we can do as the item is no longer a
|
||||
// QGraphicsWidget at this point, just a QObject
|
||||
QGraphicsWidget *foundWidget = static_cast<QGraphicsWidget *>(offscreenLayout->itemAt(i));
|
||||
if (foundWidget == widget) {
|
||||
offscreenLayout->removeAt(i);
|
||||
}
|
||||
widget->setParentItem(0);
|
||||
|
||||
//search for an empty spot in the topleft quadrant of the scene. each 'slot' is QWIDGETSIZE_MAX
|
||||
//x QWIDGETSIZE_MAX, so we're guaranteed to never have to move widgets once they're placed here.
|
||||
int i = 0;
|
||||
while (d->offscreenWidgets.contains(i)) {
|
||||
i++;
|
||||
}
|
||||
|
||||
d->offscreenWidgets[i] = widget;
|
||||
widget->setPos((-i - 1) * QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
|
||||
kDebug() << "adding offscreen widget at slot " << i;
|
||||
|
||||
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(offscreenWidgetDestroyed(QObject*)));
|
||||
}
|
||||
|
||||
void Corona::removeOffscreenWidget(QGraphicsWidget *widget)
|
||||
{
|
||||
if (!d->offscreenLayout) {
|
||||
return;
|
||||
}
|
||||
QMutableHashIterator<uint, QGraphicsWidget *> it(d->offscreenWidgets);
|
||||
|
||||
for (int i = 0; i < d->offscreenLayout->count(); i++) {
|
||||
QGraphicsWidget *foundWidget = dynamic_cast<QGraphicsWidget*>(d->offscreenLayout->itemAt(i));
|
||||
if (foundWidget == widget) {
|
||||
d->offscreenLayout->removeAt(i);
|
||||
disconnect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(offscreenWidgetDestroyed(QObject*)));
|
||||
break;
|
||||
while (it.hasNext()) {
|
||||
if (it.next().value() == widget) {
|
||||
it.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CoronaPrivate::offscreenWidgetDestroyed(QObject *o)
|
||||
{
|
||||
// at this point, it's just a QObject, not a QGraphicsWidget, but we still need
|
||||
// a pointer of the appropriate type.
|
||||
// WARNING: DO NOT USE THE WIDGET POINTER FOR ANYTHING OTHER THAN POINTER COMPARISONS
|
||||
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(o);
|
||||
q->removeOffscreenWidget(widget);
|
||||
}
|
||||
|
||||
int Corona::numScreens() const
|
||||
{
|
||||
return 1;
|
||||
|
@ -486,6 +486,8 @@ void ExtenderPrivate::adjustSizeHints()
|
||||
applet->adjustSize();
|
||||
}
|
||||
|
||||
q->adjustSize();
|
||||
|
||||
emit q->geometryChanged();
|
||||
}
|
||||
|
||||
|
@ -488,42 +488,17 @@ void ExtenderItem::moveEvent(QGraphicsSceneMoveEvent *event)
|
||||
|
||||
if (d->toplevel) {
|
||||
d->toplevel->setSceneRect(sceneBoundingRect());
|
||||
update();
|
||||
d->toplevel->setMask(d->background->mask());
|
||||
}
|
||||
}
|
||||
|
||||
void ExtenderItem::resizeEvent(QGraphicsSceneResizeEvent *event)
|
||||
{
|
||||
qreal width = event->newSize().width();
|
||||
qreal height = event->newSize().height();
|
||||
|
||||
//resize the dragger
|
||||
d->dragger->resizeFrame(QSizeF(width - d->bgLeft - d->bgRight,
|
||||
d->iconSize() +
|
||||
d->dragTop + d->dragBottom));
|
||||
|
||||
//resize the applet background
|
||||
d->background->resizeFrame(event->newSize());
|
||||
|
||||
//resize the widget
|
||||
if (d->widget && d->widget->isWidget()) {
|
||||
QSizeF newWidgetSize(width - d->bgLeft - d->bgRight - d->dragLeft - d->dragRight,
|
||||
height - d->dragHandleRect().height() - d->bgTop - d->bgBottom -
|
||||
2 * d->dragTop - 2 * d->dragBottom);
|
||||
|
||||
QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(d->widget);
|
||||
graphicsWidget->resize(newWidgetSize);
|
||||
}
|
||||
|
||||
//reposition the toolbox.
|
||||
d->repositionToolbox();
|
||||
|
||||
update();
|
||||
d->resizeContent(event->newSize());
|
||||
|
||||
if (d->toplevel) {
|
||||
d->toplevel->setSceneRect(sceneBoundingRect());
|
||||
d->toplevel->setMask(d->background->mask());
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,8 +518,8 @@ void ExtenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!d->dragStarted && (d->mousePos - event->pos().toPoint()).manhattanLength()
|
||||
>= QApplication::startDragDistance()) {
|
||||
if (d->mousePressed && !d->dragStarted &&
|
||||
(d->mousePos - event->pos().toPoint()).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
//start the drag:
|
||||
d->dragStarted = true;
|
||||
|
||||
@ -588,26 +563,20 @@ void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
d->toplevel->setWindowFlags(
|
||||
Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
||||
d->toplevel->setFrameShape(QFrame::NoFrame);
|
||||
d->toplevel->resize(screenRect.size());
|
||||
d->toplevel->setSceneRect(sceneBoundingRect());
|
||||
d->toplevel->centerOn(this);
|
||||
|
||||
//We might have to scale the view, because we might be zoomed out.
|
||||
qreal scale = screenRect.width() / size().width();
|
||||
d->toplevel->scale(scale, scale);
|
||||
|
||||
d->toplevel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
d->toplevel->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
d->toplevel->setFrameShape(QFrame::NoFrame);
|
||||
|
||||
d->toplevel->setSceneRect(sceneBoundingRect());
|
||||
d->toplevel->setGeometry(screenRect);
|
||||
d->toplevel->setMask(d->background->mask());
|
||||
|
||||
d->toplevel->update();
|
||||
d->toplevel->show();
|
||||
}
|
||||
|
||||
d->toplevel->setSceneRect(sceneBoundingRect());
|
||||
d->toplevel->setGeometry(screenRect);
|
||||
d->toplevel->setMask(d->background->mask());
|
||||
} else {
|
||||
corona->removeOffscreenWidget(this);
|
||||
setParentItem(d->hostApplet());
|
||||
@ -1032,7 +1001,7 @@ void ExtenderItemPrivate::themeChanged()
|
||||
//setCollapsed recalculates size hints.
|
||||
q->setCollapsed(q->isCollapsed());
|
||||
|
||||
q->update();
|
||||
resizeContent(q->size());
|
||||
}
|
||||
|
||||
void ExtenderItemPrivate::sourceAppletRemoved()
|
||||
@ -1057,6 +1026,34 @@ qreal ExtenderItemPrivate::iconSize()
|
||||
return qMax(size.height(), (qreal) fm.height());
|
||||
}
|
||||
|
||||
void ExtenderItemPrivate::resizeContent(const QSizeF &newSize)
|
||||
{
|
||||
qreal width = newSize.width();
|
||||
qreal height = newSize.height();
|
||||
|
||||
//resize the dragger
|
||||
dragger->resizeFrame(QSizeF(width - bgLeft - bgRight,
|
||||
iconSize() + dragTop + dragBottom));
|
||||
|
||||
//resize the applet background
|
||||
background->resizeFrame(newSize);
|
||||
|
||||
//resize the widget
|
||||
if (widget && widget->isWidget()) {
|
||||
QSizeF newWidgetSize(width - bgLeft - bgRight - dragLeft - dragRight,
|
||||
height - dragHandleRect().height() - bgTop - bgBottom -
|
||||
2 * dragTop - 2 * dragBottom);
|
||||
|
||||
QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(widget);
|
||||
graphicsWidget->resize(newWidgetSize);
|
||||
}
|
||||
|
||||
//reposition the toolbox.
|
||||
repositionToolbox();
|
||||
|
||||
q->update();
|
||||
}
|
||||
|
||||
uint ExtenderItemPrivate::s_maxExtenderItemId = 0;
|
||||
|
||||
} // namespace Plasma
|
||||
|
@ -289,15 +289,6 @@ void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
|
||||
//could that cast ever fail??
|
||||
if (corona) {
|
||||
corona->addOffscreenWidget(gWidget);
|
||||
|
||||
//necessary to mess around with the offscreen widget
|
||||
QGraphicsLayoutItem *layout = gWidget->parentLayoutItem();
|
||||
QGraphicsWidget *parentWidget = gWidget->parentWidget();
|
||||
|
||||
if (layout && parentWidget) {
|
||||
layout->updateGeometry();
|
||||
parentWidget->resize(layout->preferredSize());
|
||||
}
|
||||
dialog->setGraphicsWidget(gWidget);
|
||||
}
|
||||
} else if (qWidget) {
|
||||
|
@ -57,6 +57,7 @@ class ExtenderItemPrivate
|
||||
void themeChanged();
|
||||
void sourceAppletRemoved();
|
||||
qreal iconSize();
|
||||
void resizeContent(const QSizeF &newSize);
|
||||
|
||||
ExtenderItem *q;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user