2 * Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "layoutmanager.h"
21 #include "randrscreen.h"
22 #include "randroutput.h"
23 #include "outputgraphicsitem.h"
25 #include <QGraphicsScene>
29 LayoutManager::LayoutManager(RandRScreen
*screen
, QGraphicsScene
*scene
)
36 LayoutManager::~LayoutManager()
40 void LayoutManager::slotAdjustOutput(OutputGraphicsItem
*output
)
42 QPointF p
= output
->pos();
43 float nearest
= m_scene
->width() * m_scene
->height();
44 OutputGraphicsItem
*selected
= NULL
;
46 OutputGraphicsItem
*mouseGrabber
= dynamic_cast<OutputGraphicsItem
*>(m_scene
->mouseGrabberItem());
47 // find the nearest item
48 QList
<QGraphicsItem
*> itemList
= m_scene
->items();
50 foreach(QGraphicsItem
*current
, itemList
)
52 OutputGraphicsItem
*cur
= dynamic_cast<OutputGraphicsItem
*>(current
);
53 if (cur
== output
|| cur
== mouseGrabber
)
56 QPointF pos
= cur
->pos();
57 float distance
= (p
.x() - pos
.x())*(p
.x()-pos
.x()) + (p
.y() - pos
.y())*(p
.y() - pos
.y());
58 if (distance
<=nearest
)
67 // find in which side this
68 QRectF s
= selected
->boundingRect();
69 QRectF i
= output
->boundingRect();
71 s
.translate(selected
->scenePos());
72 i
.translate(output
->scenePos());
74 // calculate the distances
75 float top
= fabsf(i
.top() - s
.bottom());
76 float bottom
= fabsf(i
.bottom() - s
.top());
77 float left
= fabsf(i
.left() - s
.right());
78 float right
= fabsf(i
.right() - s
.left());
81 if (top
<= bottom
&& top
<= left
&& top
<= right
)
83 output
->setTop(selected
);
84 selected
->setBottom(output
);
87 else if (bottom
< top
&& bottom
<= left
&& bottom
<= right
)
89 output
->setBottom(selected
);
90 selected
->setTop(output
);
93 else if (left
< top
&& left
< bottom
&& left
<= right
)
95 output
->setLeft(selected
);
96 selected
->setRight(output
);
101 output
->setRight(selected
);
102 selected
->setLeft(output
);
106 // now visit all the outputs on the screen to adjust their positions
107 // starting by the item selected to be the parent of the current item
108 QList
<OutputGraphicsItem
*> visitedList
;
110 // FIXME: after adjusting the scene, we have to translate everything back to
111 // the 0,0 position so that everything is onscreen
113 // call a recursive function to adjust the outputs
114 adjustScene(output
, visitedList
);
117 void LayoutManager::adjustScene(OutputGraphicsItem
*current
, QList
<OutputGraphicsItem
*> &visited
)
119 visited
.append(current
);
121 OutputGraphicsItem
*item
;
122 item
= current
->left();
123 if (item
&& visited
.indexOf(item
) == -1)
125 item
->setPos(current
->x() - item
->boundingRect().width(), current
->y());
126 adjustScene(item
, visited
);
129 item
= current
->right();
130 if (item
&& visited
.indexOf(item
) == -1)
132 item
->setPos(current
->x() + current
->boundingRect().width(), current
->y());
133 adjustScene(item
, visited
);
136 item
= current
->top();
137 if (item
&& visited
.indexOf(item
) == -1)
139 item
->setPos(current
->x(), current
->y() - item
->boundingRect().height());
140 adjustScene(item
, visited
);
143 item
= current
->bottom();
144 if (item
&& visited
.indexOf(item
) == -1)
146 item
->setPos(current
->x(), current
->y() + current
->boundingRect().height());
147 adjustScene(item
, visited
);