2020-08-04 12:31:33 +08:00
|
|
|
#include "GTreeNode.h"
|
|
|
|
#include "GComponent.h"
|
|
|
|
#include "GTree.h"
|
|
|
|
|
|
|
|
NS_FGUI_BEGIN
|
2022-07-11 17:50:21 +08:00
|
|
|
USING_NS_AX;
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
GTreeNode* GTreeNode::create(bool isFolder, const std::string& resURL)
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
GTreeNode* pRet = new GTreeNode();
|
2020-08-04 12:31:33 +08:00
|
|
|
|
2021-12-08 00:11:53 +08:00
|
|
|
if (pRet->init(isFolder, resURL))
|
2020-08-04 12:31:33 +08:00
|
|
|
{
|
|
|
|
pRet->autorelease();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(pRet);
|
2020-08-04 12:31:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return pRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode::GTreeNode()
|
|
|
|
: _tree(nullptr),
|
|
|
|
_parent(nullptr),
|
|
|
|
_cell(nullptr),
|
|
|
|
_level(0),
|
|
|
|
_expanded(false),
|
|
|
|
_isFolder(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode::~GTreeNode()
|
|
|
|
{
|
|
|
|
for (auto& it : _children)
|
|
|
|
it->_parent = nullptr;
|
|
|
|
|
|
|
|
_children.clear();
|
|
|
|
|
|
|
|
if (_parent)
|
|
|
|
_parent->removeChild(this);
|
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_RELEASE(_cell);
|
2020-08-04 12:31:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GTreeNode::init(bool isFolder, const std::string& resURL)
|
|
|
|
{
|
|
|
|
_isFolder = isFolder;
|
|
|
|
_resURL = resURL;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::setExpaned(bool value)
|
|
|
|
{
|
|
|
|
if (!_isFolder)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (_expanded != value)
|
|
|
|
{
|
|
|
|
_expanded = value;
|
|
|
|
if (_tree != nullptr)
|
|
|
|
{
|
|
|
|
if (_expanded)
|
|
|
|
_tree->afterExpanded(this);
|
|
|
|
else
|
|
|
|
_tree->afterCollapsed(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string& GTreeNode::getText() const
|
|
|
|
{
|
|
|
|
if (_cell != nullptr)
|
|
|
|
return _cell->getText();
|
|
|
|
else
|
|
|
|
return STD_STRING_EMPTY;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::setText(const std::string& value)
|
|
|
|
{
|
|
|
|
if (_cell != nullptr)
|
|
|
|
return _cell->setText(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string& GTreeNode::getIcon() const
|
|
|
|
{
|
|
|
|
if (_cell != nullptr)
|
|
|
|
return _cell->getIcon();
|
|
|
|
else
|
|
|
|
return STD_STRING_EMPTY;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::setIcon(const std::string& value)
|
|
|
|
{
|
|
|
|
if (_cell != nullptr)
|
|
|
|
return _cell->setIcon(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode* GTreeNode::addChild(GTreeNode* child)
|
|
|
|
{
|
|
|
|
addChildAt(child, (int)_children.size());
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode* GTreeNode::addChildAt(GTreeNode* child, int index)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(child != nullptr, "Argument must be non-nil");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
if (child->_parent == this)
|
|
|
|
{
|
|
|
|
setChildIndex(child, index);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
child->retain();
|
|
|
|
if (child->_parent != nullptr)
|
|
|
|
child->_parent->removeChild(child);
|
|
|
|
child->_parent = this;
|
|
|
|
|
|
|
|
int cnt = (int)_children.size();
|
|
|
|
if (index == cnt)
|
|
|
|
_children.pushBack(child);
|
|
|
|
else
|
|
|
|
_children.insert(index, child);
|
|
|
|
child->release();
|
|
|
|
|
|
|
|
child->_level = _level + 1;
|
|
|
|
child->setTree(_tree);
|
|
|
|
if ((_tree != nullptr && this == _tree->getRootNode()) || (_cell != nullptr && _cell->getParent() != nullptr && _expanded))
|
|
|
|
_tree->afterInserted(child);
|
|
|
|
}
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::removeChild(GTreeNode* child)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(child != nullptr, "Argument must be non-nil");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
int childIndex = (int)_children.getIndex(child);
|
|
|
|
if (childIndex != -1)
|
|
|
|
removeChildAt(childIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::removeChildAt(int index)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(index >= 0 && index < _children.size(), "Invalid child index");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
GTreeNode* child = _children.at(index);
|
|
|
|
child->_parent = nullptr;
|
|
|
|
|
|
|
|
if (_tree != nullptr)
|
|
|
|
{
|
|
|
|
child->setTree(nullptr);
|
|
|
|
_tree->afterRemoved(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
_children.erase(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::removeChildren(int beginIndex, int endIndex)
|
|
|
|
{
|
|
|
|
if (endIndex < 0 || endIndex >= _children.size())
|
|
|
|
endIndex = (int)_children.size() - 1;
|
|
|
|
|
|
|
|
for (int i = beginIndex; i <= endIndex; ++i)
|
|
|
|
removeChildAt(beginIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode* GTreeNode::getChildAt(int index) const
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(index >= 0 && index < _children.size(), "Invalid child index");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
return _children.at(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode* GTreeNode::getPrevSibling() const
|
|
|
|
{
|
|
|
|
if (_parent == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
ssize_t i = _parent->_children.getIndex((GTreeNode*)this);
|
|
|
|
if (i <= 0)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return _parent->_children.at(i - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
GTreeNode* GTreeNode::getNextSibling() const
|
|
|
|
{
|
|
|
|
if (_parent == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
ssize_t i = _parent->_children.getIndex((GTreeNode*)this);
|
|
|
|
if (i < 0 || i >= _parent->_children.size() - 1)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return _parent->_children.at(i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int GTreeNode::getChildIndex(const GTreeNode* child) const
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(child != nullptr, "Argument must be non-nil");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
return (int)_children.getIndex((GTreeNode*)child);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::setChildIndex(GTreeNode* child, int index)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(child != nullptr, "Argument must be non-nil");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
int oldIndex = (int)_children.getIndex(child);
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(oldIndex != -1, "Not a child of this container");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
moveChild(child, oldIndex, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
int GTreeNode::setChildIndexBefore(GTreeNode* child, int index)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(child != nullptr, "Argument must be non-nil");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
int oldIndex = (int)_children.getIndex(child);
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(oldIndex != -1, "Not a child of this container");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
if (oldIndex < index)
|
|
|
|
return moveChild(child, oldIndex, index - 1);
|
|
|
|
else
|
|
|
|
return moveChild(child, oldIndex, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
int GTreeNode::moveChild(GTreeNode* child, int oldIndex, int index)
|
|
|
|
{
|
|
|
|
int cnt = (int)_children.size();
|
|
|
|
if (index > cnt)
|
|
|
|
index = cnt;
|
|
|
|
|
|
|
|
if (oldIndex == index)
|
|
|
|
return oldIndex;
|
|
|
|
|
|
|
|
child->retain();
|
|
|
|
_children.erase(oldIndex);
|
|
|
|
if (index >= cnt)
|
|
|
|
_children.pushBack(child);
|
|
|
|
else
|
|
|
|
_children.insert(index, child);
|
|
|
|
child->release();
|
|
|
|
if ((_tree != nullptr && this == _tree->getRootNode()) || (_cell != nullptr && _cell->getParent() != nullptr && _expanded))
|
|
|
|
_tree->afterMoved(child);
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::swapChildren(GTreeNode* child1, GTreeNode* child2)
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(child1 != nullptr, "Argument1 must be non-nil");
|
|
|
|
AXASSERT(child2 != nullptr, "Argument2 must be non-nil");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
int index1 = (int)_children.getIndex(child1);
|
|
|
|
int index2 = (int)_children.getIndex(child2);
|
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(index1 != -1, "Not a child of this container");
|
|
|
|
AXASSERT(index2 != -1, "Not a child of this container");
|
2020-08-04 12:31:33 +08:00
|
|
|
|
|
|
|
swapChildrenAt(index1, index2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::swapChildrenAt(int index1, int index2)
|
|
|
|
{
|
|
|
|
GTreeNode* child1 = _children.at(index1);
|
|
|
|
GTreeNode* child2 = _children.at(index2);
|
|
|
|
|
|
|
|
setChildIndex(child1, index2);
|
|
|
|
setChildIndex(child2, index1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int GTreeNode::numChildren() const
|
|
|
|
{
|
|
|
|
return (int)_children.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GTreeNode::setTree(GTree* value)
|
|
|
|
{
|
|
|
|
_tree = value;
|
|
|
|
if (_tree != nullptr && _tree->treeNodeWillExpand != nullptr && _expanded)
|
|
|
|
_tree->treeNodeWillExpand(this, true);
|
|
|
|
|
|
|
|
if (_isFolder)
|
|
|
|
{
|
|
|
|
for (auto& child : _children)
|
|
|
|
{
|
|
|
|
child->_level = _level + 1;
|
|
|
|
child->setTree(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_FGUI_END
|