1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/services/public/cpp/view_manager/view_tree_node.h"
7 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
8 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
9 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
10 #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
14 namespace view_manager {
16 void NotifyViewTreeChangeAtReceiver(
17 ViewTreeNode* receiver,
18 const ViewTreeNodeObserver::TreeChangeParams& params) {
19 ViewTreeNodeObserver::TreeChangeParams local_params = params;
20 local_params.receiver = receiver;
21 FOR_EACH_OBSERVER(ViewTreeNodeObserver,
22 *ViewTreeNodePrivate(receiver).observers(),
23 OnTreeChange(local_params));
26 void NotifyViewTreeChangeUp(
27 ViewTreeNode* start_at,
28 const ViewTreeNodeObserver::TreeChangeParams& params) {
29 for (ViewTreeNode* current = start_at; current; current = current->parent())
30 NotifyViewTreeChangeAtReceiver(current, params);
33 void NotifyViewTreeChangeDown(
34 ViewTreeNode* start_at,
35 const ViewTreeNodeObserver::TreeChangeParams& params) {
36 NotifyViewTreeChangeAtReceiver(start_at, params);
37 ViewTreeNode::Children::const_iterator it = start_at->children().begin();
38 for (; it != start_at->children().end(); ++it)
39 NotifyViewTreeChangeDown(*it, params);
42 void NotifyViewTreeChange(
43 const ViewTreeNodeObserver::TreeChangeParams& params) {
44 NotifyViewTreeChangeDown(params.target, params);
45 switch (params.phase) {
46 case ViewTreeNodeObserver::DISPOSITION_CHANGING:
47 if (params.old_parent)
48 NotifyViewTreeChangeUp(params.old_parent, params);
50 case ViewTreeNodeObserver::DISPOSITION_CHANGED:
51 if (params.new_parent)
52 NotifyViewTreeChangeUp(params.new_parent, params);
60 class ScopedTreeNotifier {
62 ScopedTreeNotifier(ViewTreeNode* target,
63 ViewTreeNode* old_parent,
64 ViewTreeNode* new_parent) {
65 params_.target = target;
66 params_.old_parent = old_parent;
67 params_.new_parent = new_parent;
68 NotifyViewTreeChange(params_);
70 ~ScopedTreeNotifier() {
71 params_.phase = ViewTreeNodeObserver::DISPOSITION_CHANGED;
72 NotifyViewTreeChange(params_);
76 ViewTreeNodeObserver::TreeChangeParams params_;
78 DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier);
81 void RemoveChildImpl(ViewTreeNode* child, ViewTreeNode::Children* children) {
82 ViewTreeNode::Children::iterator it =
83 std::find(children->begin(), children->end(), child);
84 if (it != children->end()) {
86 ViewTreeNodePrivate(child).ClearParent();
90 ////////////////////////////////////////////////////////////////////////////////
91 // ViewTreeNode, public:
94 ViewTreeNode* ViewTreeNode::Create(ViewManager* view_manager) {
95 ViewTreeNode* node = new ViewTreeNode(view_manager);
96 ViewManagerPrivate(view_manager).AddNode(node->id(), node);
100 void ViewTreeNode::Destroy() {
102 ViewManagerPrivate(manager_).synchronizer()->DestroyViewTreeNode(id_);
103 while (!children_.empty())
104 children_.front()->Destroy();
108 void ViewTreeNode::AddObserver(ViewTreeNodeObserver* observer) {
109 observers_.AddObserver(observer);
112 void ViewTreeNode::RemoveObserver(ViewTreeNodeObserver* observer) {
113 observers_.RemoveObserver(observer);
116 void ViewTreeNode::AddChild(ViewTreeNode* child) {
117 LocalAddChild(child);
119 ViewManagerPrivate(manager_).synchronizer()->AddChild(child->id(), id_);
122 void ViewTreeNode::RemoveChild(ViewTreeNode* child) {
123 LocalRemoveChild(child);
125 ViewManagerPrivate(manager_).synchronizer()->RemoveChild(child->id(), id_);
128 bool ViewTreeNode::Contains(ViewTreeNode* child) const {
129 for (ViewTreeNode* p = child->parent(); p; p = p->parent()) {
136 ViewTreeNode* ViewTreeNode::GetChildById(TransportNodeId id) {
139 // TODO(beng): this could be improved depending on how we decide to own nodes.
140 Children::const_iterator it = children_.begin();
141 for (; it != children_.end(); ++it) {
142 ViewTreeNode* node = (*it)->GetChildById(id);
149 ////////////////////////////////////////////////////////////////////////////////
150 // ViewTreeNode, protected:
152 ViewTreeNode::ViewTreeNode()
157 ViewTreeNode::~ViewTreeNode() {
159 ViewTreeNodeObserver,
161 OnNodeDestroy(this, ViewTreeNodeObserver::DISPOSITION_CHANGING));
163 parent_->LocalRemoveChild(this);
165 ViewTreeNodeObserver,
167 OnNodeDestroy(this, ViewTreeNodeObserver::DISPOSITION_CHANGED));
169 ViewManagerPrivate(manager_).RemoveNode(id_);
172 ////////////////////////////////////////////////////////////////////////////////
173 // ViewTreeNode, private:
175 ViewTreeNode::ViewTreeNode(ViewManager* manager)
177 id_(ViewManagerPrivate(manager).synchronizer()->CreateViewTreeNode()),
180 void ViewTreeNode::LocalDestroy() {
184 void ViewTreeNode::LocalAddChild(ViewTreeNode* child) {
185 ScopedTreeNotifier notifier(child, child->parent(), this);
187 RemoveChildImpl(child, &child->parent_->children_);
188 children_.push_back(child);
189 child->parent_ = this;
192 void ViewTreeNode::LocalRemoveChild(ViewTreeNode* child) {
193 DCHECK_EQ(this, child->parent());
194 ScopedTreeNotifier(child, this, NULL);
195 RemoveChildImpl(child, &children_);
198 } // namespace view_manager
199 } // namespace services