X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=blobdiff_plain;f=src%2Fgui%2Fwidgets%2FCFGScene.cxx;h=271f30354eaf66aed3ba39f1fc77d7b3ac1c53b5;hp=4e7428d340f93c822c3ed0d48e907a7136e79742;hb=d7319bb99ab84eec0c3608356bada2e5334e3e87;hpb=4bcd18ed3dc3450d014351f5b27d1c7d1596601c diff --git a/src/gui/widgets/CFGScene.cxx b/src/gui/widgets/CFGScene.cxx index 4e7428d..271f303 100644 --- a/src/gui/widgets/CFGScene.cxx +++ b/src/gui/widgets/CFGScene.cxx @@ -30,7 +30,14 @@ void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) { } } -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) { @@ -66,6 +73,13 @@ void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWi 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) { @@ -75,36 +89,52 @@ void CFGScene::spaceWidgets() { 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()); +}