Files
Renderive/YSGraphic_Core/component/Tree/Tree_Model.cpp
T
2026-07-23 18:11:07 +08:00

178 lines
4.6 KiB
C++

#include "Tree_Model.h"
#include <QQueue>
#include <QStack>
#include <iostream>
namespace Psc {
int Node::getDeep() {
int ret = -1;
Node* cur = static_cast<Node*>(this);
while (cur) {
cur = cur->par;
ret++;
}
return ret;
}
Node::Node() {}
int Node::index() {
return par->sons.indexOf(static_cast<Node*>(this));
}
bool Node::is_root() {
return par == nullptr;
}
bool Node::is_leaf() {
return !sons.size();
}
bool Node::is_first() {
return index() == 0;
}
bool Node::is_last() {
return index() == par->sons.size() - 1;
}
Node* Node::previous() {
if (is_first()) return nullptr;
return par->sons[index() - 1];
}
Node* Node::next() {
if (is_last()) return nullptr;
return par->sons[index() + 1];
}
Node* Node::last_child() {
if (is_leaf()) std::cout << "lastChild() error";
return sons[sons.size() - 1];
}
Node* Node::first_child() {
if (is_leaf()) std::cout << "firstChild() error";
return sons[0];
}
Node* Node::root() {
Node * ret = static_cast<Node*>(this);
while (ret->par != nullptr) {
ret = ret->par;
}
return ret;
}
QVector<Node*> Node::deep_traversed() {
QVector<Node*> result;
if (!this) return result;
QStack<Node*> stack;
stack.push(this);
while (!stack.isEmpty()) {
Node * node = stack.pop();
result.append(node);
// 逆序压入子节点,保证从左到右的遍历顺序
for (int i = node->sons.size() - 1; i >= 0; --i) {
stack.push(node->sons[i]);
}
}
return result;
}
QVector<Node*> Node::sequence_traversed() {
QVector<Node*> ret;
QQueue<Node*> que;
Node * that = this;
que.enqueue(that);
while (!que.empty()) {
Node * cur = que.dequeue();
int n = cur->sons.size();
ret.append(cur);
for (int i = 0; i < n; ++i) {
que.enqueue(cur->sons[i]);
}
}
return ret;
}
QVector<Node*> Node::descendants() {
QVector<Node*>&& ret = sequence_traversed();
ret.pop_front();
return ret;
}
QVector<Node*> deep_traversed(const QVector<Node*>& nodes) {
QVector<Node*> result;
if (nodes.isEmpty()) return result;
QStack<Node*> stack;
for (Node * node : nodes)
{
if (node) stack.push_front(node);
}
while (!stack.isEmpty()) {
Node * node = stack.pop();
result.append(node);
// 逆序压入子节点,保证从左到右的遍历顺序
for (int i = node->sons.size() - 1; i >= 0; --i) {
stack.push(node->sons[i]);
}
}
return result;
}
#define ReMain (pos - total_height)
int Tree_Model::height() {
int total_height = 0;
QStack<QPair<Node*, int>> stack;
for (Node * node : roots)
{
if (node) stack.push_front({node, 0});
}
Node * cur{};
int deep{};
while (!stack.isEmpty()) {
auto t = stack.top();
cur = t.first;
deep = t.second;
stack.pop();
if (cur->expand) {
for (int i = cur->sons.size() - 1; i >= 0; --i) {
stack.push({cur->sons[i], deep + 1});
}
}
total_height += cur->height + space;
}
return total_height;
}
Tree_Pos get_pos(int pos, const QVector<Node*>& roots, int space) {
int total_height = 0;
QStack<QPair<Node*, int>> stack;
for (Node * node : roots)
{
if (node) stack.push_front({node, 0});
}
Node * cur{};
int deep{};
while (!stack.isEmpty()) {
auto t = stack.top();
cur = t.first;
deep = t.second;
if (ReMain < cur->height) {
return Tree_Pos{cur, deep, total_height, ReMain, stack};
}
stack.pop();
if (cur->expand) {
for (int i = cur->sons.size() - 1; i >= 0; --i) {
stack.push({cur->sons[i], deep + 1});
}
}
total_height += cur->height + space;
}
return Tree_Pos{cur, deep, total_height, ReMain, stack};
}
void select_node(const QVector<Node*>& roots, int view_y, int length, int space, Node_Call_Back call_back) {
auto ret = get_pos(view_y, roots, space);
QStack<QPair<Node*, int>>& stack = ret.rest;
int cur_inside_y = ret.node_pos;
int cur_inside_end = cur_inside_y + length;
while (!stack.isEmpty()) {
auto [cur, depth] = stack.pop();
if (cur->expand) {
for (int i = cur->sons.size() - 1; i >= 0; --i) {
stack.push({cur->sons[i], depth + 1});
}
}
call_back(cur, depth, cur_inside_y);
cur_inside_y += cur->height + space;
if (cur_inside_y > cur_inside_end) {
break;
}
}
}
}