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

Side by Side Diff: mojo/services/view_manager/connection_manager.cc

Issue 720883003: Adds a CloneAndAnimate function to WindowManagerInternalClient (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: feedback Created 6 years, 1 month 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "mojo/services/view_manager/connection_manager.h" 5 #include "mojo/services/view_manager/connection_manager.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "mojo/converters/geometry/geometry_type_converters.h" 9 #include "mojo/converters/geometry/geometry_type_converters.h"
10 #include "mojo/converters/input_events/input_events_type_converters.h" 10 #include "mojo/converters/input_events/input_events_type_converters.h"
11 #include "mojo/public/interfaces/application/service_provider.mojom.h" 11 #include "mojo/public/interfaces/application/service_provider.mojom.h"
12 #include "mojo/services/view_manager/client_connection.h" 12 #include "mojo/services/view_manager/client_connection.h"
13 #include "mojo/services/view_manager/connection_manager_delegate.h" 13 #include "mojo/services/view_manager/connection_manager_delegate.h"
14 #include "mojo/services/view_manager/display_manager.h" 14 #include "mojo/services/view_manager/display_manager.h"
15 #include "mojo/services/view_manager/server_view.h"
16 #include "mojo/services/view_manager/view_coordinate_conversions.h"
15 #include "mojo/services/view_manager/view_manager_service_impl.h" 17 #include "mojo/services/view_manager/view_manager_service_impl.h"
16 18
17 namespace mojo { 19 namespace mojo {
18 namespace service { 20 namespace service {
21 namespace {
22
23 // Creates a copy of |view|. The copied view has |delegate| as its delegate.
24 // This does not recurse.
25 ServerView* CloneView(const ServerView* view, ServerViewDelegate* delegate) {
26 ServerView* clone = new ServerView(delegate, ClonedViewId());
27 clone->SetBounds(view->bounds());
28 clone->SetSurfaceId(view->surface_id());
29 clone->SetOpacity(view->opacity());
30 return clone;
31 }
32
33 // Creates copies of all the visible children of |parent|. Newly cloned views
34 // are added to |cloned_parent| and have |delegate| as their delegate. The
35 // stacking order of the cloned views is preseved.
36 void CloneViewTree(const ServerView* parent,
37 ServerView* cloned_parent,
38 ServerViewDelegate* delegate) {
39 DCHECK(parent->visible());
40 for (const ServerView* to_clone : parent->GetChildren()) {
41 if (to_clone->visible()) {
42 ServerView* cloned = CloneView(to_clone, delegate);
43 cloned_parent->Add(cloned);
44 CloneViewTree(to_clone, cloned, delegate);
45 }
46 }
47 }
48
49 // Recurses through all the children of |view| moving any cloned views to
50 // |new_parent| stacked above |stack_above|. |stack_above| is updated as views
51 // are moved.
52 void ReparentClonedViews(ServerView* new_parent,
53 ServerView** stack_above,
54 ServerView* view) {
55 if (view->id() == ClonedViewId()) {
56 const gfx::Rect new_bounds(ConvertRectBetweenViews(
57 view, new_parent, gfx::Rect(view->bounds().size())));
58 new_parent->Add(view);
59 new_parent->Reorder(view, *stack_above, ORDER_DIRECTION_ABOVE);
60 view->SetBounds(new_bounds);
61 *stack_above = view;
62 return;
63 }
64
65 for (ServerView* child : view->GetChildren())
66 ReparentClonedViews(new_parent, stack_above, child);
67 }
68
69 // Deletes |view| and all its descendants.
70 void DeleteViewTree(ServerView* view) {
71 for (ServerView* child : view->GetChildren())
72 DeleteViewTree(child);
73
74 delete view;
75 }
76
77 // TODO(sky): nuke, proof of concept.
78 bool DecrementAnimatingViewsOpacity(ServerView* view) {
79 if (view->id() == ClonedViewId()) {
80 const float new_opacity = view->opacity() - .05f;
81 if (new_opacity <= 0)
82 DeleteViewTree(view);
83 else
84 view->SetOpacity(new_opacity);
85 return true;
86 }
87 bool ret_value = false;
88 for (ServerView* child : view->GetChildren()) {
89 if (DecrementAnimatingViewsOpacity(child))
90 ret_value = true;
91 }
92 return ret_value;
93 }
94
95 } // namespace
19 96
20 ConnectionManager::ScopedChange::ScopedChange( 97 ConnectionManager::ScopedChange::ScopedChange(
21 ViewManagerServiceImpl* connection, 98 ViewManagerServiceImpl* connection,
22 ConnectionManager* connection_manager, 99 ConnectionManager* connection_manager,
23 bool is_delete_view) 100 bool is_delete_view)
24 : connection_manager_(connection_manager), 101 : connection_manager_(connection_manager),
25 connection_id_(connection->id()), 102 connection_id_(connection->id()),
26 is_delete_view_(is_delete_view) { 103 is_delete_view_(is_delete_view) {
27 connection_manager_->PrepareForChange(this); 104 connection_manager_->PrepareForChange(this);
28 } 105 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 152
76 // Notify remaining connections so that they can cleanup. 153 // Notify remaining connections so that they can cleanup.
77 for (auto& pair : connection_map_) { 154 for (auto& pair : connection_map_) {
78 pair.second->service()->OnWillDestroyViewManagerServiceImpl( 155 pair.second->service()->OnWillDestroyViewManagerServiceImpl(
79 connection->service()); 156 connection->service());
80 } 157 }
81 } 158 }
82 159
83 void ConnectionManager::EmbedAtView( 160 void ConnectionManager::EmbedAtView(
84 ConnectionSpecificId creator_id, 161 ConnectionSpecificId creator_id,
85 const String& url, 162 const std::string& url,
86 Id transport_view_id, 163 const ViewId& view_id,
87 InterfaceRequest<ServiceProvider> service_provider) { 164 InterfaceRequest<ServiceProvider> service_provider) {
88 std::string creator_url; 165 std::string creator_url;
89 ConnectionMap::const_iterator it = connection_map_.find(creator_id); 166 ConnectionMap::const_iterator it = connection_map_.find(creator_id);
90 if (it != connection_map_.end()) 167 if (it != connection_map_.end())
91 creator_url = it->second->service()->url(); 168 creator_url = it->second->service()->url();
92 169
93 ClientConnection* client_connection = 170 ClientConnection* client_connection =
94 delegate_->CreateClientConnectionForEmbedAtView( 171 delegate_->CreateClientConnectionForEmbedAtView(
95 this, creator_id, creator_url, url.To<std::string>(), 172 this, creator_id, creator_url, url, view_id);
96 ViewIdFromTransportId(transport_view_id));
97 AddConnection(client_connection); 173 AddConnection(client_connection);
98 client_connection->service()->Init(client_connection->client(), 174 client_connection->service()->Init(client_connection->client(),
99 service_provider.Pass()); 175 service_provider.Pass());
100 OnConnectionMessagedClient(client_connection->service()->id()); 176 OnConnectionMessagedClient(client_connection->service()->id());
101 } 177 }
102 178
103 ViewManagerServiceImpl* ConnectionManager::GetConnection( 179 ViewManagerServiceImpl* ConnectionManager::GetConnection(
104 ConnectionSpecificId connection_id) { 180 ConnectionSpecificId connection_id) {
105 ConnectionMap::iterator i = connection_map_.find(connection_id); 181 ConnectionMap::iterator i = connection_map_.find(connection_id);
106 return i == connection_map_.end() ? nullptr : i->second->service(); 182 return i == connection_map_.end() ? nullptr : i->second->service();
(...skipping 28 matching lines...) Expand all
135 void ConnectionManager::SetWindowManagerClientConnection( 211 void ConnectionManager::SetWindowManagerClientConnection(
136 scoped_ptr<ClientConnection> connection) { 212 scoped_ptr<ClientConnection> connection) {
137 CHECK(!window_manager_client_connection_); 213 CHECK(!window_manager_client_connection_);
138 window_manager_client_connection_ = connection.release(); 214 window_manager_client_connection_ = connection.release();
139 AddConnection(window_manager_client_connection_); 215 AddConnection(window_manager_client_connection_);
140 window_manager_client_connection_->service()->Init( 216 window_manager_client_connection_->service()->Init(
141 window_manager_client_connection_->client(), 217 window_manager_client_connection_->client(),
142 InterfaceRequest<ServiceProvider>()); 218 InterfaceRequest<ServiceProvider>());
143 } 219 }
144 220
221 bool ConnectionManager::CloneAndAnimate(const ViewId& view_id) {
222 ServerView* view = GetView(view_id);
223 if (!view || !view->IsDrawn(root_.get()) || view == root_.get())
224 return false;
225 if (!animation_timer_.IsRunning()) {
226 animation_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(100),
227 this, &ConnectionManager::DoAnimation);
228 }
229 ServerView* clone = CloneView(view, this);
230 CloneViewTree(view, clone, this);
231 view->parent()->Add(clone);
232 view->parent()->Reorder(clone, view, ORDER_DIRECTION_ABOVE);
233 return true;
234 }
235
145 void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view, 236 void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view,
146 const gfx::Rect& old_bounds, 237 const gfx::Rect& old_bounds,
147 const gfx::Rect& new_bounds) { 238 const gfx::Rect& new_bounds) {
148 for (auto& pair : connection_map_) { 239 for (auto& pair : connection_map_) {
149 pair.second->service()->ProcessViewBoundsChanged( 240 pair.second->service()->ProcessViewBoundsChanged(
150 view, old_bounds, new_bounds, IsChangeSource(pair.first)); 241 view, old_bounds, new_bounds, IsChangeSource(pair.first));
151 } 242 }
152 } 243 }
153 244
154 void ConnectionManager::ProcessWillChangeViewHierarchy( 245 void ConnectionManager::ProcessWillChangeViewHierarchy(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 CHECK(!current_change_); 283 CHECK(!current_change_);
193 current_change_ = change; 284 current_change_ = change;
194 } 285 }
195 286
196 void ConnectionManager::FinishChange() { 287 void ConnectionManager::FinishChange() {
197 // PrepareForChange/FinishChange should be balanced. 288 // PrepareForChange/FinishChange should be balanced.
198 CHECK(current_change_); 289 CHECK(current_change_);
199 current_change_ = NULL; 290 current_change_ = NULL;
200 } 291 }
201 292
293 void ConnectionManager::DoAnimation() {
294 if (!DecrementAnimatingViewsOpacity(root()))
295 animation_timer_.Stop();
296 }
297
202 void ConnectionManager::AddConnection(ClientConnection* connection) { 298 void ConnectionManager::AddConnection(ClientConnection* connection) {
203 DCHECK_EQ(0u, connection_map_.count(connection->service()->id())); 299 DCHECK_EQ(0u, connection_map_.count(connection->service()->id()));
204 connection_map_[connection->service()->id()] = connection; 300 connection_map_[connection->service()->id()] = connection;
205 } 301 }
206 302
303 void ConnectionManager::OnWillDestroyView(ServerView* view) {
304 if (!in_destructor_ && root_->Contains(view) && view != root_.get() &&
305 view->id() != ClonedViewId()) {
306 // We're about to destroy a view. Any cloned views need to be reparented
307 // else the animation would no longer be visible. By moving to a visible
308 // view, view->parent(), we ensure the animation is still visible.
309 ServerView* parent_above = view;
310 ReparentClonedViews(view->parent(), &parent_above, view);
311 }
312 }
313
207 void ConnectionManager::OnViewDestroyed(const ServerView* view) { 314 void ConnectionManager::OnViewDestroyed(const ServerView* view) {
208 if (!in_destructor_) 315 if (!in_destructor_)
209 ProcessViewDeleted(view->id()); 316 ProcessViewDeleted(view->id());
210 } 317 }
211 318
212 void ConnectionManager::OnWillChangeViewHierarchy( 319 void ConnectionManager::OnWillChangeViewHierarchy(ServerView* view,
213 const ServerView* view, 320 ServerView* new_parent,
214 const ServerView* new_parent, 321 ServerView* old_parent) {
215 const ServerView* old_parent) { 322 if (view->id() == ClonedViewId() || in_destructor_)
216 if (!in_destructor_) 323 return;
217 ProcessWillChangeViewHierarchy(view, new_parent, old_parent); 324
325 if (root_->Contains(view) && view != root_.get()) {
326 // We're about to reparent a view. Any cloned views need to be reparented
327 // else the animation may be effected in unusual ways. For example, the view
328 // could move to a new location such that the animation is entirely clipped.
329 // By moving to view->parent() we ensure the animation is still visible.
330 ServerView* parent_above = view;
331 ReparentClonedViews(view->parent(), &parent_above, view);
332 }
333
334 ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
218 } 335 }
219 336
220 void ConnectionManager::OnViewHierarchyChanged(const ServerView* view, 337 void ConnectionManager::OnViewHierarchyChanged(const ServerView* view,
221 const ServerView* new_parent, 338 const ServerView* new_parent,
222 const ServerView* old_parent) { 339 const ServerView* old_parent) {
223 if (in_destructor_) 340 if (in_destructor_)
224 return; 341 return;
225 342
226 ProcessViewHierarchyChanged(view, new_parent, old_parent); 343 ProcessViewHierarchyChanged(view, new_parent, old_parent);
227 344
(...skipping 28 matching lines...) Expand all
256 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size())); 373 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
257 } 374 }
258 375
259 void ConnectionManager::OnViewReordered(const ServerView* view, 376 void ConnectionManager::OnViewReordered(const ServerView* view,
260 const ServerView* relative, 377 const ServerView* relative,
261 OrderDirection direction) { 378 OrderDirection direction) {
262 if (!in_destructor_) 379 if (!in_destructor_)
263 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size())); 380 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
264 } 381 }
265 382
266 void ConnectionManager::OnWillChangeViewVisibility(const ServerView* view) { 383 void ConnectionManager::OnWillChangeViewVisibility(ServerView* view) {
267 if (in_destructor_) 384 if (in_destructor_)
268 return; 385 return;
269 386
387 if (view != root_.get() && view->id() != ClonedViewId() &&
388 root_->Contains(view) && view->IsDrawn(root_.get())) {
389 // We're about to hide |view|, this would implicitly make any cloned views
390 // hide to. Reparent so that animations are still visible.
msw 2014/11/19 01:27:51 nit: "hide too"
391 ServerView* parent_above = view;
392 ReparentClonedViews(view->parent(), &parent_above, view);
393 }
394
270 for (auto& pair : connection_map_) { 395 for (auto& pair : connection_map_) {
271 pair.second->service()->ProcessWillChangeViewVisibility( 396 pair.second->service()->ProcessWillChangeViewVisibility(
272 view, IsChangeSource(pair.first)); 397 view, IsChangeSource(pair.first));
273 } 398 }
274 } 399 }
275 400
276 void ConnectionManager::OnViewSharedPropertyChanged( 401 void ConnectionManager::OnViewSharedPropertyChanged(
277 const ServerView* view, 402 const ServerView* view,
278 const std::string& name, 403 const std::string& name,
279 const std::vector<uint8_t>* new_data) { 404 const std::vector<uint8_t>* new_data) {
280 for (auto& pair : connection_map_) { 405 for (auto& pair : connection_map_) {
281 pair.second->service()->ProcessViewPropertyChanged( 406 pair.second->service()->ProcessViewPropertyChanged(
282 view, name, new_data, IsChangeSource(pair.first)); 407 view, name, new_data, IsChangeSource(pair.first));
283 } 408 }
284 } 409 }
285 410
286 void ConnectionManager::SetViewportSize(SizePtr size) { 411 void ConnectionManager::OnScheduleViewPaint(const ServerView* view) {
287 gfx::Size new_size = size.To<gfx::Size>(); 412 if (!in_destructor_)
288 display_manager_->SetViewportSize(new_size); 413 display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
289 } 414 }
290 415
291 void ConnectionManager::DispatchInputEventToView(Id transport_view_id, 416 void ConnectionManager::DispatchInputEventToView(Id transport_view_id,
292 EventPtr event) { 417 EventPtr event) {
293 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); 418 const ViewId view_id(ViewIdFromTransportId(transport_view_id));
294 419
295 ViewManagerServiceImpl* connection = GetConnectionWithRoot(view_id); 420 ViewManagerServiceImpl* connection = GetConnectionWithRoot(view_id);
296 if (!connection) 421 if (!connection)
297 connection = GetConnection(view_id.connection_id); 422 connection = GetConnection(view_id.connection_id);
298 if (connection) { 423 if (connection) {
299 connection->client()->OnViewInputEvent( 424 connection->client()->OnViewInputEvent(
300 transport_view_id, event.Pass(), base::Bind(&base::DoNothing)); 425 transport_view_id, event.Pass(), base::Bind(&base::DoNothing));
301 } 426 }
302 } 427 }
303 428
429 void ConnectionManager::SetViewportSize(SizePtr size) {
430 gfx::Size new_size = size.To<gfx::Size>();
431 display_manager_->SetViewportSize(new_size);
432 }
433
434 void ConnectionManager::CloneAndAnimate(Id transport_view_id) {
435 CloneAndAnimate(ViewIdFromTransportId(transport_view_id));
436 }
437
304 } // namespace service 438 } // namespace service
305 } // namespace mojo 439 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698