14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/v2/public/view.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <algorithm>
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/compositor/layer_owner.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/v2/public/view_observer.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/v2/src/view_private.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace v2 {
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)enum StackDirection {
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  STACK_ABOVE,
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  STACK_BELOW
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void StackChildRelativeTo(View* parent,
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          std::vector<View*>* children,
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          View* child,
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          View* other,
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          StackDirection direction) {
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_NE(child, other);
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(child);
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(other);
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(parent, child->parent());
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(parent, other->parent());
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): Notify stacking changing.
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): consult layout manager
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const size_t child_i =
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      std::find(children->begin(), children->end(), child) - children->begin();
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const size_t other_i =
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      std::find(children->begin(), children->end(), other) - children->begin();
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const size_t destination_i =
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      direction == STACK_ABOVE ?
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      (child_i < other_i ? other_i : other_i + 1) :
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      (child_i < other_i ? other_i - 1 : other_i);
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  children->erase(children->begin() + child_i);
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  children->insert(children->begin() + destination_i, child);
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): update layer.
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): Notify stacking changed.
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NotifyViewTreeChangeAtReceiver(
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    View* receiver,
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ViewObserver::TreeChangeParams& params) {
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ViewObserver::TreeChangeParams local_params = params;
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  local_params.receiver = receiver;
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FOR_EACH_OBSERVER(ViewObserver,
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    *ViewPrivate(receiver).observers(),
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    OnViewTreeChange(local_params));
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NotifyViewTreeChangeUp(View* start_at,
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                            const ViewObserver::TreeChangeParams& params) {
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (View* current = start_at; current; current = current->parent())
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NotifyViewTreeChangeAtReceiver(current, params);
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NotifyViewTreeChangeDown(View* start_at,
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              const ViewObserver::TreeChangeParams& params) {
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NotifyViewTreeChangeAtReceiver(start_at, params);
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  View::Children::const_iterator it = start_at->children().begin();
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (; it != start_at->children().end(); ++it)
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NotifyViewTreeChangeDown(*it, params);
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NotifyViewTreeChange(const ViewObserver::TreeChangeParams& params) {
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NotifyViewTreeChangeDown(params.target, params);
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (params.phase) {
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  case ViewObserver::DISPOSITION_CHANGING:
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (params.old_parent)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NotifyViewTreeChangeUp(params.old_parent, params);
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    break;
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  case ViewObserver::DISPOSITION_CHANGED:
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (params.new_parent)
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NotifyViewTreeChangeUp(params.new_parent, params);
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    break;
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  default:
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NOTREACHED();
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    break;
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ScopedTreeNotifier {
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedTreeNotifier(View* target, View* old_parent, View* new_parent) {
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    params_.target = target;
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    params_.old_parent = old_parent;
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    params_.new_parent = new_parent;
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NotifyViewTreeChange(params_);
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ~ScopedTreeNotifier() {
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    params_.phase = ViewObserver::DISPOSITION_CHANGED;
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NotifyViewTreeChange(params_);
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ViewObserver::TreeChangeParams params_;
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier);
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void RemoveChildImpl(View* child, View::Children* children) {
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<View*>::iterator it =
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      std::find(children->begin(), children->end(), child);
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (it != children->end()) {
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    children->erase(it);
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ViewPrivate(child).ClearParent();
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ViewLayerOwner : public ui::LayerOwner,
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       public ui::LayerDelegate {
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit ViewLayerOwner(ui::Layer* layer) {
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_ = layer;
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ~ViewLayerOwner() {}
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Overridden from ui::LayerDelegate:
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // TODO(beng): paint processor.
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // TODO(beng): ???
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return base::Bind(&ViewLayerOwner::OnLayerBoundsChanged,
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      base::Unretained(this));
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void OnLayerBoundsChanged() {
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // TODO(beng): ???
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ViewLayerOwner);
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// View, public:
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Creation, configuration -----------------------------------------------------
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)View::View() : visible_(true), owned_by_parent_(true), parent_(NULL) {
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)View::~View() {
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FOR_EACH_OBSERVER(ViewObserver, observers_,
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGING));
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  while (!children_.empty()) {
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    View* child = children_.front();
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (child->owned_by_parent_) {
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      delete child;
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Deleting the child also removes it from our child list.
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      DCHECK(std::find(children_.begin(), children_.end(), child) ==
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             children_.end());
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    } else {
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      RemoveChild(child);
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (parent_)
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    parent_->RemoveChild(this);
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FOR_EACH_OBSERVER(ViewObserver, observers_,
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGED));
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::AddObserver(ViewObserver* observer) {
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  observers_.AddObserver(observer);
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::RemoveObserver(ViewObserver* observer) {
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  observers_.RemoveObserver(observer);
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::SetPainter(Painter* painter) {
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  painter_.reset(painter);
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::SetLayout(Layout* layout) {
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  layout_.reset(layout);
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Disposition -----------------------------------------------------------------
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::SetBounds(const gfx::Rect& bounds) {
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Rect old_bounds = bounds_;
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): consult layout manager
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bounds_ = bounds;
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): update layer
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): write tests for this where layoutmanager prevents a change
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //             and no changed notification is sent.
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (bounds_ != old_bounds) {
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewBoundsChanged(this,
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        old_bounds, bounds_));
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::SetVisible(bool visible) {
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this,
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ViewObserver::DISPOSITION_CHANGING));
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool old_visible = visible_;
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): consult layout manager
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  visible_ = visible;
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): update layer
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): write tests for this where layoutmanager prevents a change
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //             and no changed notification is sent.
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (old_visible != visible_) {
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this,
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ViewObserver::DISPOSITION_CHANGED));
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Tree ------------------------------------------------------------------------
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::AddChild(View* child) {
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedTreeNotifier notifier(child, child->parent(), this);
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (child->parent())
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RemoveChildImpl(child, &child->parent_->children_);
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  children_.push_back(child);
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  child->parent_ = this;
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::RemoveChild(View* child) {
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(this, child->parent());
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedTreeNotifier(child, this, NULL);
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RemoveChildImpl(child, &children_);
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool View::Contains(View* child) const {
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (View* p = child->parent(); p; p = p->parent()) {
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (p == this)
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return true;
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return false;
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::StackChildAtTop(View* child) {
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (children_.size() <= 1 || child == children_.back())
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;  // On top already.
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StackChildAbove(child, children_.back());
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::StackChildAtBottom(View* child) {
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (children_.size() <= 1 || child == children_.front())
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;  // On bottom already.
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StackChildBelow(child, children_.front());
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::StackChildAbove(View* child, View* other) {
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StackChildRelativeTo(this, &children_, child, other, STACK_ABOVE);
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::StackChildBelow(View* child, View* other) {
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StackChildRelativeTo(this, &children_, child, other, STACK_BELOW);
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Layer -----------------------------------------------------------------------
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const ui::Layer* View::layer() const {
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return layer_owner_.get() ? layer_owner_->layer() : NULL;
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ui::Layer* View::layer() {
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return const_cast<ui::Layer*>(const_cast<const View*>(this)->layer());
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool View::HasLayer() const {
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return !!layer();
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::CreateLayer(ui::LayerType layer_type) {
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  layer_owner_.reset(new ViewLayerOwner(new ui::Layer(layer_type)));
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  layer()->SetVisible(visible_);
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  layer()->set_delegate(layer_owner_.get());
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): layer name?
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(beng): SetFillsBoundsOpaquely?
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void View::DestroyLayer() {
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(layer_owner_.get());
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  layer_owner_.reset();
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ui::Layer* View::AcquireLayer() {
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(layer_owner_.get());
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return layer_owner_->AcquireLayer();
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace v2
303