Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: ui/v2/src/view.cc

Issue 25757007: V2: Implement reparenting, bounds and visibility change notifications, and write more tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « ui/v2/src/layout.cc ('k') | ui/v2/src/view_private.h » ('j') | ui/v2/src/view_private.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698