| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/v2/public/view.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "ui/compositor/layer_owner.h" | |
| 11 #include "ui/v2/public/view_observer.h" | |
| 12 #include "ui/v2/src/view_private.h" | |
| 13 | |
| 14 namespace v2 { | |
| 15 | |
| 16 enum StackDirection { | |
| 17 STACK_ABOVE, | |
| 18 STACK_BELOW | |
| 19 }; | |
| 20 | |
| 21 void StackChildRelativeTo(View* parent, | |
| 22 std::vector<View*>* children, | |
| 23 View* child, | |
| 24 View* other, | |
| 25 StackDirection direction) { | |
| 26 DCHECK_NE(child, other); | |
| 27 DCHECK(child); | |
| 28 DCHECK(other); | |
| 29 DCHECK_EQ(parent, child->parent()); | |
| 30 DCHECK_EQ(parent, other->parent()); | |
| 31 | |
| 32 // TODO(beng): Notify stacking changing. | |
| 33 // TODO(beng): consult layout manager | |
| 34 const size_t child_i = | |
| 35 std::find(children->begin(), children->end(), child) - children->begin(); | |
| 36 const size_t other_i = | |
| 37 std::find(children->begin(), children->end(), other) - children->begin(); | |
| 38 const size_t destination_i = | |
| 39 direction == STACK_ABOVE ? | |
| 40 (child_i < other_i ? other_i : other_i + 1) : | |
| 41 (child_i < other_i ? other_i - 1 : other_i); | |
| 42 children->erase(children->begin() + child_i); | |
| 43 children->insert(children->begin() + destination_i, child); | |
| 44 | |
| 45 // TODO(beng): update layer. | |
| 46 // TODO(beng): Notify stacking changed. | |
| 47 } | |
| 48 | |
| 49 void NotifyViewTreeChangeAtReceiver( | |
| 50 View* receiver, | |
| 51 const ViewObserver::TreeChangeParams& params) { | |
| 52 ViewObserver::TreeChangeParams local_params = params; | |
| 53 local_params.receiver = receiver; | |
| 54 FOR_EACH_OBSERVER(ViewObserver, | |
| 55 *ViewPrivate(receiver).observers(), | |
| 56 OnViewTreeChange(local_params)); | |
| 57 } | |
| 58 | |
| 59 void NotifyViewTreeChangeUp(View* start_at, | |
| 60 const ViewObserver::TreeChangeParams& params) { | |
| 61 for (View* current = start_at; current; current = current->parent()) | |
| 62 NotifyViewTreeChangeAtReceiver(current, params); | |
| 63 } | |
| 64 | |
| 65 void NotifyViewTreeChangeDown(View* start_at, | |
| 66 const ViewObserver::TreeChangeParams& params) { | |
| 67 NotifyViewTreeChangeAtReceiver(start_at, params); | |
| 68 View::Children::const_iterator it = start_at->children().begin(); | |
| 69 for (; it != start_at->children().end(); ++it) | |
| 70 NotifyViewTreeChangeDown(*it, params); | |
| 71 } | |
| 72 | |
| 73 void NotifyViewTreeChange(const ViewObserver::TreeChangeParams& params) { | |
| 74 NotifyViewTreeChangeDown(params.target, params); | |
| 75 switch (params.phase) { | |
| 76 case ViewObserver::DISPOSITION_CHANGING: | |
| 77 if (params.old_parent) | |
| 78 NotifyViewTreeChangeUp(params.old_parent, params); | |
| 79 break; | |
| 80 case ViewObserver::DISPOSITION_CHANGED: | |
| 81 if (params.new_parent) | |
| 82 NotifyViewTreeChangeUp(params.new_parent, params); | |
| 83 break; | |
| 84 default: | |
| 85 NOTREACHED(); | |
| 86 break; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 class ScopedTreeNotifier { | |
| 91 public: | |
| 92 ScopedTreeNotifier(View* target, View* old_parent, View* new_parent) { | |
| 93 params_.target = target; | |
| 94 params_.old_parent = old_parent; | |
| 95 params_.new_parent = new_parent; | |
| 96 NotifyViewTreeChange(params_); | |
| 97 } | |
| 98 ~ScopedTreeNotifier() { | |
| 99 params_.phase = ViewObserver::DISPOSITION_CHANGED; | |
| 100 NotifyViewTreeChange(params_); | |
| 101 } | |
| 102 | |
| 103 private: | |
| 104 ViewObserver::TreeChangeParams params_; | |
| 105 | |
| 106 DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier); | |
| 107 }; | |
| 108 | |
| 109 void RemoveChildImpl(View* child, View::Children* children) { | |
| 110 std::vector<View*>::iterator it = | |
| 111 std::find(children->begin(), children->end(), child); | |
| 112 if (it != children->end()) { | |
| 113 children->erase(it); | |
| 114 ViewPrivate(child).ClearParent(); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 class ViewLayerOwner : public ui::LayerOwner, | |
| 119 public ui::LayerDelegate { | |
| 120 public: | |
| 121 explicit ViewLayerOwner(ui::Layer* layer) { | |
| 122 layer_ = layer; | |
| 123 } | |
| 124 ~ViewLayerOwner() {} | |
| 125 | |
| 126 private: | |
| 127 // Overridden from ui::LayerDelegate: | |
| 128 virtual void OnPaintLayer(gfx::Canvas* canvas) override { | |
| 129 // TODO(beng): paint processor. | |
| 130 } | |
| 131 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) override { | |
| 132 // TODO(beng): ??? | |
| 133 } | |
| 134 virtual base::Closure PrepareForLayerBoundsChange() override { | |
| 135 return base::Bind(&ViewLayerOwner::OnLayerBoundsChanged, | |
| 136 base::Unretained(this)); | |
| 137 } | |
| 138 | |
| 139 void OnLayerBoundsChanged() { | |
| 140 // TODO(beng): ??? | |
| 141 } | |
| 142 | |
| 143 DISALLOW_COPY_AND_ASSIGN(ViewLayerOwner); | |
| 144 }; | |
| 145 | |
| 146 //////////////////////////////////////////////////////////////////////////////// | |
| 147 // View, public: | |
| 148 | |
| 149 // Creation, configuration ----------------------------------------------------- | |
| 150 | |
| 151 View::View() : visible_(true), owned_by_parent_(true), parent_(NULL) { | |
| 152 } | |
| 153 | |
| 154 View::~View() { | |
| 155 FOR_EACH_OBSERVER(ViewObserver, observers_, | |
| 156 OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGING)); | |
| 157 | |
| 158 while (!children_.empty()) { | |
| 159 View* child = children_.front(); | |
| 160 if (child->owned_by_parent_) { | |
| 161 delete child; | |
| 162 // Deleting the child also removes it from our child list. | |
| 163 DCHECK(std::find(children_.begin(), children_.end(), child) == | |
| 164 children_.end()); | |
| 165 } else { | |
| 166 RemoveChild(child); | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 if (parent_) | |
| 171 parent_->RemoveChild(this); | |
| 172 | |
| 173 FOR_EACH_OBSERVER(ViewObserver, observers_, | |
| 174 OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGED)); | |
| 175 } | |
| 176 | |
| 177 void View::AddObserver(ViewObserver* observer) { | |
| 178 observers_.AddObserver(observer); | |
| 179 } | |
| 180 | |
| 181 void View::RemoveObserver(ViewObserver* observer) { | |
| 182 observers_.RemoveObserver(observer); | |
| 183 } | |
| 184 | |
| 185 void View::SetPainter(Painter* painter) { | |
| 186 painter_.reset(painter); | |
| 187 } | |
| 188 | |
| 189 void View::SetLayout(Layout* layout) { | |
| 190 layout_.reset(layout); | |
| 191 } | |
| 192 | |
| 193 // Disposition ----------------------------------------------------------------- | |
| 194 | |
| 195 void View::SetBounds(const gfx::Rect& bounds) { | |
| 196 gfx::Rect old_bounds = bounds_; | |
| 197 // TODO(beng): consult layout manager | |
| 198 bounds_ = bounds; | |
| 199 // TODO(beng): update layer | |
| 200 | |
| 201 // TODO(beng): write tests for this where layoutmanager prevents a change | |
| 202 // and no changed notification is sent. | |
| 203 if (bounds_ != old_bounds) { | |
| 204 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewBoundsChanged(this, | |
| 205 old_bounds, bounds_)); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void View::SetVisible(bool visible) { | |
| 210 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this, | |
| 211 ViewObserver::DISPOSITION_CHANGING)); | |
| 212 | |
| 213 bool old_visible = visible_; | |
| 214 // TODO(beng): consult layout manager | |
| 215 visible_ = visible; | |
| 216 // TODO(beng): update layer | |
| 217 | |
| 218 // TODO(beng): write tests for this where layoutmanager prevents a change | |
| 219 // and no changed notification is sent. | |
| 220 if (old_visible != visible_) { | |
| 221 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this, | |
| 222 ViewObserver::DISPOSITION_CHANGED)); | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 // Tree ------------------------------------------------------------------------ | |
| 227 | |
| 228 void View::AddChild(View* child) { | |
| 229 ScopedTreeNotifier notifier(child, child->parent(), this); | |
| 230 if (child->parent()) | |
| 231 RemoveChildImpl(child, &child->parent_->children_); | |
| 232 children_.push_back(child); | |
| 233 child->parent_ = this; | |
| 234 } | |
| 235 | |
| 236 void View::RemoveChild(View* child) { | |
| 237 DCHECK_EQ(this, child->parent()); | |
| 238 ScopedTreeNotifier(child, this, NULL); | |
| 239 RemoveChildImpl(child, &children_); | |
| 240 } | |
| 241 | |
| 242 bool View::Contains(View* child) const { | |
| 243 for (View* p = child->parent(); p; p = p->parent()) { | |
| 244 if (p == this) | |
| 245 return true; | |
| 246 } | |
| 247 return false; | |
| 248 } | |
| 249 | |
| 250 void View::StackChildAtTop(View* child) { | |
| 251 if (children_.size() <= 1 || child == children_.back()) | |
| 252 return; // On top already. | |
| 253 StackChildAbove(child, children_.back()); | |
| 254 } | |
| 255 | |
| 256 void View::StackChildAtBottom(View* child) { | |
| 257 if (children_.size() <= 1 || child == children_.front()) | |
| 258 return; // On bottom already. | |
| 259 StackChildBelow(child, children_.front()); | |
| 260 } | |
| 261 | |
| 262 void View::StackChildAbove(View* child, View* other) { | |
| 263 StackChildRelativeTo(this, &children_, child, other, STACK_ABOVE); | |
| 264 } | |
| 265 | |
| 266 void View::StackChildBelow(View* child, View* other) { | |
| 267 StackChildRelativeTo(this, &children_, child, other, STACK_BELOW); | |
| 268 } | |
| 269 | |
| 270 // Layer ----------------------------------------------------------------------- | |
| 271 | |
| 272 const ui::Layer* View::layer() const { | |
| 273 return layer_owner_.get() ? layer_owner_->layer() : NULL; | |
| 274 } | |
| 275 | |
| 276 ui::Layer* View::layer() { | |
| 277 return const_cast<ui::Layer*>(const_cast<const View*>(this)->layer()); | |
| 278 } | |
| 279 | |
| 280 bool View::HasLayer() const { | |
| 281 return !!layer(); | |
| 282 } | |
| 283 | |
| 284 void View::CreateLayer(ui::LayerType layer_type) { | |
| 285 layer_owner_.reset(new ViewLayerOwner(new ui::Layer(layer_type))); | |
| 286 layer()->SetVisible(visible_); | |
| 287 layer()->set_delegate(layer_owner_.get()); | |
| 288 // TODO(beng): layer name? | |
| 289 // TODO(beng): SetFillsBoundsOpaquely? | |
| 290 } | |
| 291 | |
| 292 void View::DestroyLayer() { | |
| 293 DCHECK(layer_owner_.get()); | |
| 294 layer_owner_.reset(); | |
| 295 } | |
| 296 | |
| 297 ui::Layer* View::AcquireLayer() { | |
| 298 DCHECK(layer_owner_.get()); | |
| 299 return layer_owner_->AcquireLayer(); | |
| 300 } | |
| 301 | |
| 302 } // namespace v2 | |
| OLD | NEW |