NCL Composer  0.1.5
 All Classes Functions Variables Pages
qnstgraphicsnode.cpp
1 #include "qnstgraphicsnode.h"
2 
3 #include <QDebug>
4 
5 QnstGraphicsNode::QnstGraphicsNode(QnstGraphicsEntity* parent)
7 {
8  setncgType(Qncg::Node);
9  setnstType(Qnst::Node);
10 
11  hover = false;
12 }
13 
14 QnstGraphicsNode::~QnstGraphicsNode()
15 {
16 
17 }
18 
19 void QnstGraphicsNode::fit(qreal padding)
20 {
21  qreal top = getTop();
22  qreal left = getLeft();
23  qreal width = getWidth();
24  qreal height = getHeight();
25 
26  qreal nextTop = top;
27  qreal nextLeft = left;
28  qreal nextWidth = width;
29  qreal nextHeight = height;
30 
31  foreach(QncgGraphicsEntity* entity, getncgGraphicsEntities())
32  {
33  if (entity->getncgType() == Qncg::Node)
34  {
35  if ((entity->getTop()-4) + top < nextTop + padding)
36  {
37  nextTop = (entity->getTop()-4) + top - padding;
38  }
39 
40  if ((entity->getLeft()-4) + left < nextLeft + padding)
41  {
42  nextLeft = (entity->getLeft()-4) + left - padding;
43  }
44 
45  if ((entity->getLeft()-4) + entity->getWidth() > nextWidth - padding)
46  {
47  nextWidth = (entity->getLeft()-4) + entity->getWidth() + padding;
48  }
49 
50  if ((entity->getTop()-4) + entity->getHeight() > nextHeight - padding)
51  {
52  nextHeight = (entity->getTop()-4) + entity->getHeight() + padding;
53  }
54  }
55  }
56 
57  if (nextWidth != width)
58  setWidth(nextWidth);
59 
60  if (nextHeight != height)
61  setHeight(nextHeight);
62 
63  if (nextTop != top)
64  {
65  foreach(QncgGraphicsEntity* entity, getncgGraphicsEntities())
66  {
67  if (entity->getncgType() == Qncg::Node)
68  {
69  entity->setTop(entity->getTop() + (top - nextTop));
70  }
71  }
72 
73  setHeight(getHeight() + (top - nextTop));
74  setTop(nextTop);
75  }
76 
77  if (nextLeft != left)
78  {
79  foreach(QncgGraphicsEntity* entity, getncgGraphicsEntities())
80  {
81  if (entity->getncgType() == Qncg::Node)
82  {
83  entity->setLeft(entity->getLeft() + (left - nextLeft));
84  }
85  }
86 
87  setWidth(getWidth() + (left - nextLeft));
88  setLeft(nextLeft);
89  }
90 
91  QnstGraphicsNode* parent = (QnstGraphicsNode*) getnstGraphicsParent();
92 
93  if (parent != NULL)
94  parent->fit(padding);
95 }
96 
97 void QnstGraphicsNode::inside()
98 {
99  QncgGraphicsEntity* parent = getncgGraphicsParent();
100 
101  if (parent != NULL)
102  {
103  QPointF pa(getLeft()+getWidth()/2, getTop()+getHeight()/2);
104  QPointF pb(parent->getWidth()/2, parent->getHeight()/2);
105 
106  QLineF line(pa, pb);
107 
108  qreal n = 0;
109 
110  qreal i = 0.0;
111 
112  setSelectable(false);
113  update();
114 
115  while(!collidesWithItem(parent,Qt::ContainsItemShape))
116  {
117  i += 0.01;
118 
119  setTop(getTop()+line.pointAt(i).y()-pa.y());
120  setLeft(getLeft()+line.pointAt(i).x()-pa.x());
121 
122  if (++n > 1000) // avoid inifinity loop
123  {
124  n = -1;
125  break;
126  }
127  }
128 
129  if (n < 0)
130  {
131  setTop(pb.x()-getHeight()/2);
132  setLeft(pb.y()-getWidth()/2);
133  }
134 
135  setSelectable(true); update();
136  }
137 }
138 
139 
140 void QnstGraphicsNode::adjust(bool avoidCollision)
141 {
142  foreach(QnstGraphicsEntity* entity, getnstGraphicsEntities())
143  {
144  entity->adjust();
145  }
146 
147  if(getnstGraphicsParent() != NULL)
148  {
149  if (avoidCollision){
150  int colliding;
151  int maxInter = 10, inter = 0;
152  do
153  {
154  if(inter > maxInter) break;
155  inter++;
156 
157  colliding = false;
158  foreach(QnstGraphicsEntity *entity,
159  getnstGraphicsParent()->getnstGraphicsEntities())
160  {
161  if(this != entity && entity->getnstType() >= Qnst::Node &&
162  entity->getnstType() <= Qnst::Switch)
163  {
164  qreal n = 0;
165  qreal i = 0.0;
166 
167  entity->setSelectable(false); update();
168  // check collision
169  while(collidesWithItem(entity, Qt::IntersectsItemBoundingRect))
170  {
171 
172  QPointF pa(getLeft()+getWidth()/2, getTop()+getHeight()/2);
173  QPointF pb(entity->getWidth()/2, entity->getHeight()/2);
174 
175  QLineF line(pa, pb);
176 
177  line.setAngle(qrand()%360);
178 
179  i += (double)(qrand()%100)/10000.0;
180 
181  setTop(getTop()+line.pointAt(i/2).y()-pa.y());
182  setLeft(getLeft()+line.pointAt(i/2).x()-pa.x());
183 
184  if (++n > 1000){
185  n = -1; break;
186  }
187  }
188 
189  inside();
190 
191  entity->setSelectable(true); update();
192  }
193  }
194 
195  foreach(QnstGraphicsEntity *entity,
196  getnstGraphicsParent()->getnstGraphicsEntities())
197  {
198  if(collidesWithItem(entity, Qt::IntersectsItemBoundingRect))
199  {
200  colliding = true;
201  }
202  }
203  }
204  while(colliding);
205  }
206  }
207 
208  inside();
209 
210  foreach(QnstGraphicsEntity* entity, getnstGraphicsEdges())
211  {
212  if (entity->getnstType() == Qnst::Reference ||
213  entity->getnstType() == Qnst::Link ||
214  entity->getnstType() == Qnst::Mapping ||
215  entity->getnstType() == Qnst::Condition ||
216  entity->getnstType() == Qnst::Action)
217  {
218  entity->adjust();
219  }
220  }
221 
222  if (scene() != NULL)
223  scene()->update();
224 }
225 
226 void QnstGraphicsNode::move(QGraphicsSceneMouseEvent* event)
227 {
228  // setting
229  qreal x = getLeft();
230  qreal y = getTop();
231 
232  QncgGraphicsEntity* parent = getncgGraphicsParent();
233 
234  // setting minimal position
235  qreal minx;
236  qreal miny;
237 
238  if (parent != NULL)
239  {
240  minx = 4;
241  miny = 4;
242  }
243  else
244  {
245  minx = 0;
246  miny = 0;
247  }
248 
249  // setting maximal position
250  qreal maxx;
251  qreal maxy;
252 
253  if (parent != NULL)
254  {
255  maxx = parent->getWidth() - getWidth() - 4;
256  maxy = parent->getHeight() - getHeight() - 4;
257  }
258  else
259  {
260  maxx = scene()->width() - getWidth();
261  maxy = scene()->height() - getHeight();
262  }
263 
264  // setting delta
265  qreal dx = event->pos().x() - getPressLeft(); // (x1 - x0)
266  qreal dy = event->pos().y() - getPressTop(); // (y1 - y0)
267 
268  // setting next position
269  qreal nextx = x + dx;
270  qreal nexty = y + dy;
271 
272  // moving
273  setMoveTop(nexty);
274  setMoveLeft(nextx);
275 
276 
277  scene()->update();
278 }
279 
280 void QnstGraphicsNode::resize(QGraphicsSceneMouseEvent* event)
281 {
282  // setting
283  qreal x = getLeft();
284  qreal y = getTop();
285  qreal w = getWidth();
286  qreal h = getHeight();
287 
288  QncgGraphicsEntity* parent = getncgGraphicsParent();
289 
290  // setting minimal bounds
291  qreal minx;
292  qreal miny;
293  qreal minw;
294  qreal minh;
295 
296  if (parentItem() != NULL)
297  {
298  minx = 4;
299  miny = 4;
300  minw = -1; // not used
301  minh = -1; // not used
302  }
303  else
304  {
305  minx = 0;
306  miny = 0;
307  minw = -1; // not used
308  minh = -1; // not used
309  }
310 
311  // setting maximal bounds
312  qreal maxx;
313  qreal maxy;
314  qreal maxw;
315  qreal maxh;
316 
317  if (parentItem() != NULL)
318  {
319  maxx = parent->getWidth() - getWidth() - 4;
320  maxy = parent->getHeight() - getHeight() - 4;
321  maxw = parent->getWidth() - 4;
322  maxh = parent->getHeight() - 4;
323  }
324  else
325  {
326  maxx = scene()->width() - getWidth();
327  maxy = scene()->height() - getHeight();
328  maxw = scene()->width();
329  maxh = scene()->height();
330  }
331 
332  // setting delta
333  qreal dx = event->pos().x() - getPressLeft(); // (x1 - x0)
334  qreal dy = event->pos().y() - getPressTop(); // (y1 - y0)
335  qreal dw = -dx;
336  qreal dh = -dy;
337 
338  // setting next bounds
339  qreal nextx = x + dx;
340  qreal nexty = y + dy;
341  qreal nextw = w + dw;
342  qreal nexth = h + dh;
343 
344  // adjusting
345  switch(getncgResize())
346  {
347  case Qncg::TopLeft:
348  {
349  break;
350  }
351 
352  case Qncg::Top:
353  {
354  nextx = x; // fixed x
355  nextw = w; // fixed width
356 
357  break;
358  }
359 
360  case Qncg::TopRight:
361  {
362  nextx = x; // fixed x
363  nextw = w - dw;
364 
365  break;
366  }
367 
368  case Qncg::Right:
369  {
370  nextx = x; // fixed x
371  nextw = w - dw;
372 
373  nexty = y; // fixed y
374  nexth = h; // fixed height
375 
376  break;
377  }
378 
379  case Qncg::BottomRight:
380  {
381  nextx = x; // fixed x
382  nextw = w - dw;
383 
384  nexty = y; // fixed y
385  nexth = h - dh;
386 
387  break;
388  }
389 
390  case Qncg::Bottom:
391  {
392  nextx = x; // fixed x
393  nextw = w; // fixed width
394 
395  nexty = y; // fixed y
396  nexth = h - dh;
397 
398  break;
399  }
400 
401  case Qncg::BottomLeft:
402  {
403  nexty = y; // fixed y
404  nexth = h - dh;
405 
406  break;
407  }
408 
409  case Qncg::Left:
410  {
411  nexty = y; // fixed y
412  nexth = h; // fixed height
413 
414  break;
415  }
416  }
417 
418  // resizing
419  setResizeTop(nexty);
420  setResizeLeft(nextx);
421  setResizeWidth(nextw);
422  setResizeHeight(nexth);
423 
424  scene()->update();
425 }