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 303