This source file includes following definitions.
- StackChildRelativeTo
- NotifyViewTreeChangeAtReceiver
- NotifyViewTreeChangeUp
- NotifyViewTreeChangeDown
- NotifyViewTreeChange
- RemoveChildImpl
- OnPaintLayer
- OnDeviceScaleFactorChanged
- PrepareForLayerBoundsChange
- OnLayerBoundsChanged
- parent_
- AddObserver
- RemoveObserver
- SetPainter
- SetLayout
- SetBounds
- SetVisible
- AddChild
- RemoveChild
- Contains
- StackChildAtTop
- StackChildAtBottom
- StackChildAbove
- StackChildBelow
- layer
- layer
- HasLayer
- CreateLayer
- DestroyLayer
- AcquireLayer
#include "ui/v2/public/view.h"
#include <algorithm>
#include "base/bind.h"
#include "ui/compositor/layer_owner.h"
#include "ui/v2/public/view_observer.h"
#include "ui/v2/src/view_private.h"
namespace v2 {
enum StackDirection {
STACK_ABOVE,
STACK_BELOW
};
void StackChildRelativeTo(View* parent,
std::vector<View*>* children,
View* child,
View* other,
StackDirection direction) {
DCHECK_NE(child, other);
DCHECK(child);
DCHECK(other);
DCHECK_EQ(parent, child->parent());
DCHECK_EQ(parent, other->parent());
const size_t child_i =
std::find(children->begin(), children->end(), child) - children->begin();
const size_t other_i =
std::find(children->begin(), children->end(), other) - children->begin();
const size_t destination_i =
direction == STACK_ABOVE ?
(child_i < other_i ? other_i : other_i + 1) :
(child_i < other_i ? other_i - 1 : other_i);
children->erase(children->begin() + child_i);
children->insert(children->begin() + destination_i, child);
}
void NotifyViewTreeChangeAtReceiver(
View* receiver,
const ViewObserver::TreeChangeParams& params) {
ViewObserver::TreeChangeParams local_params = params;
local_params.receiver = receiver;
FOR_EACH_OBSERVER(ViewObserver,
*ViewPrivate(receiver).observers(),
OnViewTreeChange(local_params));
}
void NotifyViewTreeChangeUp(View* start_at,
const ViewObserver::TreeChangeParams& params) {
for (View* current = start_at; current; current = current->parent())
NotifyViewTreeChangeAtReceiver(current, params);
}
void NotifyViewTreeChangeDown(View* start_at,
const ViewObserver::TreeChangeParams& params) {
NotifyViewTreeChangeAtReceiver(start_at, params);
View::Children::const_iterator it = start_at->children().begin();
for (; it != start_at->children().end(); ++it)
NotifyViewTreeChangeDown(*it, params);
}
void NotifyViewTreeChange(const ViewObserver::TreeChangeParams& params) {
NotifyViewTreeChangeDown(params.target, params);
switch (params.phase) {
case ViewObserver::DISPOSITION_CHANGING:
if (params.old_parent)
NotifyViewTreeChangeUp(params.old_parent, params);
break;
case ViewObserver::DISPOSITION_CHANGED:
if (params.new_parent)
NotifyViewTreeChangeUp(params.new_parent, params);
break;
default:
NOTREACHED();
break;
}
}
class ScopedTreeNotifier {
public:
ScopedTreeNotifier(View* target, View* old_parent, View* new_parent) {
params_.target = target;
params_.old_parent = old_parent;
params_.new_parent = new_parent;
NotifyViewTreeChange(params_);
}
~ScopedTreeNotifier() {
params_.phase = ViewObserver::DISPOSITION_CHANGED;
NotifyViewTreeChange(params_);
}
private:
ViewObserver::TreeChangeParams params_;
DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier);
};
void RemoveChildImpl(View* child, View::Children* children) {
std::vector<View*>::iterator it =
std::find(children->begin(), children->end(), child);
if (it != children->end()) {
children->erase(it);
ViewPrivate(child).ClearParent();
}
}
class ViewLayerOwner : public ui::LayerOwner,
public ui::LayerDelegate {
public:
explicit ViewLayerOwner(ui::Layer* layer) {
layer_ = layer;
}
~ViewLayerOwner() {}
private:
virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
}
virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
}
virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
return base::Bind(&ViewLayerOwner::OnLayerBoundsChanged,
base::Unretained(this));
}
void OnLayerBoundsChanged() {
}
DISALLOW_COPY_AND_ASSIGN(ViewLayerOwner);
};
View::View() : visible_(true), owned_by_parent_(true), parent_(NULL) {
}
View::~View() {
FOR_EACH_OBSERVER(ViewObserver, observers_,
OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGING));
while (!children_.empty()) {
View* child = children_.front();
if (child->owned_by_parent_) {
delete child;
DCHECK(std::find(children_.begin(), children_.end(), child) ==
children_.end());
} else {
RemoveChild(child);
}
}
if (parent_)
parent_->RemoveChild(this);
FOR_EACH_OBSERVER(ViewObserver, observers_,
OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGED));
}
void View::AddObserver(ViewObserver* observer) {
observers_.AddObserver(observer);
}
void View::RemoveObserver(ViewObserver* observer) {
observers_.RemoveObserver(observer);
}
void View::SetPainter(Painter* painter) {
painter_.reset(painter);
}
void View::SetLayout(Layout* layout) {
layout_.reset(layout);
}
void View::SetBounds(const gfx::Rect& bounds) {
gfx::Rect old_bounds = bounds_;
bounds_ = bounds;
if (bounds_ != old_bounds) {
FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewBoundsChanged(this,
old_bounds, bounds_));
}
}
void View::SetVisible(bool visible) {
FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this,
ViewObserver::DISPOSITION_CHANGING));
bool old_visible = visible_;
visible_ = visible;
if (old_visible != visible_) {
FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this,
ViewObserver::DISPOSITION_CHANGED));
}
}
void View::AddChild(View* child) {
ScopedTreeNotifier notifier(child, child->parent(), this);
if (child->parent())
RemoveChildImpl(child, &child->parent_->children_);
children_.push_back(child);
child->parent_ = this;
}
void View::RemoveChild(View* child) {
DCHECK_EQ(this, child->parent());
ScopedTreeNotifier(child, this, NULL);
RemoveChildImpl(child, &children_);
}
bool View::Contains(View* child) const {
for (View* p = child->parent(); p; p = p->parent()) {
if (p == this)
return true;
}
return false;
}
void View::StackChildAtTop(View* child) {
if (children_.size() <= 1 || child == children_.back())
return;
StackChildAbove(child, children_.back());
}
void View::StackChildAtBottom(View* child) {
if (children_.size() <= 1 || child == children_.front())
return;
StackChildBelow(child, children_.front());
}
void View::StackChildAbove(View* child, View* other) {
StackChildRelativeTo(this, &children_, child, other, STACK_ABOVE);
}
void View::StackChildBelow(View* child, View* other) {
StackChildRelativeTo(this, &children_, child, other, STACK_BELOW);
}
const ui::Layer* View::layer() const {
return layer_owner_.get() ? layer_owner_->layer() : NULL;
}
ui::Layer* View::layer() {
return const_cast<ui::Layer*>(const_cast<const View*>(this)->layer());
}
bool View::HasLayer() const {
return !!layer();
}
void View::CreateLayer(ui::LayerType layer_type) {
layer_owner_.reset(new ViewLayerOwner(new ui::Layer(layer_type)));
layer()->SetVisible(visible_);
layer()->set_delegate(layer_owner_.get());
}
void View::DestroyLayer() {
DCHECK(layer_owner_.get());
layer_owner_.reset();
}
ui::Layer* View::AcquireLayer() {
DCHECK(layer_owner_.get());
return layer_owner_->AcquireLayer();
}
}