| // 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 "mojo/services/view_manager/server_view_delegate.h" |
| |
| namespace mojo { |
| namespace service { |
| |
| ServerView::ServerView(ServerViewDelegate* delegate, const ViewId& id) |
| : delegate_(delegate), id_(id), parent_(NULL), visible_(true) { |
| DCHECK(delegate); // Must provide a delegate. |
| } |
| |
| ServerView::~ServerView() { |
| 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(), ORDER_DIRECTION_ABOVE); |
| return; |
| } |
| |
| const ServerView* old_parent = child->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); |
| |
| RemoveImpl(child); |
| child->delegate_->OnViewHierarchyChanged(child, NULL, this); |
| } |
| |
| void ServerView::Reorder(ServerView* child, |
| ServerView* relative, |
| 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 == ORDER_DIRECTION_ABOVE) { |
| DCHECK(i != children_.end()); |
| children_.insert(++i, child); |
| } else if (direction == ORDER_DIRECTION_BELOW) { |
| DCHECK(i != children_.end()); |
| children_.insert(i, child); |
| } |
| } |
| |
| 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; |
| |
| visible_ = value; |
| // TODO(sky): notification, including repaint. |
| } |
| |
| void ServerView::SetBitmap(const SkBitmap& bitmap) { |
| bitmap_ = bitmap; |
| delegate_->OnViewBitmapChanged(this); |
| } |
| |
| void ServerView::RemoveImpl(ServerView* view) { |
| view->parent_ = NULL; |
| children_.erase(std::find(children_.begin(), children_.end(), view)); |
| } |
| |
| } // namespace service |
| } // namespace mojo |