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; }
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); }
void copyTree(VisualNode* node_t, NodeTree& tree_t, const VisualNode* node_s, const NodeTree& tree_s) { auto& na_t = tree_t.getNA(); const auto& na_s = tree_s.getNA(); stack<VisualNode*> stk_t; stack<const VisualNode*> stk_s; stk_s.push(node_s); stk_t.push(node_t); while (stk_s.size() > 0) { const VisualNode* n = stk_s.top(); stk_s.pop(); VisualNode* next = stk_t.top(); stk_t.pop(); auto kids = n->getNumberOfChildren(); next->setNumberOfChildren(kids, na_t); next->setStatus(n->getStatus()); next->dirtyUp(na_t); for (auto i = 0u; i < kids; ++i) { stk_s.push(n->getChild(na_s, i)); stk_t.push(next->getChild(na_t, i)); } } }
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(); } } }
void TreeCanvas::navLeft(void) { QMutexLocker locker(&mutex); VisualNode* p = currentNode->getParent(*na); if (p != NULL) { int alt = currentNode->getAlternative(*na); if (alt > 0) { VisualNode* n = p->getChild(*na,alt-1); setCurrentNode(n); centerCurrentNode(); } } }