TreeNode.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package ArmarX::Gui::TreeNode
17* @author Kai Welke ( welke at kit dot edu)
18* @date
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
23#include "TreeNode.h"
24
25#include <cfloat>
26
27namespace armarx
28{
31 const QSize TreeNode::DefaultNodeSize(30, 30);
32
33 //----------------------------------------------------------------------
34 // construction
35 //----------------------------------------------------------------------
36 TreeNode::TreeNode(QGraphicsScene* scene, QSize nodeSize)
37 {
38 this->size = nodeSize;
39
40 nodeItem = new QGraphicsEllipseItem();
41 scene->addItem(nodeItem);
42 nodeItem->hide();
43 edgeItem = new QGraphicsLineItem();
44 scene->addItem(edgeItem);
45 edgeItem->hide();
46 }
47
48 //----------------------------------------------------------------------
49 // tree structure
50 //----------------------------------------------------------------------
51 void
52 TreeNode::setParent(TreeNodeWeakPtr parent)
53 {
54 this->parent = parent;
55 // maybe set parent of QGraphicsItems in order to allow transformations
56 }
57
58 void
60 {
61 child->setParent(TreeNodeWeakPtr(shared_from_this()));
62 childs.push_back(child);
63 }
64
65 //----------------------------------------------------------------------
66 // layout handling
67 //----------------------------------------------------------------------
68 void
69 TreeNode::update(QPointF positionLeftTop)
70 {
71 // assure root node
72 if (parent.lock())
73 {
74 return;
75 }
76
77 // recalculate size recursively
78 calculateSubTreeSize();
79
80 // update layout recursively
81 updateLayout(positionLeftTop);
82 }
83
84 std::vector<TreeNodePtr>
86 {
87 return childs;
88 }
89
90 //----------------------------------------------------------------------
91 // helper methods
92 //----------------------------------------------------------------------
93 void
94 TreeNode::updateLayout(QPointF leftTop)
95 {
96 // update of childs if necessary
97 if (childs.size() > 0)
98 {
99 // init left top position of childs
100 QPointF childLeftTop = leftTop;
101 childLeftTop.ry() +=
103
104 std::vector<TreeNodePtr>::iterator iter = childs.begin();
105
106 while (iter != childs.end())
107 {
108 // set layout of children
109 (*iter)->updateLayout(childLeftTop);
110
111 // move to next left position
112 QSize childSubTreeSize = (*iter)->getSubTreeSize();
113 QPointF inc(
114 childSubTreeSize.width() + TreeNode::DefaultNodeHorizontalSeparator.width(), 0);
115 childLeftTop += inc;
116
117 iter++;
118 }
119 }
120
121 // calculate position of node and draw
122 if (childs.size() == 0) // put node in center
123 {
124 // set geometry of node
125 boundingBox =
126 QRectF(leftTop.x() + getSubTreeSize().width() / 2.0f - getSize().width() / 2.0f,
127 leftTop.y(),
128 getSize().width(),
129 getSize().height());
130 drawNode(boundingBox);
131 }
132 else
133 {
134 // center nodes with respect to next layer
135 QRectF childsBB = calculateChildsBoundingBox();
136
137 // set geometry of node
138 boundingBox = QRectF(childsBB.center().x() - getSize().width() / 2.0f,
139 leftTop.y(),
140 getSize().width(),
141 getSize().height());
142 drawNode(boundingBox);
143 }
144
145 // draw edge
146 drawEdges();
147 }
148
149 QSize
150 TreeNode::calculateSubTreeSize()
151 {
152 std::vector<TreeNodePtr>::iterator iter = childs.begin();
153
154 // size of childs
155 int width = 0;
156 int height = 0;
157
158 while (iter != childs.end())
159 {
160 // width of children is the sum
161 QSize childSize = (*iter)->calculateSubTreeSize();
162 width += childSize.width() + TreeNode::DefaultNodeHorizontalSeparator.width();
163
164 // height is the maximum
165 if (childSize.height() > height)
166 {
167 height = childSize.height();
168 }
169
170 iter++;
171 }
172
173 // adapt wize
174 if (childs.size() > 0)
175 {
178 }
179 else
180 {
181 width = getSize().width();
182 }
183
184 // adapt size in height
185 height += getSize().height();
186
187 this->subTreeSize = QSize(width, height);
188
189 return subTreeSize;
190 }
191
192 QRectF
193 TreeNode::calculateChildsBoundingBox()
194 {
195 // calculate boundingbox of childs
196 float minX = FLT_MAX;
197 float maxX = 0;
198
199 float minY = FLT_MAX;
200 float maxY = 0;
201
202 std::vector<TreeNodePtr>::iterator iter = childs.begin();
203
204 while (iter != childs.end())
205 {
206 QRectF childBB = (*iter)->getBoundingBox();
207
208 if (childBB.left() < minX)
209 {
210 minX = childBB.left();
211 }
212
213 if (childBB.right() > maxX)
214 {
215 maxX = childBB.right();
216 }
217
218 if (childBB.top() < minY)
219 {
220 minY = childBB.top();
221 }
222
223 if (childBB.bottom() > maxY)
224 {
225 maxY = childBB.bottom();
226 }
227
228 iter++;
229 }
230
231 QRectF result(minX, minY, maxX - minX, maxY - minY);
232 return result;
233 }
234
235 void
236 TreeNode::drawEdges()
237 {
238 std::vector<TreeNodePtr>::iterator iter = childs.begin();
239
240 while (iter != childs.end())
241 {
242 QPointF lineStart =
243 (getBoundingBox().bottomLeft() + getBoundingBox().bottomRight()) / 2.0f;
244 QPointF lineEnd =
245 ((*iter)->getBoundingBox().topLeft() + (*iter)->getBoundingBox().topRight()) / 2.0f;
246 QLineF line(lineStart, lineEnd);
247
248 (*iter)->drawEdge(line);
249
250 iter++;
251 }
252 }
253
254 void
256 {
257 edgeItem->setLine(line);
258 edgeItem->show();
259 }
260
261 void
262 TreeNode::drawNode(QRectF boundingBox)
263 {
264 nodeItem->setRect(boundingBox);
265 nodeItem->show();
266 }
267} // namespace armarx
std::vector< TreeNodePtr > getChildren() const
Definition TreeNode.cpp:85
virtual void drawEdge(QLineF line)
Draws an edge to this node.
Definition TreeNode.cpp:255
static const QSize DefaultNodeSize
Definition TreeNode.h:49
virtual void drawNode(QRectF boundingBox)
Draws the node.
Definition TreeNode.cpp:262
static const QSize DefaultNodeVerticalSeparator
Definition TreeNode.h:48
static const QSize DefaultNodeHorizontalSeparator
Definition TreeNode.h:47
void addChild(TreeNodePtr child)
Adds a child to the node in the tree structure.
Definition TreeNode.cpp:59
QSize getSize()
Retrieve size of the node.
Definition TreeNode.h:76
QRectF getBoundingBox()
Retrieve boundingbox of the node.
Definition TreeNode.h:88
TreeNode(QGraphicsScene *scene, QSize nodeSize=TreeNode::DefaultNodeSize)
Constructs a tree node as part of a Qt visualizable tree.
Definition TreeNode.cpp:36
void update(QPointF positionLeftTop=QPointF(0, 0))
Updates the layout of the tree.
Definition TreeNode.cpp:69
QSize getSubTreeSize()
Retrieve size of the complete subtree where the current node is root.
Definition TreeNode.h:99
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< TreeNode > TreeNodePtr
Definition TreeNode.h:40
std::weak_ptr< TreeNode > TreeNodeWeakPtr
Definition TreeNode.h:41