HAL
graphics_scene.cpp
Go to the documentation of this file.
2 
5 #include "hal_core/netlist/net.h"
7 
17 #include "gui/gui_globals.h"
19 
20 #include <QGraphicsSceneMouseEvent>
21 #include <QPainter>
22 #include <QString>
23 
24 #include <QDebug>
25 
26 namespace hal
27 {
28  qreal GraphicsScene::sLod = 0;
29 
30  const qreal GraphicsScene::sGridFadeStart = 0.4;
31  const qreal GraphicsScene::sGridFadeEnd = 1.0;
32 
33  bool GraphicsScene::sGridEnabled = true;
34  bool GraphicsScene::sGridClustersEnabled = true;
35  GraphicsScene::GridType GraphicsScene::sGridType = GraphicsScene::GridType::Dots;
36 
37  void GraphicsScene::setLod(const qreal& lod)
38  {
39  sLod = lod;
40 
41  if (lod >= sGridFadeStart && lod <= sGridFadeEnd)
42  {
43  const qreal alpha = (lod - sGridFadeStart) / (sGridFadeEnd - sGridFadeStart);
44 
46  }
47  else
48  {
49  const int alpha = 255;
50 
52  }
53  }
54 
55  void GraphicsScene::setGridEnabled(const bool& value)
56  {
57  sGridEnabled = value;
58  }
59 
60  void GraphicsScene::setGridClustersEnabled(const bool& value)
61  {
62  sGridClustersEnabled = value;
63  }
64 
66  {
67  sGridType = gridType;
68  }
69 
71  {
72  int adjusted_x = qRound(pos.x() / graph_widget_constants::sGridSize) * graph_widget_constants::sGridSize;
73  int adjusted_y = qRound(pos.y() / graph_widget_constants::sGridSize) * graph_widget_constants::sGridSize;
74  return QPoint(adjusted_x, adjusted_y);
75  }
76 
78  mDebugGridEnable(false),
79  mDragController(nullptr),
80  mSelectionStatus(NotPressed)
81  {
82  // FIND OUT IF MANUAL CHANGE TO DEPTH IS NECESSARY / INCREASES PERFORMANCE
83  //mScene.setBspTreeDepth(10);
84 
85  gSelectionRelay->registerSender(this, "GraphView");
86  connectAll();
87 
89  }
90 
92  {
94  if (mDragController) mDragController->clearShadows(this);
95 
96  for (QGraphicsItem* gi : items())
97  {
98  removeItem(gi);
99  delete gi;
100  }
101  }
102 
104  {
105  mDragController = dc;
106  }
107 
109  {
110  // SELECTION HAS TO BE UPDATED MANUALLY AFTER ADDING / REMOVING ITEMS
111 
112  if (!item)
113  return;
114 
116 
117  switch (item->itemType())
118  {
119  case ItemType::Gate:
120  {
121  GraphicsGate* g = static_cast<GraphicsGate*>(item);
122  int i = 0;
123  while (i < mGateItems.size())
124  {
125  if (g->id() < mGateItems.at(i)->id())
126  break;
127 
128  i++;
129  }
130  mGateItems.insert(i, g);
131  return;
132  }
133  case ItemType::Net:
134  {
135  GraphicsNet* n = static_cast<GraphicsNet*>(item);
136  int i = 0;
137  while (i < mNetItems.size())
138  {
139  if (n->id() < mNetItems.at(i)->id())
140  break;
141 
142  i++;
143  }
144  mNetItems.insert(i, n);
145  return;
146  }
147  case ItemType::Module:
148  {
149  GraphicsModule* m = static_cast<GraphicsModule*>(item);
150  int i = 0;
151  while (i < mModuleItems.size())
152  {
153  if (m->id() < mModuleItems.at(i)->id())
154  break;
155 
156  i++;
157  }
158  mModuleItems.insert(i, m);
159  return;
160  }
161  default:
162  return;
163  }
164  }
165 
167  {
168  // SELECTION HAS TO BE UPDATED MANUALLY AFTER ADDING / REMOVING ITEMS
169 
170  if (!item)
171  return;
172 
174 
175  switch (item->itemType())
176  {
177  case ItemType::Gate:
178  {
179  GraphicsGate* g = static_cast<GraphicsGate*>(item);
180  u32 id = g->id();
181 
182  int i = 0;
183  while (i < mGateItems.size())
184  {
185  if (mGateItems.at(i)->id() == id)
186  {
187  mGateItems.remove(i);
188  delete g;
189  return;
190  }
191 
192  ++i;
193  }
194 
195  return;
196  }
197  case ItemType::Net:
198  {
199  GraphicsNet* n = static_cast<GraphicsNet*>(item);
200  u32 id = n->id();
201 
202  int i = 0;
203  while (i < mNetItems.size())
204  {
205  if (mNetItems.at(i)->id() == id)
206  {
207  mNetItems.remove(i);
208  delete n;
209  return;
210  }
211 
212  ++i;
213  }
214 
215  return;
216  }
217  case ItemType::Module:
218  {
219  GraphicsModule* m = static_cast<GraphicsModule*>(item);
220  u32 id = m->id();
221 
222  int i = 0;
223  while (i < mModuleItems.size())
224  {
225  if (mModuleItems.at(i)->id() == id)
226  {
227  mModuleItems.remove(i);
228  delete m;
229  return;
230  }
231 
232  ++i;
233  }
234 
235  return;
236  }
237  default:
238  return;
239  }
240  }
241 
243  {
244  for (const GraphicsGate* gg : mGateItems)
245  {
246  if (gg->id() > id)
247  break;
248 
249  if (gg->id() == id)
250  return gg;
251  }
252 
253  return nullptr;
254  }
255 
257  {
258  for (const GraphicsNet* gn : mNetItems)
259  {
260  if (gn->id() > id)
261  break;
262 
263  if (gn->id() == id)
264  return gn;
265  }
266 
267  return nullptr;
268  }
269 
271  {
272  for (const GraphicsModule* gm : mModuleItems)
273  {
274  if (gm->id() > id)
275  break;
276 
277  if (gm->id() == id)
278  return gm;
279  }
280 
281  return nullptr;
282  }
283 
285  {
287 
298  }
299 
301  {
303 
314  }
315 
317  {
318  if (mDragController) mDragController->clearShadows(this);
319 
320  for (auto item : items())
321  {
322  removeItem(item);
323  }
324 
325  mModuleItems.clear();
326  mGateItems.clear();
327  mNetItems.clear();
329  }
330 
332  {
333  for (GraphicsModule* gm : mModuleItems)
334  {
335  gm->setVisuals(s.mOduleVisuals.value(gm->id()));
336  }
337 
338  for (GraphicsGate* gg : mGateItems)
339  {
340  gg->setVisuals(s.mGateVisuals.value(gg->id()));
341  }
342 
343  for (GraphicsNet* gn : mNetItems)
344  {
345  gn->setVisuals(s.mNetVisuals.value(gn->id()));
346  }
347  }
348 
350  {
351  for (GraphicsNet* gn : mNetItems)
352  gn->setZValue(-1);
353  }
354 
355  void GraphicsScene::setMousePressed(bool isPressed)
356  {
357  if (isPressed)
358  {
359  // internal selection changed event might fire before mouse pressed event
360  if (mSelectionStatus != SelectionChanged)
361  mSelectionStatus = BeginPressed;
362  }
363  else
364  {
365  // released ...
366  if (mSelectionStatus == SelectionChanged)
367  {
368  mSelectionStatus = EndPressed;
370  }
371  mSelectionStatus = NotPressed;
372  }
373  }
374 
375 
377  {
378  switch (mSelectionStatus)
379  {
380  case SelectionChanged:
381  return;
382  case BeginPressed:
383  mSelectionStatus = SelectionChanged;
386  return;
387  default:
388  // no mouse pressed (single click) or mouse released
389  break;
390  }
391 
393 
394  QSet<u32> mods;
395  QSet<u32> gats;
396  QSet<u32> nets;
397 
398  for (const QGraphicsItem* item : selectedItems())
399  {
400  switch (static_cast<const GraphicsItem*>(item)->itemType())
401  {
402  case ItemType::Gate:
403  {
404  gats.insert(static_cast<const GraphicsItem*>(item)->id());
405  break;
406  }
407  case ItemType::Net:
408  {
409  nets.insert(static_cast<const GraphicsItem*>(item)->id());
410  break;
411  }
412  case ItemType::Module:
413  {
414  mods.insert(static_cast<const GraphicsItem*>(item)->id());
415  break;
416  }
417  default:
418  break;
419  }
420  }
421 
422  // TEST CODE
423  // ADD FOCUS DEDUCTION INTO RELAY ???
424  if (gats.size() + nets.size() + mods.size() == 1)
425  {
426  if (!gats.isEmpty())
427  {
429  }
430  else if (!nets.isEmpty())
431  {
433  }
434  else
435  {
437  }
438  }
439  else
440  {
442  }
443  // END OF TEST CODE
444 
445  //LOG MANUAL SELECTION CHANGED:
446  //log_info("gui", "Selection changed through manual interaction with a view to: insert here..");
447 
452  }
453 
455  {
456  Q_UNUSED(grp);
457 
459  if (gm) gm->update();
460  }
461 
463  {
464  Q_UNUSED(grp);
465 
467  if (gg) gg->update();
468  }
469 
471  {
472  Q_UNUSED(grp);
473 
474  GraphicsNet* gn = (GraphicsNet*) getNetItem(id);
475  if (gn) gn->update();
476  }
477 
479  {
480  Q_UNUSED(grp);
481 
482  updateAllItems();
483  }
484 
486  {
487  for (GraphicsModule* gm : mModuleItems)
488  gm->update();
489  for (GraphicsGate* gg : mGateItems)
490  gg->update();
491  for (GraphicsNet* gn : mNetItems)
492  gn->update();
493  }
494 
496  {
497  QSet<u32> highlightSet[3];
498  for (const ModuleItem* sti : highlightItems)
499  {
500  if (sti) highlightSet[(int)sti->getType()].insert(sti->id());
501  }
502 
503  for (GraphicsModule* gm : mModuleItems)
504  gm->setHightlight(highlightSet[(int)ModuleItem::TreeItemType::Module].contains(gm->id()));
505  for (GraphicsGate* gg : mGateItems)
506  gg->setHightlight(highlightSet[(int)ModuleItem::TreeItemType::Gate].contains(gg->id()));
507  for (GraphicsNet* gn : mNetItems)
508  gn->setHightlight(highlightSet[(int)ModuleItem::TreeItemType::Net].contains(gn->id()));
509  }
510 
512  {
513  // CLEAR CURRENT SELECTION EITHER MANUALLY OR USING clearSelection()
514  // UNCERTAIN ABOUT THE SENDER PARAMETER
515 
516  if (sender == this)
517  return;
518 
519  bool original_value = blockSignals(true);
520 
521  clearSelection();
522 
524  {
525  for (GraphicsModule* gm : mModuleItems)
526  {
527  if (gSelectionRelay->isModuleSelected(gm->id()))
528  {
529  gm->setSelected(true);
530  gm->update();
531  }
532  }
533  }
534 
536  {
537  for (GraphicsGate* gg : mGateItems)
538  {
539  if (gSelectionRelay->isGateSelected(gg->id()))
540  {
541  gg->setSelected(true);
542  gg->update();
543  }
544  }
545  }
546 
548  {
549  for (GraphicsNet* gn : mNetItems)
550  {
551  if (gSelectionRelay->isNetSelected(gn->id()))
552  {
553  gn->setSelected(true);
554  gn->update();
555  }
556  }
557  }
558 
559  blockSignals(original_value);
560  }
561 
563  {
564  Q_UNUSED(sender)
565  }
566 
568  {
569  // CONTEXT MENU CLEARING SELECTION WORKAROUND
570  if (event->button() == Qt::RightButton)
571  {
572  event->accept();
573  return;
574  }
575 
577  }
578 
579  void GraphicsScene::drawBackground(QPainter* painter, const QRectF& rect)
580  {
581  if (!sGridEnabled)
582  return;
583 
584  if (sLod < sGridFadeStart)
585  return;
586 
587  QFlags original_flags = painter->renderHints(); // UNNECESSARY ?
588  painter->setRenderHint(QPainter::Antialiasing, true);
589 
590  QPen pen;
591  pen.setWidth(2);
592 
593  // OVERDRAW NEEDED BECAUSE QT FAILS AT BASIC geometry
594  const int overdraw = 2;
595 
596  const int x_from = rect.left() - overdraw;
597  const int x_to = rect.right() + overdraw;
598 
599  const int y_from = rect.top() - overdraw;
600  const int y_to = rect.bottom() + overdraw;
601 
602  const int xOffset = x_from % graph_widget_constants::sGridSize;
603  const int yOffset = y_from % graph_widget_constants::sGridSize;
604 
605  switch (sGridType)
606  {
607  case GraphicsScene::GridType::None:
608  break;//return; // nothing to do //indirectly disabled the debug grid if activated
609  case GraphicsScene::GridType::Lines:
610  {
611  QVarLengthArray<QLine, 512> base_lines;
612  QVarLengthArray<QLine, 64> cluster_lines;
613 
614  for (int x = x_from - xOffset; x < x_to; x += graph_widget_constants::sGridSize)
615  {
616  QLine line(x, y_from, x, y_to);
617  if (x % (graph_widget_constants::sGridSize * graph_widget_constants::sClusterSize))
618  base_lines.append(line);
619  else
620  cluster_lines.append(line);
621  }
622 
623  for (int y = y_from - yOffset; y < y_to; y += graph_widget_constants::sGridSize)
624  {
625  QLine line(x_from, y, x_to, y);
626  if (y % (graph_widget_constants::sGridSize * graph_widget_constants::sClusterSize))
627  base_lines.append(line);
628  else
629  cluster_lines.append(line);
630  }
631 
632  pen.setColor(GraphicsQssAdapter::instance()->gridBaseLineColor());
633  painter->setPen(pen);
634 
635  painter->drawLines(base_lines.data(), base_lines.size());
636 
637  if (sGridClustersEnabled)
638  {
639  pen.setColor(GraphicsQssAdapter::instance()->gridClusterLineColor());
640  painter->setPen(pen);
641  }
642 
643  painter->drawLines(cluster_lines.data(), cluster_lines.size());
644  break;
645  }
646 
647  case GraphicsScene::GridType::Dots:
648  {
649  QVector<QPoint> base_points;
650  QVector<QPoint> cluster_points;
651 
652  for (int x = x_from - xOffset; x < x_to; x += graph_widget_constants::sGridSize)
653  for (int y = y_from - yOffset; y < y_to; y += graph_widget_constants::sGridSize)
654  {
655  if ((x % (graph_widget_constants::sGridSize * graph_widget_constants::sClusterSize)) && (y % (graph_widget_constants::sGridSize * graph_widget_constants::sClusterSize)))
656  base_points.append(QPoint(x,y));
657  else
658  cluster_points.append(QPoint(x,y));
659  }
660 
661  pen.setColor(GraphicsQssAdapter::instance()->gridBaseDotColor());
662  painter->setPen(pen);
663 
664  painter->drawPoints(base_points.data(), base_points.size());
665 
666  if (sGridClustersEnabled)
667  {
668  pen.setColor(GraphicsQssAdapter::instance()->gridClusterDotColor());
669  painter->setPen(pen);
670  }
671 
672  painter->drawPoints(cluster_points.data(), cluster_points.size());
673  break;
674  }
675  }
676 
677  #ifdef GUI_DEBUG_GRID
678  if (mDebugGridEnable)
679  debugDrawLayouterGrid(painter, x_from, x_to, y_from, y_to);
680  #endif
681 
682  painter->setRenderHints(original_flags); // UNNECESSARY ?
683  }
684 
685  #ifdef GUI_DEBUG_GRID
686  void GraphicsScene::debugSetLayouterGrid(const QVector<qreal>& debug_x_lines, const QVector<qreal>& debug_y_lines, qreal debug_default_height, qreal debug_default_width)
687  {
688  mDebugXLines = debug_x_lines;
689  mDebugYLines = debug_y_lines;
690  mDebugDefaultHeight = debug_default_height;
691  mDebugDefaultWidth = debug_default_width;
692  }
693 
694  void GraphicsScene::debugDrawLayouterGrid(QPainter* painter, const int x_from, const int x_to, const int y_from, const int y_to)
695  {
696  if (mDebugXLines.isEmpty() || mDebugYLines.isEmpty()) return;
697  painter->setPen(QPen(Qt::magenta));
698 
699  for (qreal x : mDebugXLines)
700  {
701  QLineF line(x, y_from, x, y_to);
702  painter->drawLine(line);
703  }
704 
705  for (qreal y : mDebugYLines)
706  {
707  QLineF line(x_from, y, x_to, y);
708  painter->drawLine(line);
709  }
710 
711  painter->setPen(QPen(Qt::green));
712 
713  qreal x = mDebugXLines.last() + mDebugDefaultWidth;
714 
715  while (x <= x_to)
716  {
717  QLineF line(x, y_from, x, y_to);
718  painter->drawLine(line);
719  x += mDebugDefaultWidth;
720  }
721 
722  x = mDebugXLines.first() - mDebugDefaultWidth;
723 
724  while (x >= x_from)
725  {
726  QLineF line(x, y_from, x, y_to);
727  painter->drawLine(line);
728  x -= mDebugDefaultWidth;
729  }
730 
731  qreal y = mDebugYLines.last() + mDebugDefaultHeight;
732 
733  while (y <= y_to)
734  {
735  QLineF line(x_from, y, x_to, y);
736  painter->drawLine(line);
737  y += mDebugDefaultHeight;
738  }
739 
740  y = mDebugYLines.first() - mDebugDefaultHeight;
741 
742  while (y >= y_from)
743  {
744  QLineF line(x_from, y, x_to, y);
745  painter->drawLine(line);
746  y -= mDebugDefaultHeight;
747  }
748  }
749 
750  void GraphicsScene::setDebugGridEnabled(bool enabled)
751  {
752  mDebugGridEnable = enabled;
753  }
754 
755  bool GraphicsScene::debugGridEnabled()
756  {
757  return mDebugGridEnable;
758  }
759  #endif
760 }
GroupingManagerWidget * getGroupingManagerWidget()
static SettingsItemCheckbox * sSettingNetGroupingToPins
Abstract base class for gates.
Definition: graphics_gate.h:48
Superclass for all graphic items used ins the GraphicsScene. It contains information about the underl...
Definition: graphics_item.h:44
ItemType itemType() const
Abstract base class for modules.
The basic net class all other nets inherit from.
Definition: graphics_net.h:43
static GraphicsQssAdapter * instance()
void removeGraphItem(GraphicsItem *item)
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
const GraphicsGate * getGateItem(const u32 id) const
void updateVisuals(const GraphShader::Shading &s)
static void setLod(const qreal &lod)
void handleGroupingAssignNet(Grouping *grp, u32 id)
void setMousePressed(bool isPressed)
void handleGroupingAssignModule(Grouping *grp, u32 id)
const GraphicsModule * getModuleItem(const u32 id) const
void handleHighlight(const QVector< const ModuleItem * > &highlightItems)
void handleGroupingAssignGate(Grouping *grp, u32 id)
void handleExternSelectionChanged(void *sender)
static void setGridEnabled(const bool &value)
void handleGroupingColorChanged(Grouping *grp)
static void setGridType(const GridType &gridType)
void addGraphItem(GraphicsItem *item)
void handleInternSelectionChanged()
const GraphicsNet * getNetItem(const u32 id) const
static QPointF snapToGrid(const QPointF &pos) Q_DECL_DEPRECATED
void handleExternSubfocusChanged(void *sender)
void setDragController(DragController *dc)
static void setGridClustersEnabled(const bool &value)
GraphicsScene(QObject *parent=nullptr)
GroupingTableModel * getModel() const
void groupingColorChanged(Grouping *grp)
An item in the ModuleModel.
Definition: module_item.h:48
void groupingGateAssigned(Grouping *grp, u32 id) const
void groupingModuleAssigned(Grouping *grp, u32 id) const
void groupingModuleRemoved(Grouping *grp, u32 id) const
void groupingNetAssigned(Grouping *grp, u32 id) const
void groupingNetRemoved(Grouping *grp, u32 id) const
void groupingGateRemoved(Grouping *grp, u32 id) const
int numberSelectedGates() const
void setFocus(ItemType ftype, u32 fid, Subfocus sfoc=Subfocus::None, u32 sfinx=0)
void selectionChanged(void *sender)
bool isNetSelected(u32 id) const
void relaySelectionChanged(void *sender)
int numberSelectedNets() const
int numberSelectedModules() const
void setSelectedGates(const QSet< u32 > &ids)
bool isModuleSelected(u32 id) const
void setSelectedNets(const QSet< u32 > &ids)
void subfocusChanged(void *sender)
void registerSender(void *sender, QString name)
bool isGateSelected(u32 id) const
void setSelectedModules(const QSet< u32 > &ids)
ContentManager * gContentManager
Definition: plugin_gui.cpp:78
GraphContextManager * gGraphContextManager
Definition: plugin_gui.cpp:85
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:83
NetlistRelay * gNetlistRelay
Definition: plugin_gui.cpp:81
n
Definition: test.py:6
quint32 u32
i32 id
void update(const QRectF &rect)
void addItem(QGraphicsItem *item)
void clearSelection()
virtual bool event(QEvent *event) override
QList< QGraphicsItem * > items(Qt::SortOrder order) const const
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
void removeItem(QGraphicsItem *item)
QList< QGraphicsItem * > selectedItems() const const
void selectionChanged()
bool blockSignals(bool block)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QObject * sender() const const
void drawLine(const QLineF &line)
void drawLines(const QLineF *lines, int lineCount)
void drawPoints(const QPointF *points, int pointCount)
QPainter::RenderHints renderHints() const const
void setPen(const QColor &color)
void setRenderHint(QPainter::RenderHint hint, bool on)
void setRenderHints(QPainter::RenderHints hints, bool on)
void setColor(const QColor &color)
void setWidth(int width)
qreal x() const const
qreal y() const const
qreal bottom() const const
qreal left() const const
qreal right() const const
qreal top() const const
QSet::iterator begin()
bool contains(const T &value) const const
QSet::iterator insert(const T &value)
bool isEmpty() const const
int size() const const
RightButton
void append(const T &t)
int size() const const
void append(const T &value)
T * data()
int size() const const
QMap< u32, GraphicsNode::Visuals > mGateVisuals
Definition: graph_shader.h:52
QMap< u32, GraphicsNet::Visuals > mNetVisuals
Definition: graph_shader.h:53
QMap< u32, GraphicsNode::Visuals > mOduleVisuals
Definition: graph_shader.h:51