}
}
-void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to, int8_t side) {
+/* Forward edges: Forward (downward) edges are just drawn straight
+ * down and then to the right side
+ * Backward edges: Consider the smallest rectangle that contains both,
+ * source and destination block. Draw the edge along
+ * the shorter side of that rectangle
+ */
+void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to,
+ int8_t side) {
QPointF from_p = from->getExits()[side+1] + QPointF(0, 20);
QPointF to_p = to->getEntry() - QPointF(0, 20);
if ((to_p - from_p).y() > 0) {
void CFGScene::spaceWidgets() {
bool changed = false;
+
+ /* While some BasicBlockWidget overlaps with a direct predecessor,
+ * move that widget down one step. Move each widget at most once
+ * per iteration so that widgets with severall incoming edges
+ * don't outrun these with less -- preserving order by address
+ * where appropriate.
+ */
do {
changed = false;
for (BasicBlockWidget * widget : widgets) {
if (NULL != next[0]
&& (next[0]->getEntry() - widget->getEntry()).y() > 0
&& (next[0]->getEntry() - out).y() < 50) {
- next[0]->moveBy(0, 1);
+ widget->moveBy(0, -3);
changed = true;
- }
- if (NULL != next[1]
+ } else if (NULL != next[1]
&& (next[1]->getEntry() - widget->getEntry()).y() > 0
&& (next[1]->getEntry() - out).y() < 50) {
- next[1]->moveBy(0, 1);
+ widget->moveBy(0, -3);
changed = true;
}
}
} while (changed);
+ /* If there are still BasicBlockWidgets overlapping (BasicBlocks
+ * that don't have a direct edge) spread them sideways.
+ */
for (BasicBlockWidget * widget : widgets) {
QRectF relevantRect = widget->boundingRect();
relevantRect.moveTo(widget->scenePos());
relevantRect.adjust(-20, -20, 20, 20);
for (QGraphicsItem * item : items(relevantRect)) {
- if (item == widget) continue;
- if (std::find(widgets.begin(), widgets.end(), item) == widgets.end()) continue;
+ if (item == widget)
+ continue;
+ if (std::find(widgets.begin(), widgets.end(), item) == widgets.end())
+ continue;
QRectF itemrect = item->boundingRect();
itemrect.moveTo(item->scenePos());
while (relevantRect.intersects(itemrect)) {
if (widget->scenePos().x() > item->scenePos().x()) {
- widget->moveBy(1, 0);
+ widget->moveBy(3, 0);
relevantRect.moveTo(widget->scenePos());
} else {
- item->moveBy(1, 0);
+ item->moveBy(3, 0);
itemrect.moveTo(item->scenePos());
}
}
}
}
}
+
+void CFGScene::highlightBlock(BasicBlockWidget* block) {
+ QGraphicsView* view = *(views().begin());
+ if (highlightedBlock) {
+ highlightedBlock->setColor(highlightedBlock->defaultColor);
+ update(highlightedBlock->boundingRect());
+ }
+ highlightedBlock = block;
+ view->centerOn(block);
+ block->setColor(block->highlightColor);
+ update(block->boundingRect());
+}