}
}
+/* 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);
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, -1);
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, -1);
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());
}
}
}
+
+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());
+}