| Index: mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
|
| diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
|
| index 74e88a96bf076d06d9300554ccf12cc258429f97..a0341769e61a24267d6602e7faa5519efcde4492 100644
|
| --- a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
|
| +++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
|
| @@ -6,13 +6,17 @@
|
|
|
| #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
|
| #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
|
| +#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
|
| #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
|
| +#include "mojo/services/public/cpp/view_manager/view.h"
|
| #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
|
|
|
| namespace mojo {
|
| namespace services {
|
| namespace view_manager {
|
|
|
| +namespace {
|
| +
|
| void NotifyViewTreeChangeAtReceiver(
|
| ViewTreeNode* receiver,
|
| const ViewTreeNodeObserver::TreeChangeParams& params) {
|
| @@ -87,6 +91,64 @@ void RemoveChildImpl(ViewTreeNode* child, ViewTreeNode::Children* children) {
|
| }
|
| }
|
|
|
| +class ScopedSetActiveViewNotifier {
|
| + public:
|
| + ScopedSetActiveViewNotifier(ViewTreeNode* node,
|
| + View* old_view,
|
| + View* new_view)
|
| + : node_(node),
|
| + old_view_(old_view),
|
| + new_view_(new_view) {
|
| + FOR_EACH_OBSERVER(
|
| + ViewTreeNodeObserver,
|
| + *ViewTreeNodePrivate(node).observers(),
|
| + OnNodeActiveViewChange(node_,
|
| + old_view_,
|
| + new_view_,
|
| + ViewTreeNodeObserver::DISPOSITION_CHANGING));
|
| + }
|
| + ~ScopedSetActiveViewNotifier() {
|
| + FOR_EACH_OBSERVER(
|
| + ViewTreeNodeObserver,
|
| + *ViewTreeNodePrivate(node_).observers(),
|
| + OnNodeActiveViewChange(node_,
|
| + old_view_,
|
| + new_view_,
|
| + ViewTreeNodeObserver::DISPOSITION_CHANGED));
|
| + }
|
| +
|
| + private:
|
| + ViewTreeNode* node_;
|
| + View* old_view_;
|
| + View* new_view_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ScopedSetActiveViewNotifier);
|
| +};
|
| +
|
| +class ScopedDestructionNotifier {
|
| + public:
|
| + explicit ScopedDestructionNotifier(ViewTreeNode* node)
|
| + : node_(node) {
|
| + FOR_EACH_OBSERVER(
|
| + ViewTreeNodeObserver,
|
| + *ViewTreeNodePrivate(node_).observers(),
|
| + OnNodeDestroy(node_, ViewTreeNodeObserver::DISPOSITION_CHANGING));
|
| + }
|
| + ~ScopedDestructionNotifier() {
|
| + FOR_EACH_OBSERVER(
|
| + ViewTreeNodeObserver,
|
| + *ViewTreeNodePrivate(node_).observers(),
|
| + OnNodeDestroy(node_, ViewTreeNodeObserver::DISPOSITION_CHANGED));
|
| + }
|
| +
|
| + private:
|
| + ViewTreeNode* node_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ScopedDestructionNotifier);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // ViewTreeNode, public:
|
|
|
| @@ -114,18 +176,24 @@ void ViewTreeNode::RemoveObserver(ViewTreeNodeObserver* observer) {
|
| }
|
|
|
| void ViewTreeNode::AddChild(ViewTreeNode* child) {
|
| + if (manager_)
|
| + CHECK_EQ(ViewTreeNodePrivate(child).view_manager(), manager_);
|
| LocalAddChild(child);
|
| if (manager_)
|
| ViewManagerPrivate(manager_).synchronizer()->AddChild(child->id(), id_);
|
| }
|
|
|
| void ViewTreeNode::RemoveChild(ViewTreeNode* child) {
|
| + if (manager_)
|
| + CHECK_EQ(ViewTreeNodePrivate(child).view_manager(), manager_);
|
| LocalRemoveChild(child);
|
| if (manager_)
|
| ViewManagerPrivate(manager_).synchronizer()->RemoveChild(child->id(), id_);
|
| }
|
|
|
| bool ViewTreeNode::Contains(ViewTreeNode* child) const {
|
| + if (manager_)
|
| + CHECK_EQ(ViewTreeNodePrivate(child).view_manager(), manager_);
|
| for (ViewTreeNode* p = child->parent(); p; p = p->parent()) {
|
| if (p == this)
|
| return true;
|
| @@ -146,25 +214,29 @@ ViewTreeNode* ViewTreeNode::GetChildById(TransportNodeId id) {
|
| return NULL;
|
| }
|
|
|
| +void ViewTreeNode::SetActiveView(View* view) {
|
| + if (manager_)
|
| + CHECK_EQ(ViewPrivate(view).view_manager(), manager_);
|
| + LocalSetActiveView(view);
|
| + if (manager_) {
|
| + ViewManagerPrivate(manager_).synchronizer()->SetActiveView(
|
| + id_, active_view_->id());
|
| + }
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // ViewTreeNode, protected:
|
|
|
| ViewTreeNode::ViewTreeNode()
|
| : manager_(NULL),
|
| id_(-1),
|
| - parent_(NULL) {}
|
| + parent_(NULL),
|
| + active_view_(NULL) {}
|
|
|
| ViewTreeNode::~ViewTreeNode() {
|
| - FOR_EACH_OBSERVER(
|
| - ViewTreeNodeObserver,
|
| - observers_,
|
| - OnNodeDestroy(this, ViewTreeNodeObserver::DISPOSITION_CHANGING));
|
| + ScopedDestructionNotifier notifier(this);
|
| if (parent_)
|
| parent_->LocalRemoveChild(this);
|
| - FOR_EACH_OBSERVER(
|
| - ViewTreeNodeObserver,
|
| - observers_,
|
| - OnNodeDestroy(this, ViewTreeNodeObserver::DISPOSITION_CHANGED));
|
| if (manager_)
|
| ViewManagerPrivate(manager_).RemoveNode(id_);
|
| }
|
| @@ -175,7 +247,8 @@ ViewTreeNode::~ViewTreeNode() {
|
| ViewTreeNode::ViewTreeNode(ViewManager* manager)
|
| : manager_(manager),
|
| id_(ViewManagerPrivate(manager).synchronizer()->CreateViewTreeNode()),
|
| - parent_(NULL) {}
|
| + parent_(NULL),
|
| + active_view_(NULL) {}
|
|
|
| void ViewTreeNode::LocalDestroy() {
|
| delete this;
|
| @@ -195,6 +268,15 @@ void ViewTreeNode::LocalRemoveChild(ViewTreeNode* child) {
|
| RemoveChildImpl(child, &children_);
|
| }
|
|
|
| +void ViewTreeNode::LocalSetActiveView(View* view) {
|
| + ScopedSetActiveViewNotifier notifier(this, active_view_, view);
|
| + if (active_view_)
|
| + ViewPrivate(active_view_).set_node(NULL);
|
| + active_view_ = view;
|
| + if (active_view_)
|
| + ViewPrivate(active_view_).set_node(this);
|
| +}
|
| +
|
| } // namespace view_manager
|
| } // namespace services
|
| } // namespace mojo
|
|
|