OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/v2/public/view.h" | 5 #include "ui/v2/public/view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ui/v2/public/view_observer.h" | 9 #include "ui/v2/public/view_observer.h" |
| 10 #include "ui/v2/src/view_private.h" |
10 | 11 |
11 namespace v2 { | 12 namespace v2 { |
12 | 13 |
13 // Friend of View. Provides a way to get at a View's observer list for | |
14 // notification methods. | |
15 class ViewObserversAccessor { | |
16 public: | |
17 explicit ViewObserversAccessor(View* view) : view_(view) {} | |
18 ~ViewObserversAccessor() {} | |
19 | |
20 ObserverList<ViewObserver>* get() { return &view_->observers_; } | |
21 | |
22 private: | |
23 View* view_; | |
24 | |
25 DISALLOW_COPY_AND_ASSIGN(ViewObserversAccessor); | |
26 }; | |
27 | |
28 enum StackDirection { | 14 enum StackDirection { |
29 STACK_ABOVE, | 15 STACK_ABOVE, |
30 STACK_BELOW | 16 STACK_BELOW |
31 }; | 17 }; |
32 | 18 |
33 void StackChildRelativeTo(View* parent, | 19 void StackChildRelativeTo(View* parent, |
34 std::vector<View*>* children, | 20 std::vector<View*>* children, |
35 View* child, | 21 View* child, |
36 View* other, | 22 View* other, |
37 StackDirection direction) { | 23 StackDirection direction) { |
38 DCHECK_NE(child, other); | 24 DCHECK_NE(child, other); |
39 DCHECK(child); | 25 DCHECK(child); |
40 DCHECK(other); | 26 DCHECK(other); |
41 DCHECK_EQ(parent, child->parent()); | 27 DCHECK_EQ(parent, child->parent()); |
42 DCHECK_EQ(parent, other->parent()); | 28 DCHECK_EQ(parent, other->parent()); |
43 | 29 |
44 // Notify stacking changing. | 30 // TODO(beng): Notify stacking changing. |
45 | 31 // TODO(beng): consult layout manager |
46 // TODO(beng): This is simpler than aura::Window's for now. | |
47 const size_t child_i = | 32 const size_t child_i = |
48 std::find(children->begin(), children->end(), child) - children->begin(); | 33 std::find(children->begin(), children->end(), child) - children->begin(); |
49 const size_t other_i = | 34 const size_t other_i = |
50 std::find(children->begin(), children->end(), other) - children->begin(); | 35 std::find(children->begin(), children->end(), other) - children->begin(); |
51 const size_t destination_i = | 36 const size_t destination_i = |
52 direction == STACK_ABOVE ? | 37 direction == STACK_ABOVE ? |
53 (child_i < other_i ? other_i : other_i + 1) : | 38 (child_i < other_i ? other_i : other_i + 1) : |
54 (child_i < other_i ? other_i - 1 : other_i); | 39 (child_i < other_i ? other_i - 1 : other_i); |
55 children->erase(children->begin() + child_i); | 40 children->erase(children->begin() + child_i); |
56 children->insert(children->begin() + destination_i, child); | 41 children->insert(children->begin() + destination_i, child); |
57 | 42 |
58 // TODO(beng): restack layers. | 43 // TODO(beng): update layer. |
59 | 44 // TODO(beng): Notify stacking changed. |
60 // Notify stacking changed. | |
61 } | 45 } |
62 | 46 |
63 void NotifyViewTreeChangeAtReceiver( | 47 void NotifyViewTreeChangeAtReceiver( |
64 View* receiver, | 48 View* receiver, |
65 const ViewObserver::TreeChangeParams& params) { | 49 const ViewObserver::TreeChangeParams& params) { |
66 ViewObserver::TreeChangeParams local_params = params; | 50 ViewObserver::TreeChangeParams local_params = params; |
67 local_params.receiver = receiver; | 51 local_params.receiver = receiver; |
68 FOR_EACH_OBSERVER(ViewObserver, | 52 FOR_EACH_OBSERVER(ViewObserver, |
69 *ViewObserversAccessor(receiver).get(), | 53 *ViewPrivate(receiver).observers(), |
70 OnViewTreeChange(local_params)); | 54 OnViewTreeChange(local_params)); |
71 } | 55 } |
72 | 56 |
73 void NotifyViewTreeChangeUp(View* start_at, | 57 void NotifyViewTreeChangeUp(View* start_at, |
74 const ViewObserver::TreeChangeParams& params) { | 58 const ViewObserver::TreeChangeParams& params) { |
75 for (View* current = start_at; current; current = current->parent()) | 59 for (View* current = start_at; current; current = current->parent()) |
76 NotifyViewTreeChangeAtReceiver(current, params); | 60 NotifyViewTreeChangeAtReceiver(current, params); |
77 } | 61 } |
78 | 62 |
79 void NotifyViewTreeChangeDown(View* start_at, | 63 void NotifyViewTreeChangeDown(View* start_at, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 params_.phase = ViewObserver::DISPOSITION_CHANGED; | 97 params_.phase = ViewObserver::DISPOSITION_CHANGED; |
114 NotifyViewTreeChange(params_); | 98 NotifyViewTreeChange(params_); |
115 } | 99 } |
116 | 100 |
117 private: | 101 private: |
118 ViewObserver::TreeChangeParams params_; | 102 ViewObserver::TreeChangeParams params_; |
119 | 103 |
120 DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier); | 104 DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier); |
121 }; | 105 }; |
122 | 106 |
| 107 void RemoveChildImpl(View* child, View::Children* children) { |
| 108 std::vector<View*>::iterator it = |
| 109 std::find(children->begin(), children->end(), child); |
| 110 if (it != children->end()) { |
| 111 children->erase(it); |
| 112 ViewPrivate(child).ClearParent(); |
| 113 } |
| 114 } |
| 115 |
123 //////////////////////////////////////////////////////////////////////////////// | 116 //////////////////////////////////////////////////////////////////////////////// |
124 // View, public: | 117 // View, public: |
125 | 118 |
126 // Creation, configuration ----------------------------------------------------- | 119 // Creation, configuration ----------------------------------------------------- |
127 | 120 |
128 View::View() : visible_(false), owned_by_parent_(true), parent_(NULL) { | 121 View::View() : visible_(true), owned_by_parent_(true), parent_(NULL) { |
129 } | 122 } |
130 | 123 |
131 View::~View() { | 124 View::~View() { |
132 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroying()); | 125 FOR_EACH_OBSERVER(ViewObserver, observers_, |
| 126 OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGING)); |
133 | 127 |
134 while (!children_.empty()) { | 128 while (!children_.empty()) { |
135 View* child = children_.front(); | 129 View* child = children_.front(); |
136 if (child->owned_by_parent_) { | 130 if (child->owned_by_parent_) { |
137 delete child; | 131 delete child; |
138 // Deleting the child also removes it from our child list. | 132 // Deleting the child also removes it from our child list. |
139 DCHECK(std::find(children_.begin(), children_.end(), child) == | 133 DCHECK(std::find(children_.begin(), children_.end(), child) == |
140 children_.end()); | 134 children_.end()); |
141 } else { | 135 } else { |
142 RemoveChild(child); | 136 RemoveChild(child); |
143 } | 137 } |
144 } | 138 } |
145 | 139 |
146 if (parent_) | 140 if (parent_) |
147 parent_->RemoveChild(this); | 141 parent_->RemoveChild(this); |
148 | 142 |
149 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroyed()); | 143 FOR_EACH_OBSERVER(ViewObserver, observers_, |
| 144 OnViewDestroy(this, ViewObserver::DISPOSITION_CHANGED)); |
150 } | 145 } |
151 | 146 |
152 void View::AddObserver(ViewObserver* observer) { | 147 void View::AddObserver(ViewObserver* observer) { |
153 observers_.AddObserver(observer); | 148 observers_.AddObserver(observer); |
154 } | 149 } |
155 | 150 |
156 void View::RemoveObserver(ViewObserver* observer) { | 151 void View::RemoveObserver(ViewObserver* observer) { |
157 observers_.RemoveObserver(observer); | 152 observers_.RemoveObserver(observer); |
158 } | 153 } |
159 | 154 |
160 void View::SetPainter(Painter* painter) { | 155 void View::SetPainter(Painter* painter) { |
161 painter_.reset(painter); | 156 painter_.reset(painter); |
162 } | 157 } |
163 | 158 |
164 void View::SetLayout(Layout* layout) { | 159 void View::SetLayout(Layout* layout) { |
165 layout_.reset(layout); | 160 layout_.reset(layout); |
166 } | 161 } |
167 | 162 |
168 // Disposition ----------------------------------------------------------------- | 163 // Disposition ----------------------------------------------------------------- |
169 | 164 |
170 void View::SetBounds(const gfx::Rect& bounds) { | 165 void View::SetBounds(const gfx::Rect& bounds) { |
171 if (parent_ && parent_->layout_.get()) | 166 gfx::Rect old_bounds = bounds_; |
172 parent_->layout_->SetChildBounds(this, bounds); | 167 // TODO(beng): consult layout manager |
173 else | 168 bounds_ = bounds; |
174 SetBoundsInternal(bounds); | 169 // TODO(beng): update layer |
| 170 |
| 171 // TODO(beng): write tests for this where layoutmanager prevents a change |
| 172 // and no changed notification is sent. |
| 173 if (bounds_ != old_bounds) { |
| 174 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewBoundsChanged(this, |
| 175 old_bounds, bounds_)); |
| 176 } |
175 } | 177 } |
176 | 178 |
177 void View::SetVisible(bool visible) {} | 179 void View::SetVisible(bool visible) { |
| 180 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this, |
| 181 ViewObserver::DISPOSITION_CHANGING)); |
| 182 |
| 183 bool old_visible = visible_; |
| 184 // TODO(beng): consult layout manager |
| 185 visible_ = visible; |
| 186 // TODO(beng): update layer |
| 187 |
| 188 // TODO(beng): write tests for this where layoutmanager prevents a change |
| 189 // and no changed notification is sent. |
| 190 if (old_visible != visible_) { |
| 191 FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChange(this, |
| 192 ViewObserver::DISPOSITION_CHANGED)); |
| 193 } |
| 194 } |
178 | 195 |
179 // Tree ------------------------------------------------------------------------ | 196 // Tree ------------------------------------------------------------------------ |
180 | 197 |
181 void View::AddChild(View* child) { | 198 void View::AddChild(View* child) { |
182 ScopedTreeNotifier notifier(child, child->parent(), this); | 199 ScopedTreeNotifier notifier(child, child->parent(), this); |
| 200 if (child->parent()) |
| 201 RemoveChildImpl(child, &child->parent_->children_); |
183 children_.push_back(child); | 202 children_.push_back(child); |
184 child->parent_ = this; | 203 child->parent_ = this; |
185 } | 204 } |
186 | 205 |
187 void View::RemoveChild(View* child) { | 206 void View::RemoveChild(View* child) { |
| 207 DCHECK_EQ(this, child->parent()); |
188 ScopedTreeNotifier(child, this, NULL); | 208 ScopedTreeNotifier(child, this, NULL); |
189 std::vector<View*>::iterator it = | 209 RemoveChildImpl(child, &children_); |
190 std::find(children_.begin(), children_.end(), child); | |
191 if (it != children_.end()) { | |
192 children_.erase(it); | |
193 child->parent_ = NULL; | |
194 } | |
195 } | 210 } |
196 | 211 |
197 bool View::Contains(View* child) const { | 212 bool View::Contains(View* child) const { |
198 for (View* p = child->parent(); p; p = p->parent()) { | 213 for (View* p = child->parent(); p; p = p->parent()) { |
199 if (p == this) | 214 if (p == this) |
200 return true; | 215 return true; |
201 } | 216 } |
202 return false; | 217 return false; |
203 } | 218 } |
204 | 219 |
(...skipping 10 matching lines...) Expand all Loading... |
215 } | 230 } |
216 | 231 |
217 void View::StackChildAbove(View* child, View* other) { | 232 void View::StackChildAbove(View* child, View* other) { |
218 StackChildRelativeTo(this, &children_, child, other, STACK_ABOVE); | 233 StackChildRelativeTo(this, &children_, child, other, STACK_ABOVE); |
219 } | 234 } |
220 | 235 |
221 void View::StackChildBelow(View* child, View* other) { | 236 void View::StackChildBelow(View* child, View* other) { |
222 StackChildRelativeTo(this, &children_, child, other, STACK_BELOW); | 237 StackChildRelativeTo(this, &children_, child, other, STACK_BELOW); |
223 } | 238 } |
224 | 239 |
225 //////////////////////////////////////////////////////////////////////////////// | |
226 // View, private: | |
227 | |
228 void View::SetBoundsInternal(const gfx::Rect& bounds) { | |
229 bounds_ = bounds; | |
230 | |
231 // TODO(beng): Update layer. | |
232 // TODO(beng): Notify changed. | |
233 } | |
234 | |
235 } // namespace v2 | 240 } // namespace v2 |
OLD | NEW |