diff options
author | crupest <crupest@outlook.com> | 2022-02-10 22:06:50 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-02-10 22:06:50 +0800 |
commit | f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0 (patch) | |
tree | c24a3a25284c94d52af5264dda996bfdd311857b /src | |
parent | a236a2a146bfcc4eb5c93a85cd99ac330e83a7f5 (diff) | |
download | cru-f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0.tar.gz cru-f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0.tar.bz2 cru-f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0.zip |
...
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/controls/TreeView.cpp | 87 | ||||
-rw-r--r-- | src/ui/render/TreeRenderObject.cpp | 12 |
2 files changed, 99 insertions, 0 deletions
diff --git a/src/ui/controls/TreeView.cpp b/src/ui/controls/TreeView.cpp index e69de29b..659aef00 100644 --- a/src/ui/controls/TreeView.cpp +++ b/src/ui/controls/TreeView.cpp @@ -0,0 +1,87 @@ +#include "cru/ui/controls/TreeView.h" + +namespace cru::ui::controls { +TreeViewItem::TreeViewItem(TreeView* tree_view, TreeViewItem* parent, + render::TreeRenderObjectItem* render_object_item) + : tree_view_(tree_view), + parent_(parent), + render_object_item_(render_object_item) {} + +TreeViewItem::~TreeViewItem() { + if (control_) { + control_->SetParent(nullptr); + } + + for (auto item : children_) { + delete item; + } +} + +Index TreeViewItem::IndexOf(TreeViewItem* item) const { + auto result = std::find(children_.begin(), children_.end(), item); + if (result == children_.end()) { + return -1; + } + return result - children_.begin(); +} + +void TreeViewItem::RemoveFromParent() { + if (parent_ == nullptr) return; + parent_->RemoveItem(parent_->IndexOf(this)); +} + +TreeViewItem* TreeViewItem::AddItem(Index position) { + auto render_object_item = render_object_item_->AddItem(position); + auto item = new TreeViewItem(tree_view_, this, render_object_item); + children_.insert(children_.begin() + position, item); + return item; +} + +void TreeViewItem::RemoveItem(Index position) { + Expects(position >= 0 && position < children_.size()); + delete children_[position]; + children_.erase(children_.begin() + position); + render_object_item_->RemoveItem(position); +} + +void TreeViewItem::SetControl(Control* control) { + if (control_) { + control_->SetParent(nullptr); + render_object_item_->SetRenderObject(nullptr); + } + control_ = control; + if (control) { + control->SetParent(tree_view_); + render_object_item_->SetRenderObject(control->GetRenderObject()); + } +} + +void TreeViewItem::TraverseDescendants( + std::function<void(TreeViewItem*)> callback) { + callback(this); + for (auto item : children_) { + TraverseDescendants(callback); + } +} + +TreeView::TreeView() + : root_item_(this, nullptr, render_object_.GetRootItem()) {} + +TreeView::~TreeView() {} + +void TreeView::ForEachChild(const std::function<void(Control*)>& predicate) { + root_item_.TraverseDescendants([&predicate](TreeViewItem* item) { + if (auto control = item->GetControl()) { + predicate(control); + } + }); +} + +void TreeView::RemoveChild(Control* control) { + root_item_.TraverseDescendants([&control](TreeViewItem* item) { + if (item->GetControl() == control) { + item->SetControl(nullptr); + } + }); +} +} // namespace cru::ui::controls diff --git a/src/ui/render/TreeRenderObject.cpp b/src/ui/render/TreeRenderObject.cpp index 9bf74535..8bf662e4 100644 --- a/src/ui/render/TreeRenderObject.cpp +++ b/src/ui/render/TreeRenderObject.cpp @@ -9,6 +9,11 @@ TreeRenderObjectItem::TreeRenderObjectItem(TreeRenderObject* tree_render_object, : tree_render_object_(tree_render_object), parent_(parent) {} TreeRenderObjectItem::~TreeRenderObjectItem() { + if (render_object_) { + render_object_->SetParent(nullptr); + render_object_ = nullptr; + } + for (auto child : children_) { delete child; } @@ -16,7 +21,14 @@ TreeRenderObjectItem::~TreeRenderObjectItem() { void TreeRenderObjectItem::SetRenderObject(RenderObject* render_object) { if (render_object == render_object_) return; + if (render_object_) { + render_object_->SetParent(nullptr); + } render_object_ = render_object; + if (render_object) { + assert(render_object->GetParent() == nullptr); + render_object->SetParent(tree_render_object_); + } tree_render_object_->InvalidateLayout(); } |