aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-10 22:06:50 +0800
committercrupest <crupest@outlook.com>2022-02-10 22:06:50 +0800
commitf65d0502a9f0fc44be0dd79a5f3f31697bb3aad0 (patch)
treec24a3a25284c94d52af5264dda996bfdd311857b /src
parenta236a2a146bfcc4eb5c93a85cd99ac330e83a7f5 (diff)
downloadcru-f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0.tar.gz
cru-f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0.tar.bz2
cru-f65d0502a9f0fc44be0dd79a5f3f31697bb3aad0.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/ui/controls/TreeView.cpp87
-rw-r--r--src/ui/render/TreeRenderObject.cpp12
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();
}