Index: mojo/services/view_manager/server_view.cc |
diff --git a/mojo/services/view_manager/server_view.cc b/mojo/services/view_manager/server_view.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6459f9adcd84c72cf5fe4ad3d323a60e9b215f96 |
--- /dev/null |
+++ b/mojo/services/view_manager/server_view.cc |
@@ -0,0 +1,206 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "mojo/services/view_manager/server_view.h" |
+ |
+#include <inttypes.h> |
+ |
+#include "base/strings/stringprintf.h" |
+#include "mojo/services/view_manager/server_view_delegate.h" |
+ |
+namespace view_manager { |
+ |
+ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id) |
+ : delegate_(delegate), |
+ id_(id), |
+ parent_(nullptr), |
+ visible_(false), |
+ opacity_(1) { |
+ DCHECK(delegate); // Must provide a delegate. |
+} |
+ |
+ServerView::~ServerView() { |
+ delegate_->OnWillDestroyView(this); |
+ |
+ while (!children_.empty()) |
+ children_.front()->parent()->Remove(children_.front()); |
+ |
+ if (parent_) |
+ parent_->Remove(this); |
+ |
+ delegate_->OnViewDestroyed(this); |
+} |
+ |
+void ServerView::Add(ServerView* child) { |
+ // We assume validation checks happened already. |
+ DCHECK(child); |
+ DCHECK(child != this); |
+ DCHECK(!child->Contains(this)); |
+ if (child->parent() == this) { |
+ if (children_.size() == 1) |
+ return; // Already in the right position. |
+ Reorder(child, children_.back(), mojo::ORDER_DIRECTION_ABOVE); |
+ return; |
+ } |
+ |
+ ServerView* old_parent = child->parent(); |
+ child->delegate_->OnWillChangeViewHierarchy(child, this, old_parent); |
+ if (child->parent()) |
+ child->parent()->RemoveImpl(child); |
+ |
+ child->parent_ = this; |
+ children_.push_back(child); |
+ child->delegate_->OnViewHierarchyChanged(child, this, old_parent); |
+} |
+ |
+void ServerView::Remove(ServerView* child) { |
+ // We assume validation checks happened else where. |
+ DCHECK(child); |
+ DCHECK(child != this); |
+ DCHECK(child->parent() == this); |
+ |
+ child->delegate_->OnWillChangeViewHierarchy(child, NULL, this); |
+ RemoveImpl(child); |
+ child->delegate_->OnViewHierarchyChanged(child, NULL, this); |
+} |
+ |
+void ServerView::Reorder(ServerView* child, |
+ ServerView* relative, |
+ mojo::OrderDirection direction) { |
+ // We assume validation checks happened else where. |
+ DCHECK(child); |
+ DCHECK(child->parent() == this); |
+ DCHECK_GT(children_.size(), 1u); |
+ children_.erase(std::find(children_.begin(), children_.end(), child)); |
+ Views::iterator i = std::find(children_.begin(), children_.end(), relative); |
+ if (direction == mojo::ORDER_DIRECTION_ABOVE) { |
+ DCHECK(i != children_.end()); |
+ children_.insert(++i, child); |
+ } else if (direction == mojo::ORDER_DIRECTION_BELOW) { |
+ DCHECK(i != children_.end()); |
+ children_.insert(i, child); |
+ } |
+ delegate_->OnViewReordered(this, relative, direction); |
+} |
+ |
+void ServerView::SetBounds(const gfx::Rect& bounds) { |
+ if (bounds_ == bounds) |
+ return; |
+ |
+ const gfx::Rect old_bounds = bounds_; |
+ bounds_ = bounds; |
+ delegate_->OnViewBoundsChanged(this, old_bounds, bounds); |
+} |
+ |
+const ServerView* ServerView::GetRoot() const { |
+ const ServerView* view = this; |
+ while (view && view->parent()) |
+ view = view->parent(); |
+ return view; |
+} |
+ |
+std::vector<const ServerView*> ServerView::GetChildren() const { |
+ std::vector<const ServerView*> children; |
+ children.reserve(children_.size()); |
+ for (size_t i = 0; i < children_.size(); ++i) |
+ children.push_back(children_[i]); |
+ return children; |
+} |
+ |
+std::vector<ServerView*> ServerView::GetChildren() { |
+ // TODO(sky): rename to children() and fix return type. |
+ return children_; |
+} |
+ |
+bool ServerView::Contains(const ServerView* view) const { |
+ for (const ServerView* parent = view; parent; parent = parent->parent_) { |
+ if (parent == this) |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+void ServerView::SetVisible(bool value) { |
+ if (visible_ == value) |
+ return; |
+ |
+ delegate_->OnWillChangeViewVisibility(this); |
+ visible_ = value; |
+} |
+ |
+void ServerView::SetOpacity(float value) { |
+ if (value == opacity_) |
+ return; |
+ opacity_ = value; |
+ delegate_->OnScheduleViewPaint(this); |
+} |
+ |
+void ServerView::SetTransform(const gfx::Transform& transform) { |
+ if (transform_ == transform) |
+ return; |
+ |
+ transform_ = transform; |
+ delegate_->OnScheduleViewPaint(this); |
+} |
+ |
+void ServerView::SetProperty(const std::string& name, |
+ const std::vector<uint8_t>* value) { |
+ auto it = properties_.find(name); |
+ if (it != properties_.end()) { |
+ if (value && it->second == *value) |
+ return; |
+ } else if (!value) { |
+ // This property isn't set in |properties_| and |value| is NULL, so there's |
+ // no change. |
+ return; |
+ } |
+ |
+ if (value) { |
+ properties_[name] = *value; |
+ } else if (it != properties_.end()) { |
+ properties_.erase(it); |
+ } |
+ |
+ delegate_->OnViewSharedPropertyChanged(this, name, value); |
+} |
+ |
+bool ServerView::IsDrawn(const ServerView* root) const { |
+ if (!root->visible_) |
+ return false; |
+ const ServerView* view = this; |
+ while (view && view != root && view->visible_) |
+ view = view->parent_; |
+ return view == root; |
+} |
+ |
+void ServerView::SetSurfaceId(cc::SurfaceId surface_id) { |
+ surface_id_ = surface_id; |
+ delegate_->OnViewSurfaceIdChanged(this); |
+} |
+ |
+#if !defined(NDEBUG) |
+std::string ServerView::GetDebugWindowHierarchy() const { |
+ std::string result; |
+ BuildDebugInfo(std::string(), &result); |
+ return result; |
+} |
+ |
+void ServerView::BuildDebugInfo(const std::string& depth, |
+ std::string* result) const { |
+ *result += base::StringPrintf( |
+ "%sid=%d,%d visible=%s bounds=%d,%d %dx%d surface_id=%" PRIu64 "\n", |
+ depth.c_str(), static_cast<int>(id_.connection_id), |
+ static_cast<int>(id_.view_id), visible_ ? "true" : "false", bounds_.x(), |
+ bounds_.y(), bounds_.width(), bounds_.height(), surface_id_.id); |
+ for (const ServerView* child : children_) |
+ child->BuildDebugInfo(depth + " ", result); |
+} |
+#endif |
+ |
+void ServerView::RemoveImpl(ServerView* view) { |
+ view->parent_ = NULL; |
+ children_.erase(std::find(children_.begin(), children_.end(), view)); |
+} |
+ |
+} // namespace view_manager |