mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 19:32:54 +00:00
658 lines
23 KiB
C++
658 lines
23 KiB
C++
/*
|
|
* Copyright 2009-2010 by Giulio Camuffo <giuliocamuffo@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License as
|
|
* published by the Free Software Foundation; either version 2, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "gridgroup.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <qmath.h>
|
|
#include <QtGui/QPainter>
|
|
#include <QtGui/QGraphicsSceneResizeEvent>
|
|
#include <QtGui/QGraphicsSceneHoverEvent>
|
|
#include <QtGui/QGraphicsLinearLayout>
|
|
#include <QtGui/QStyleOptionGraphicsItem>
|
|
|
|
#include <KIcon>
|
|
|
|
#include <Plasma/Theme>
|
|
#include <Plasma/PaintUtils>
|
|
#include <Plasma/ToolButton>
|
|
#include <Plasma/Animator>
|
|
#include <Plasma/Animation>
|
|
|
|
#include "spacer.h"
|
|
#include "gridmanager.h"
|
|
|
|
REGISTER_GROUP(GridGroup)
|
|
|
|
static const int CORNERHANDLE_WIDTH = 20;
|
|
static const int CORNERHANDLE_HEIGHT = 20;
|
|
|
|
GridGroup::GridGroup(QGraphicsItem *parent, Qt::WindowFlags wFlags)
|
|
: AbstractGroup(parent, wFlags),
|
|
m_showGrid(false),
|
|
m_gridManager(new GridManager(this))
|
|
{
|
|
resize(200,200);
|
|
setGroupType(AbstractGroup::ConstrainedGroup);
|
|
|
|
m_gridManager->hide();
|
|
connect(m_gridManager, SIGNAL(newClicked()), this, SLOT(addNewRowOrColumn()));
|
|
connect(m_gridManager, SIGNAL(deleteClicked()), this, SLOT(removeRowOrColumn()));
|
|
|
|
connect(this, SIGNAL(appletRemovedFromGroup(Plasma::Applet*,AbstractGroup*)),
|
|
this, SLOT(appletRemoved(Plasma::Applet*)));
|
|
connect(this, SIGNAL(subGroupRemovedFromGroup(AbstractGroup*,AbstractGroup*)),
|
|
this, SLOT(subGroupRemoved(AbstractGroup*)));
|
|
}
|
|
|
|
GridGroup::~GridGroup()
|
|
{
|
|
|
|
}
|
|
|
|
void GridGroup::init()
|
|
{
|
|
KConfigGroup cg = config();
|
|
m_rowsNumber = cg.readEntry("RowsNumber", 0);
|
|
m_colsNumber = cg.readEntry("ColsNumber", 0);
|
|
|
|
if (m_rowsNumber == 0) {
|
|
m_rowsNumber = contentsRect().height() / 50;
|
|
|
|
cg.writeEntry("RowsNumber", m_rowsNumber);
|
|
}
|
|
if (m_colsNumber == 0) {
|
|
m_colsNumber = contentsRect().width() / 50;
|
|
|
|
cg.writeEntry("ColsNumber", m_colsNumber);
|
|
}
|
|
}
|
|
|
|
bool GridGroup::showDropZone(const QPointF &pos)
|
|
{
|
|
bool showGrid = !pos.isNull();
|
|
if (showGrid != m_showGrid) {
|
|
m_showGrid = showGrid;
|
|
update();
|
|
}
|
|
|
|
return m_showGrid;
|
|
}
|
|
|
|
QString GridGroup::pluginName() const
|
|
{
|
|
return QString("grid");
|
|
}
|
|
|
|
void GridGroup::restoreChildGroupInfo(QGraphicsWidget *child, const KConfigGroup &group)
|
|
{
|
|
QRect rect(group.readEntry("Geometry", QRect()));
|
|
QRectF cRect(contentsRect());
|
|
const qreal width = cRect.width() / m_colsNumber;
|
|
const qreal height = cRect.height() / m_rowsNumber;
|
|
m_childrenRects.insert(child, rect);
|
|
child->setPos(rect.x() * width + cRect.x(), rect.y() * height + cRect.y());
|
|
child->resize(rect.width() * width, rect.height() * height);
|
|
|
|
child->installEventFilter(this);
|
|
}
|
|
|
|
void GridGroup::saveChildGroupInfo(QGraphicsWidget *child, KConfigGroup group) const
|
|
{
|
|
group.writeEntry("Geometry", m_childrenRects.value(child));
|
|
}
|
|
|
|
void GridGroup::addNewRowOrColumn()
|
|
{
|
|
KConfigGroup cg = config();
|
|
Plasma::Location location = m_gridManager->location();
|
|
bool left = location == Plasma::LeftEdge;
|
|
if (left || location == Plasma::RightEdge) {
|
|
++m_colsNumber;
|
|
cg.writeEntry("ColsNumber", m_colsNumber);
|
|
if (left) { //must move all the children one column right
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRect r(m_childrenRects.value(child));
|
|
r.translate(1, 0);
|
|
m_childrenRects.insert(child, r);
|
|
}
|
|
}
|
|
} else {
|
|
++m_rowsNumber;
|
|
cg.writeEntry("RowsNumber", m_rowsNumber);
|
|
if (location == Plasma::TopEdge) { //must move all the children one row down
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRect r(m_childrenRects.value(child));
|
|
r.translate(0, 1);
|
|
m_childrenRects.insert(child, r);
|
|
}
|
|
}
|
|
}
|
|
saveChildren();
|
|
emit configNeedsSaving();
|
|
|
|
updateGeometries();
|
|
}
|
|
|
|
void GridGroup::removeRowOrColumn()
|
|
{
|
|
KConfigGroup cg = config();
|
|
Plasma::Location location = m_gridManager->location();
|
|
bool left = location == Plasma::LeftEdge;
|
|
if (left || location == Plasma::RightEdge) {
|
|
//check we don't remove columns with children in it
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRect rect = m_childrenRects.value(child);
|
|
QPoint p;
|
|
if (left) {
|
|
p = QPoint(0, rect.y());
|
|
} else {
|
|
p = QPoint(m_colsNumber - 1, rect.y());
|
|
}
|
|
if (rect.contains(p)) {
|
|
return;
|
|
}
|
|
}
|
|
m_colsNumber = (m_colsNumber > 1 ? m_colsNumber - 1 : 1);
|
|
cg.writeEntry("ColsNumber", m_colsNumber);
|
|
if (left) { //must move all the children one column left
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRect r(m_childrenRects.value(child));
|
|
r.translate(-1, 0);
|
|
m_childrenRects.insert(child, r);
|
|
}
|
|
}
|
|
} else {
|
|
//check we don't remove rows with children in it
|
|
bool top = location == Plasma::TopEdge;
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRectF rect = m_childrenRects.value(child);
|
|
QPoint p;
|
|
if (top) {
|
|
p = QPoint(rect.x(), 0);
|
|
} else {
|
|
p = QPoint(rect.x(), m_rowsNumber);
|
|
}
|
|
if (rect.contains(p)) {
|
|
return;
|
|
}
|
|
}
|
|
m_rowsNumber = (m_rowsNumber > 1 ? m_rowsNumber - 1 : 1);
|
|
cg.writeEntry("RowsNumber", m_rowsNumber);
|
|
if (top) { //must move all the children one row up
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRect r(m_childrenRects.value(child));
|
|
r.translate(0, -1);
|
|
m_childrenRects.insert(child, r);
|
|
}
|
|
}
|
|
}
|
|
saveChildren();
|
|
emit configNeedsSaving();
|
|
|
|
updateGeometries();
|
|
}
|
|
|
|
void GridGroup::appletRemoved(Plasma::Applet *)
|
|
{
|
|
if (m_cornerHandle && m_cornerHandle.data()->isVisible()) {
|
|
m_cornerHandle.data()->hide();
|
|
m_cornerHandle.data()->setParentItem(this);
|
|
}
|
|
}
|
|
|
|
void GridGroup::subGroupRemoved(AbstractGroup *)
|
|
{
|
|
appletRemoved(0);
|
|
}
|
|
|
|
void GridGroup::updateChild(QGraphicsWidget *child)
|
|
{
|
|
QPointF pos(child->pos());
|
|
QRectF rect(contentsRect());
|
|
QRectF geom(child->geometry());
|
|
|
|
const qreal width = rect.width() / m_colsNumber;
|
|
const qreal height = rect.height() / m_rowsNumber;
|
|
int i = qRound(pos.x() / width);
|
|
int j = qRound(pos.y() / height);
|
|
int cols = qRound(geom.width() / width);
|
|
int rows = qRound(geom.height() / height);
|
|
QSizeF minSize(child->effectiveSizeHint(Qt::MinimumSize));
|
|
while (cols * width < minSize.width()) {
|
|
++cols;
|
|
}
|
|
while (rows * height < minSize.height()) {
|
|
++rows;
|
|
}
|
|
rows = (rows > 0 ? rows : 1);
|
|
cols = (cols > 0 ? cols : 1);
|
|
|
|
i = (i < 0 ? 0 : i);
|
|
j = (j < 0 ? 0 : j);
|
|
QGraphicsWidget *w = childAt(i, j);
|
|
//find the nearest hole in which the child can be put
|
|
if (w && w != child) {
|
|
bool done = false;
|
|
int ray = 1;
|
|
bool firstPhase = true;
|
|
while (!done && (ray < m_colsNumber || ray < m_rowsNumber)) {
|
|
for (int k = ray; k > -ray; --k) {
|
|
int col = k + i;
|
|
int row = (k >= 0 ? ray - k : ray + k) + j;
|
|
if (firstPhase) {
|
|
qreal dist = qSqrt((col - i) * (col - i) + (row - j) * (row - j));
|
|
if (dist == ray) {
|
|
continue;
|
|
}
|
|
}
|
|
if (col >= 0 && row >= 0 && col < m_colsNumber && row < m_rowsNumber) {
|
|
QGraphicsWidget *c = childAt(col, row);
|
|
if (!c || c == child) {
|
|
i = col;
|
|
j = row;
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!done) {
|
|
for (int k = -ray; k < ray; ++k) {
|
|
int col = k + i;
|
|
int row = (k >= 0 ? -ray + k : -ray - k) + j;
|
|
if (firstPhase) {
|
|
qreal dist = qSqrt((col - i) * (col - i) + (row - j) * (row - j));
|
|
if (dist == ray) {
|
|
continue;
|
|
}
|
|
}
|
|
if (col >= 0 && row >= 0 && col < m_colsNumber && row < m_rowsNumber) {
|
|
QGraphicsWidget *c = childAt(col, row);
|
|
if (!c || c == child) {
|
|
i = col;
|
|
j = row;
|
|
done = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!firstPhase) {
|
|
++ray;
|
|
}
|
|
firstPhase = !firstPhase;
|
|
}
|
|
|
|
if (!done) { //couldn't find an empty cell
|
|
w->hide(); //FIXME: do something, maybe should destroy it?
|
|
}
|
|
}
|
|
|
|
int colsNumber = m_colsNumber;
|
|
for (int col = i + 1; col < m_colsNumber; ++col) {
|
|
bool occupied = false;
|
|
for (int row = j; row < j + rows; ++row) {
|
|
QGraphicsWidget *c = childAt(col, row);
|
|
if (c && c != child) {
|
|
occupied = true;
|
|
break;
|
|
}
|
|
}
|
|
if (occupied) {
|
|
colsNumber = col;
|
|
break;
|
|
}
|
|
}
|
|
if (i + cols > colsNumber) {
|
|
cols = colsNumber - i;
|
|
}
|
|
|
|
int rowsNumber = m_rowsNumber;
|
|
for (int row = j + 1; row < m_rowsNumber; ++row) {
|
|
bool occupied = false;
|
|
for (int col = i; col < i + cols; ++col) {
|
|
QGraphicsWidget *c = childAt(col, row);
|
|
if (c && c != child) {
|
|
occupied = true;
|
|
break;
|
|
}
|
|
}
|
|
if (occupied) {
|
|
rowsNumber = row;
|
|
break;
|
|
}
|
|
}
|
|
if (j + rows > rowsNumber) {
|
|
rows = rowsNumber - j;
|
|
}
|
|
|
|
m_childrenRects.insert(child, QRect(i, j, cols, rows));
|
|
child->setGeometry(QRectF(i * width + rect.x(), j * height + rect.y(),
|
|
width * cols, height * rows));
|
|
}
|
|
|
|
QGraphicsWidget *GridGroup::childAt(int column, int row)
|
|
{
|
|
foreach (QGraphicsWidget *c, children()) {
|
|
QRectF rect = m_childrenRects.value(c);
|
|
if (rect.contains(column, row) && column < rect.right() && row < rect.bottom()) {
|
|
return c;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void GridGroup::updateGeometries()
|
|
{
|
|
QRectF rect(contentsRect());
|
|
const qreal width = rect.width() / m_colsNumber;
|
|
const qreal height = rect.height() / m_rowsNumber;
|
|
foreach (QGraphicsWidget *child, children()) {
|
|
QRectF r(m_childrenRects.value(child));
|
|
child->setPos(r.x() * width + rect.x(), r.y() * height + rect.y());
|
|
child->resize(r.width() * width, r.height() * height);
|
|
}
|
|
}
|
|
|
|
void GridGroup::layoutChild(QGraphicsWidget *child, const QPointF &)
|
|
{
|
|
updateChild(child);
|
|
|
|
child->installEventFilter(this);
|
|
|
|
m_showGrid = false;
|
|
update();
|
|
}
|
|
|
|
void GridGroup::resizeEvent(QGraphicsSceneResizeEvent *event)
|
|
{
|
|
AbstractGroup::resizeEvent(event);
|
|
|
|
m_gridManager->hideAnimated();
|
|
updateGeometries();
|
|
}
|
|
|
|
void GridGroup::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
|
{
|
|
if (immutability() == Plasma::Mutable) {
|
|
m_gridManager->checkLocation(event->pos());
|
|
}
|
|
}
|
|
|
|
void GridGroup::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
|
|
{
|
|
m_gridManager->hideAnimated();
|
|
if (m_cornerHandle) {
|
|
m_cornerHandle.data()->hide();
|
|
}
|
|
}
|
|
|
|
void GridGroup::checkCorner(const QPointF &pos, QGraphicsWidget *widget)
|
|
{
|
|
const QRectF rect(widget->contentsRect());
|
|
QRectF topLeft(rect.left() - CORNERHANDLE_WIDTH / 2., rect.top() - CORNERHANDLE_HEIGHT / 2.,
|
|
CORNERHANDLE_WIDTH, CORNERHANDLE_HEIGHT);
|
|
QRectF topRight(rect.right() - CORNERHANDLE_WIDTH / 2., rect.top() - CORNERHANDLE_HEIGHT / 2.,
|
|
CORNERHANDLE_WIDTH, CORNERHANDLE_HEIGHT);
|
|
QRectF bottomRight(rect.right() - CORNERHANDLE_WIDTH / 2., rect.bottom() - CORNERHANDLE_HEIGHT / 2.,
|
|
CORNERHANDLE_WIDTH, CORNERHANDLE_HEIGHT);
|
|
QRectF bottomLeft(rect.left() - CORNERHANDLE_WIDTH / 2., rect.bottom() - CORNERHANDLE_HEIGHT / 2.,
|
|
CORNERHANDLE_WIDTH, CORNERHANDLE_HEIGHT);
|
|
|
|
//it would be better to check if pos is inside one of those rects above, but that way
|
|
//the corner handle wouldn't show up when hovering the analog clock of other applets with
|
|
//shape != boundingRect because they can be outside its shape.
|
|
const QRectF bRect(widget->boundingRect());
|
|
QRectF activeRect(bRect.topLeft(), bRect.size() / 2.);
|
|
m_cornerHandle.data()->show();
|
|
qreal shiftWidth = bRect.width() / 2.;
|
|
qreal shiftHeight = bRect.height() / 2.;
|
|
if (activeRect.contains(pos)) {
|
|
m_cornerHandle.data()->setGeometry(topLeft);
|
|
m_handleCorner = Qt::TopLeftCorner;
|
|
} else if (activeRect.translated(shiftWidth, 0).contains(pos)) {
|
|
m_cornerHandle.data()->setGeometry(topRight);
|
|
m_handleCorner = Qt::TopRightCorner;
|
|
} else if (activeRect.translated(shiftWidth, shiftHeight).contains(pos)) {
|
|
m_cornerHandle.data()->setGeometry(bottomRight);
|
|
m_handleCorner = Qt::BottomRightCorner;
|
|
} else if (activeRect.translated(0, shiftHeight).contains(pos)) {
|
|
m_cornerHandle.data()->setGeometry(bottomLeft);
|
|
m_handleCorner = Qt::BottomLeftCorner;
|
|
} else {
|
|
m_cornerHandle.data()->setParentItem(this);
|
|
m_cornerHandle.data()->hide();
|
|
}
|
|
}
|
|
|
|
bool GridGroup::eventFilter(QObject *obj, QEvent *event)
|
|
{
|
|
if (immutability() != Plasma::Mutable) {
|
|
return AbstractGroup::eventFilter(obj, event);
|
|
}
|
|
|
|
switch (event->type()) {
|
|
case QEvent::GraphicsSceneHoverEnter:
|
|
case QEvent::GraphicsSceneHoverMove: {
|
|
QGraphicsWidget *widget = qobject_cast<QGraphicsWidget *>(obj);
|
|
QGraphicsSceneHoverEvent *e = static_cast<QGraphicsSceneHoverEvent *>(event);
|
|
if (widget && children().contains(widget)) {
|
|
if (!m_cornerHandle) {
|
|
m_cornerHandle = new Spacer(this);
|
|
m_cornerHandle.data()->hide();
|
|
m_cornerHandle.data()->resize(CORNERHANDLE_WIDTH, CORNERHANDLE_HEIGHT);
|
|
m_cornerHandle.data()->installEventFilter(this);
|
|
}
|
|
m_cornerHandle.data()->setParentItem(widget);
|
|
|
|
checkCorner(e->pos(), widget);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case QEvent::GraphicsSceneHoverLeave:
|
|
if (m_cornerHandle) {
|
|
QGraphicsItem *child = m_cornerHandle.data()->parentItem();
|
|
if (!child->boundingRect().contains(static_cast<QGraphicsSceneHoverEvent *>(event)->pos())) {
|
|
m_cornerHandle.data()->setParentItem(this);
|
|
m_cornerHandle.data()->hide();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case QEvent::GraphicsSceneMousePress:
|
|
if (obj == m_cornerHandle.data()) {
|
|
QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent *>(event);
|
|
if (e->button() == Qt::LeftButton) {
|
|
event->accept();
|
|
m_showGrid = true;
|
|
m_resizeStartPos = mapFromScene(e->scenePos());
|
|
m_resizeStartGeom = m_cornerHandle.data()->parentWidget()->geometry();
|
|
update();
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case QEvent::GraphicsSceneMouseMove:
|
|
if (obj == m_cornerHandle.data()) {
|
|
QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent *>(event);
|
|
QGraphicsWidget *child = m_cornerHandle.data()->parentWidget();
|
|
QRectF geom(m_resizeStartGeom);
|
|
QPointF pos(m_cornerHandle.data()->pos());
|
|
QSizeF size(child->effectiveSizeHint(Qt::MinimumSize));
|
|
const QPointF delta = mapFromScene(e->scenePos()) - m_resizeStartPos;
|
|
switch (m_handleCorner) {
|
|
case Qt::TopLeftCorner: {
|
|
const qreal top = geom.top() + delta.y();
|
|
const qreal left = geom.left() + delta.x();
|
|
geom.setTop(geom.bottom() - top >= size.height() ? top : geom.bottom() - size.height());
|
|
geom.setLeft(geom.right() - left >= size.width() ? left : geom.right() - size.width());
|
|
}
|
|
break;
|
|
case Qt::TopRightCorner: {
|
|
const qreal top = geom.top() + delta.y();
|
|
const qreal right = geom.right() + delta.x();
|
|
geom.setTop(geom.bottom() - top >= size.height() ? top : geom.bottom() - size.height());
|
|
geom.setRight(right - geom.left() >= size.width() ? right : geom.left() + size.width());
|
|
qreal l, t, r, b;
|
|
child->getContentsMargins(&l, &t, &r, &b);
|
|
pos = QPointF(geom.width() - r - CORNERHANDLE_WIDTH / 2., t - CORNERHANDLE_HEIGHT / 2.);
|
|
}
|
|
break;
|
|
case Qt::BottomRightCorner: {
|
|
const qreal bottom = geom.bottom() + delta.y();
|
|
const qreal right = geom.right() + delta.x();
|
|
geom.setBottom(bottom - geom.top() >= size.height() ? bottom : geom.top() + size.height());
|
|
geom.setRight(right - geom.left() >= size.width() ? right : geom.left() + size.width());
|
|
qreal l, t, r, b;
|
|
child->getContentsMargins(&l, &t, &r, &b);
|
|
pos = QPointF(geom.width() - r - CORNERHANDLE_WIDTH / 2., geom.height() - b - CORNERHANDLE_HEIGHT / 2.);
|
|
}
|
|
break;
|
|
case Qt::BottomLeftCorner: {
|
|
const qreal bottom = geom.bottom() + delta.y();
|
|
const qreal left = geom.left() + delta.x();
|
|
geom.setBottom(bottom - geom.top() >= size.height() ? bottom : geom.top() + size.height());
|
|
geom.setLeft(geom.right() - left >= size.width() ? left : geom.right() - size.width());
|
|
qreal l, t, r, b;
|
|
child->getContentsMargins(&l, &t, &r, &b);
|
|
pos = QPointF(l - CORNERHANDLE_WIDTH / 2., geom.height() - b - CORNERHANDLE_HEIGHT / 2.);
|
|
}
|
|
break;
|
|
}
|
|
child->setGeometry(geom);
|
|
m_cornerHandle.data()->setPos(pos);
|
|
|
|
event->accept();
|
|
}
|
|
break;
|
|
|
|
case QEvent::GraphicsSceneMouseRelease:
|
|
if (obj == m_cornerHandle.data()) {
|
|
QGraphicsWidget *child = m_cornerHandle.data()->parentWidget();
|
|
QRectF geom(child->geometry());
|
|
|
|
QPointF pos(child->pos());
|
|
QRectF rect(contentsRect());
|
|
|
|
const qreal width = rect.width() / m_colsNumber;
|
|
const qreal height = rect.height() / m_rowsNumber;
|
|
int i = qRound(pos.x() / width);
|
|
int j = qRound(pos.y() / height);
|
|
int cols = qRound(geom.width() / width);
|
|
int rows = qRound(geom.height() / height);
|
|
QSizeF minSize(child->effectiveSizeHint(Qt::MinimumSize));
|
|
while (cols * width < minSize.width()) {
|
|
++cols;
|
|
}
|
|
while (rows * height < minSize.height()) {
|
|
++rows;
|
|
}
|
|
i = (i > 0 ? i : 0);
|
|
j = (j > 0 ? j : 0);
|
|
|
|
QRect newRect(i, j, cols, rows);
|
|
|
|
bool intersects = false;
|
|
foreach (QGraphicsWidget *c, children()) {
|
|
if (c != child) {
|
|
QRect r(m_childrenRects.value(c));
|
|
if (r.intersects(newRect)) {
|
|
intersects = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (intersects) {
|
|
newRect = m_childrenRects.value(child);
|
|
} else {
|
|
m_childrenRects.insert(child, newRect);
|
|
}
|
|
child->setGeometry(QRectF(newRect.x() * width + rect.x(), newRect.y() * height + rect.y(),
|
|
width * newRect.width(), height * newRect.height()));
|
|
|
|
QPointF p(child->mapFromScene(static_cast<QGraphicsSceneMouseEvent *>(event)->scenePos()));
|
|
checkCorner(p, child);
|
|
|
|
Plasma::Animation *anim = Plasma::Animator::create(Plasma::Animator::GeometryAnimation);
|
|
if (anim) {
|
|
child->removeEventFilter(this);
|
|
anim->setTargetWidget(child);
|
|
anim->setProperty("startGeometry", geom);
|
|
anim->setProperty("targetGeometry", child->geometry());
|
|
anim->start(QAbstractAnimation::DeleteWhenStopped);
|
|
connect(anim, SIGNAL(finished()), this, SLOT(resizeDone()));
|
|
}
|
|
|
|
m_showGrid = false;
|
|
update();
|
|
|
|
saveChildren();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return AbstractGroup::eventFilter(obj, event);
|
|
}
|
|
|
|
void GridGroup::resizeDone()
|
|
{
|
|
Plasma::Animation *anim = static_cast<Plasma::Animation *>(sender());
|
|
anim->targetWidget()->installEventFilter(this);
|
|
}
|
|
|
|
void GridGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
{
|
|
AbstractGroup::paint(painter, option, widget);
|
|
|
|
if (m_showGrid) {
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
QRectF rect(contentsRect());
|
|
const qreal width = rect.width() / m_colsNumber;
|
|
const qreal height = rect.height() / m_rowsNumber;
|
|
for (int i = 0; i < m_colsNumber; ++i) {
|
|
for (int j = 0; j < m_rowsNumber; ++j) {
|
|
QRectF r(i * width + rect.x(), j * height + rect.y(), width, height);
|
|
if (r.intersects(option->exposedRect)) {
|
|
QPainterPath p = Plasma::PaintUtils::roundedRectangle(r.adjusted(2, 2, -2, -2), 4);
|
|
QColor c = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
|
|
c.setAlphaF(0.3);
|
|
painter->fillPath(p, c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GroupInfo GridGroup::groupInfo()
|
|
{
|
|
GroupInfo gi("grid", i18n("Grid Group"));
|
|
gi.setIcon("view-grid");
|
|
|
|
return gi;
|
|
}
|
|
|
|
#include "moc_gridgroup.cpp"
|