void IcicleTreeCanvas::dfsVisible(VisualNode& root, int idx, int curx, int cury, const int xoff, const int width, const int yoff, const int depth) { if (cury > depth) return; const int kids = root.getNumberOfChildren(); auto& na = node_tree.getNA(); int nextxL = curx; int nextxR; for (int i = 0; i < kids; i++) { if (nextxL > xoff + width) break; int kidIdx = root.getChild(i); if (statistic[kidIdx].height >= compressLevel) { VisualNode& kid = *na[kidIdx]; nextxR = nextxL + statistic[kidIdx].leafCnt; if (nextxR >= xoff) dfsVisible(kid, kidIdx, nextxL, cury+1, xoff, width, yoff, depth); nextxL = nextxR; } } if (cury >= yoff && cury <= yoff + depth) { int rectAbsXL = std::max(curx, xoff); int rectAbsXR = std::min(curx + statistic[idx].leafCnt, xoff + width); int rectAbsY = cury; int height = icicle_image_.pixel_height(); int x = rectAbsXL - xoff; int y = rectAbsY - yoff; int width = rectAbsXR - rectAbsXL; icicle_rects_.push_back(IcicleRect{x, y, width, height, root}); } }
bool IcicleTreeCanvas::compressInit(VisualNode& root, int idx, int absX) { const int kids = root.getNumberOfChildren(); auto& na = node_tree.getNA(); bool hasSolved = false; int leafCnt = 0, expectSolvedCnt = 0, actualSolvedCnt = 0; statistic[idx].ns = root.getStatus(); statistic[idx].absX = absX; for (int i = 0; i < kids; i++) { int kidIdx = root.getChild(i); VisualNode& kid = *na[kidIdx]; if (kid.hasSolvedChildren()) expectSolvedCnt++; if (statistic[kidIdx].height >= compressLevel) { bool kidRes = compressInit(kid, kidIdx, absX + leafCnt); hasSolved |= kidRes; leafCnt += statistic[kidIdx].leafCnt; if (kidRes) actualSolvedCnt++; } } statistic[idx].leafCnt = leafCnt? leafCnt: 1; if (kids && statistic[idx].height == compressLevel) statistic[idx].ns = root.hasSolvedChildren()? SOLVED: FAILED; else if (expectSolvedCnt > actualSolvedCnt) statistic[idx].ns = SOLVED; return hasSolved | (statistic[idx].ns == SOLVED); }
forceinline void LayoutCursor::processCurrentNode() { VisualNode* currentNode = node(); if (currentNode->isDirty()) { if (currentNode->isHidden()) { // do nothing } else if (currentNode->getNumberOfChildren() < 1) { currentNode->setShape(Shape::leaf); } else { currentNode->computeShape(na,startNode()); } currentNode->setDirty(false); } if (currentNode->getNumberOfChildren() >= 1) currentNode->setChildrenLayoutDone(true); }
void TreeCanvas::navRight(void) { QMutexLocker locker(&mutex); VisualNode* p = currentNode->getParent(*na); if (p != NULL) { unsigned int alt = currentNode->getAlternative(*na); if (alt + 1 < p->getNumberOfChildren()) { VisualNode* n = p->getChild(*na,alt+1); setCurrentNode(n); centerCurrentNode(); } } }
IcicleNodeStatistic IcicleTreeCanvas::initTreeStatistic(VisualNode& root, int idx, int absX) { const int kids = root.getNumberOfChildren(); auto& na = node_tree.getNA(); IcicleNodeStatistic cntRoot = IcicleNodeStatistic{kids?0: 1, 0, absX, root.getStatus()}; for (int i=0; i < kids; i++) { VisualNode& kid = *root.getChild(na, i); int kidIdx = root.getChild(i); IcicleNodeStatistic cntKid = initTreeStatistic(kid, kidIdx, absX + cntRoot.leafCnt); cntRoot.leafCnt += cntKid.leafCnt; cntRoot.height = std::max(cntRoot.height, cntKid.height + 1); } statistic[idx] = cntRoot; return cntRoot; }
bool compareSubtrees(const NodeTree& nt, const VisualNode& root1, const VisualNode& root2) { // compare roots bool equal = compareNodes(root1, root2); if (!equal) return false; // if nodes have children, compare them recursively: for (auto i = 0u; i < root1.getNumberOfChildren(); ++i) { auto new_root_1 = nt.getChild(root1, i); auto new_root_2 = nt.getChild(root2, i); bool equal = compareSubtrees(nt, *new_root_1, *new_root_2); if (!equal) return false; } return true; }
void Gist::updateActions(VisualNode* n, bool finished) { // qDebug() << "!! updateActions triggered"; if (!finished) { navUp->setEnabled(false); navDown->setEnabled(false); navLeft->setEnabled(false); navRight->setEnabled(false); navRoot->setEnabled(false); unhideAll->setEnabled(false); } else { navRoot->setEnabled(true); if (n->getNumberOfChildren() > 0) { navDown->setEnabled(true); } else { navDown->setEnabled(false); } VisualNode* p = n->getParent(execution->getNA()); if (p == nullptr) { navUp->setEnabled(false); navRight->setEnabled(false); navLeft->setEnabled(false); } else { navUp->setEnabled(true); unsigned int alt = n->getAlternative(execution->getNA()); navRight->setEnabled(alt + 1 < p->getNumberOfChildren()); navLeft->setEnabled(alt > 0); } if (n->getNumberOfChildren() > 0) { unhideAll->setEnabled(true); } else { unhideAll->setEnabled(false); } } }