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 #include <cfloat>
25 
26 namespace armarx
27 {
29  const QSize TreeNode::DefaultNodeVerticalSeparator(0, 50);
30  const QSize TreeNode::DefaultNodeSize(30, 30);
31 
32  //----------------------------------------------------------------------
33  // construction
34  //----------------------------------------------------------------------
35  TreeNode::TreeNode(QGraphicsScene* scene, QSize nodeSize)
36  {
37  this->size = nodeSize;
38 
39  nodeItem = new QGraphicsEllipseItem();
40  scene->addItem(nodeItem);
41  nodeItem->hide();
42  edgeItem = new QGraphicsLineItem();
43  scene->addItem(edgeItem);
44  edgeItem->hide();
45  }
46 
47  //----------------------------------------------------------------------
48  // tree structure
49  //----------------------------------------------------------------------
50  void TreeNode::setParent(TreeNodeWeakPtr parent)
51  {
52  this->parent = parent;
53  // maybe set parent of QGraphicsItems in order to allow transformations
54  }
55 
57  {
58  child->setParent(TreeNodeWeakPtr(shared_from_this()));
59  childs.push_back(child);
60  }
61 
62  //----------------------------------------------------------------------
63  // layout handling
64  //----------------------------------------------------------------------
65  void TreeNode::update(QPointF positionLeftTop)
66  {
67  // assure root node
68  if (parent.lock())
69  {
70  return;
71  }
72 
73  // recalculate size recursively
74  calculateSubTreeSize();
75 
76  // update layout recursively
77  updateLayout(positionLeftTop);
78  }
79 
80  std::vector<TreeNodePtr> TreeNode::getChildren() const
81  {
82  return childs;
83  }
84 
85  //----------------------------------------------------------------------
86  // helper methods
87  //----------------------------------------------------------------------
88  void TreeNode::updateLayout(QPointF leftTop)
89  {
90  // update of childs if necessary
91  if (childs.size() > 0)
92  {
93  // init left top position of childs
94  QPointF childLeftTop = leftTop;
95  childLeftTop.ry() += TreeNode::DefaultNodeVerticalSeparator.height() + getSize().height();
96 
97  std::vector<TreeNodePtr>::iterator iter = childs.begin();
98 
99  while (iter != childs.end())
100  {
101  // set layout of children
102  (*iter)->updateLayout(childLeftTop);
103 
104  // move to next left position
105  QSize childSubTreeSize = (*iter)->getSubTreeSize();
106  QPointF inc(childSubTreeSize.width() + TreeNode::DefaultNodeHorizontalSeparator.width(), 0);
107  childLeftTop += inc;
108 
109  iter++;
110  }
111  }
112 
113  // calculate position of node and draw
114  if (childs.size() == 0) // put node in center
115  {
116  // set geometry of node
117  boundingBox = QRectF(leftTop.x() + getSubTreeSize().width() / 2.0f - getSize().width() / 2.0f, leftTop.y(), getSize().width(), getSize().height());
118  drawNode(boundingBox);
119  }
120  else
121  {
122  // center nodes with respect to next layer
123  QRectF childsBB = calculateChildsBoundingBox();
124 
125  // set geometry of node
126  boundingBox = QRectF(childsBB.center().x() - getSize().width() / 2.0f, leftTop.y(), getSize().width(), getSize().height());
127  drawNode(boundingBox);
128  }
129 
130  // draw edge
131  drawEdges();
132  }
133 
134  QSize TreeNode::calculateSubTreeSize()
135  {
136  std::vector<TreeNodePtr>::iterator iter = childs.begin();
137 
138  // size of childs
139  int width = 0;
140  int height = 0;
141 
142  while (iter != childs.end())
143  {
144  // width of children is the sum
145  QSize childSize = (*iter)->calculateSubTreeSize();
146  width += childSize.width() + TreeNode::DefaultNodeHorizontalSeparator.width();
147 
148  // height is the maximum
149  if (childSize.height() > height)
150  {
151  height = childSize.height();
152  }
153 
154  iter++;
155  }
156 
157  // adapt wize
158  if (childs.size() > 0)
159  {
161  height += TreeNode::DefaultNodeVerticalSeparator.height();
162  }
163  else
164  {
165  width = getSize().width();
166  }
167 
168  // adapt size in height
169  height += getSize().height();
170 
171  this->subTreeSize = QSize(width, height);
172 
173  return subTreeSize;
174  }
175 
176  QRectF TreeNode::calculateChildsBoundingBox()
177  {
178  // calculate boundingbox of childs
179  float minX = FLT_MAX;
180  float maxX = 0;
181 
182  float minY = FLT_MAX;
183  float maxY = 0;
184 
185  std::vector<TreeNodePtr>::iterator iter = childs.begin();
186 
187  while (iter != childs.end())
188  {
189  QRectF childBB = (*iter)->getBoundingBox();
190 
191  if (childBB.left() < minX)
192  {
193  minX = childBB.left();
194  }
195 
196  if (childBB.right() > maxX)
197  {
198  maxX = childBB.right();
199  }
200 
201  if (childBB.top() < minY)
202  {
203  minY = childBB.top();
204  }
205 
206  if (childBB.bottom() > maxY)
207  {
208  maxY = childBB.bottom();
209  }
210 
211  iter++;
212  }
213 
214  QRectF result(minX, minY, maxX - minX, maxY - minY);
215  return result;
216  }
217 
218  void TreeNode::drawEdges()
219  {
220  std::vector<TreeNodePtr>::iterator iter = childs.begin();
221 
222  while (iter != childs.end())
223  {
224  QPointF lineStart = (getBoundingBox().bottomLeft() + getBoundingBox().bottomRight()) / 2.0f;
225  QPointF lineEnd = ((*iter)->getBoundingBox().topLeft() + (*iter)->getBoundingBox().topRight()) / 2.0f;
226  QLineF line(lineStart, lineEnd);
227 
228  (*iter)->drawEdge(line);
229 
230  iter++;
231  }
232  }
233 
234  void TreeNode::drawEdge(QLineF line)
235  {
236  edgeItem->setLine(line);
237  edgeItem->show();
238  }
239 
240  void TreeNode::drawNode(QRectF boundingBox)
241  {
242  nodeItem->setRect(boundingBox);
243  nodeItem->show();
244  }
245 }
armarx::TreeNode::DefaultNodeVerticalSeparator
static const QSize DefaultNodeVerticalSeparator
Definition: TreeNode.h:48
armarx::TreeNode::getChildren
std::vector< TreeNodePtr > getChildren() const
Definition: TreeNode.cpp:80
armarx::TreeNodePtr
std::shared_ptr< TreeNode > TreeNodePtr
Definition: TreeNode.h:40
armarx::TreeNode::TreeNode
TreeNode(QGraphicsScene *scene, QSize nodeSize=TreeNode::DefaultNodeSize)
Constructs a tree node as part of a Qt visualizable tree.
Definition: TreeNode.cpp:35
armarx::TreeNode::DefaultNodeHorizontalSeparator
static const QSize DefaultNodeHorizontalSeparator
Definition: TreeNode.h:47
TreeNode.h
armarx::TreeNode::DefaultNodeSize
static const QSize DefaultNodeSize
Definition: TreeNode.h:49
armarx::TreeNode::getSubTreeSize
QSize getSubTreeSize()
Retrieve size of the complete subtree where the current node is root.
Definition: TreeNode.h:97
armarx::TreeNode::update
void update(QPointF positionLeftTop=QPointF(0, 0))
Updates the layout of the tree.
Definition: TreeNode.cpp:65
armarx::TreeNode::drawNode
virtual void drawNode(QRectF boundingBox)
Draws the node.
Definition: TreeNode.cpp:240
armarx::TreeNodeWeakPtr
std::weak_ptr< TreeNode > TreeNodeWeakPtr
Definition: TreeNode.h:41
armarx::TreeNode::getBoundingBox
QRectF getBoundingBox()
Retrieve boundingbox of the node.
Definition: TreeNode.h:87
armarx::TreeNode::addChild
void addChild(TreeNodePtr child)
Adds a child to the node in the tree structure.
Definition: TreeNode.cpp:56
armarx::TreeNode::drawEdge
virtual void drawEdge(QLineF line)
Draws an edge to this node.
Definition: TreeNode.cpp:234
armarx::TreeNode::getSize
QSize getSize()
Retrieve size of the node.
Definition: TreeNode.h:76
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28