OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/aura/window.h" | 5 #include "ui/aura/window.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "ui/aura/client/stacking_client.h" | 11 #include "ui/aura/client/stacking_client.h" |
12 #include "ui/aura/desktop.h" | 12 #include "ui/aura/desktop.h" |
13 #include "ui/aura/event.h" | 13 #include "ui/aura/event.h" |
14 #include "ui/aura/event_filter.h" | 14 #include "ui/aura/event_filter.h" |
15 #include "ui/aura/layout_manager.h" | 15 #include "ui/aura/layout_manager.h" |
| 16 #include "ui/aura/shadow.h" |
16 #include "ui/aura/window_delegate.h" | 17 #include "ui/aura/window_delegate.h" |
17 #include "ui/aura/window_observer.h" | 18 #include "ui/aura/window_observer.h" |
18 #include "ui/aura/window_types.h" | 19 #include "ui/aura/window_types.h" |
19 #include "ui/base/animation/multi_animation.h" | 20 #include "ui/base/animation/multi_animation.h" |
20 #include "ui/gfx/canvas_skia.h" | 21 #include "ui/gfx/canvas_skia.h" |
21 #include "ui/gfx/compositor/compositor.h" | 22 #include "ui/gfx/compositor/compositor.h" |
22 #include "ui/gfx/screen.h" | 23 #include "ui/gfx/screen.h" |
23 | 24 |
24 namespace aura { | 25 namespace aura { |
25 | 26 |
26 Window::Window(WindowDelegate* delegate) | 27 Window::Window(WindowDelegate* delegate) |
27 : type_(WINDOW_TYPE_UNKNOWN), | 28 : type_(WINDOW_TYPE_UNKNOWN), |
28 delegate_(delegate), | 29 delegate_(delegate), |
29 parent_(NULL), | 30 parent_(NULL), |
30 transient_parent_(NULL), | 31 transient_parent_(NULL), |
31 id_(-1), | 32 id_(-1), |
32 user_data_(NULL), | 33 user_data_(NULL), |
33 stops_event_propagation_(false) { | 34 stops_event_propagation_(false), |
| 35 show_shadow_(false) { |
34 } | 36 } |
35 | 37 |
36 Window::~Window() { | 38 Window::~Window() { |
37 // Let the delegate know we're in the processing of destroying. | 39 // Let the delegate know we're in the processing of destroying. |
38 if (delegate_) | 40 if (delegate_) |
39 delegate_->OnWindowDestroying(); | 41 delegate_->OnWindowDestroying(); |
40 | 42 |
41 // Let the root know so that it can remove any references to us. | 43 // Let the root know so that it can remove any references to us. |
42 Desktop* desktop = GetDesktop(); | 44 Desktop* desktop = GetDesktop(); |
43 if (desktop) | 45 if (desktop) |
(...skipping 23 matching lines...) Expand all Loading... |
67 if (parent_) | 69 if (parent_) |
68 parent_->RemoveChild(this); | 70 parent_->RemoveChild(this); |
69 | 71 |
70 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroyed(this)); | 72 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroyed(this)); |
71 } | 73 } |
72 | 74 |
73 void Window::Init(ui::Layer::LayerType layer_type) { | 75 void Window::Init(ui::Layer::LayerType layer_type) { |
74 layer_.reset(new ui::Layer(Desktop::GetInstance()->compositor(), layer_type)); | 76 layer_.reset(new ui::Layer(Desktop::GetInstance()->compositor(), layer_type)); |
75 layer_->SetVisible(false); | 77 layer_->SetVisible(false); |
76 layer_->set_delegate(this); | 78 layer_->set_delegate(this); |
| 79 |
| 80 if (show_shadow_) |
| 81 InitShadow(); |
77 } | 82 } |
78 | 83 |
79 void Window::SetType(WindowType type) { | 84 void Window::SetType(WindowType type) { |
80 // Cannot change type after the window is initialized. | 85 // Cannot change type after the window is initialized. |
81 DCHECK(!layer()); | 86 DCHECK(!layer()); |
82 type_ = type; | 87 type_ = type; |
83 } | 88 } |
84 | 89 |
85 void Window::Show() { | 90 void Window::Show() { |
86 SetVisible(true); | 91 SetVisible(true); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 std::find(children_.begin(), children_.end(), other) - children_.begin(); | 188 std::find(children_.begin(), children_.end(), other) - children_.begin(); |
184 if (child_i > other_i) | 189 if (child_i > other_i) |
185 return; // Already in front of |other|. | 190 return; // Already in front of |other|. |
186 | 191 |
187 // Reorder children. | 192 // Reorder children. |
188 children_.erase(children_.begin() + child_i); | 193 children_.erase(children_.begin() + child_i); |
189 children_.insert(children_.begin() + other_i, child); | 194 children_.insert(children_.begin() + other_i, child); |
190 | 195 |
191 // Reorder the layer. | 196 // Reorder the layer. |
192 layer()->MoveAbove(child->layer(), other->layer()); | 197 layer()->MoveAbove(child->layer(), other->layer()); |
| 198 if (child->shadow_.get()) |
| 199 layer()->MoveAbove(child->shadow_->layer(), other->layer()); |
193 | 200 |
194 // Move any transient children that share the same parent to be in front of | 201 // Move any transient children that share the same parent to be in front of |
195 // 'child'. | 202 // 'child'. |
196 Window* last_transient = child; | 203 Window* last_transient = child; |
197 for (Windows::iterator i = child->transient_children_.begin(); | 204 for (Windows::iterator i = child->transient_children_.begin(); |
198 i != child->transient_children_.end(); ++i) { | 205 i != child->transient_children_.end(); ++i) { |
199 Window* transient_child = *i; | 206 Window* transient_child = *i; |
200 if (transient_child->parent_ == this) { | 207 if (transient_child->parent_ == this) { |
201 MoveChildAbove(transient_child, last_transient); | 208 MoveChildAbove(transient_child, last_transient); |
202 last_transient = transient_child; | 209 last_transient = transient_child; |
203 } | 210 } |
204 } | 211 } |
205 } | 212 } |
206 | 213 |
207 bool Window::CanActivate() const { | 214 bool Window::CanActivate() const { |
208 return IsVisible() && (!delegate_ || delegate_->ShouldActivate(NULL)); | 215 return IsVisible() && (!delegate_ || delegate_->ShouldActivate(NULL)); |
209 } | 216 } |
210 | 217 |
211 void Window::AddChild(Window* child) { | 218 void Window::AddChild(Window* child) { |
212 DCHECK(std::find(children_.begin(), children_.end(), child) == | 219 DCHECK(std::find(children_.begin(), children_.end(), child) == |
213 children_.end()); | 220 children_.end()); |
214 if (child->parent()) | 221 if (child->parent()) |
215 child->parent()->RemoveChild(child); | 222 child->parent()->RemoveChild(child); |
216 child->parent_ = this; | 223 child->parent_ = this; |
| 224 |
| 225 if (child->shadow_.get()) |
| 226 layer_->Add(child->shadow_->layer()); |
217 layer_->Add(child->layer_.get()); | 227 layer_->Add(child->layer_.get()); |
| 228 |
218 children_.push_back(child); | 229 children_.push_back(child); |
219 if (layout_manager_.get()) | 230 if (layout_manager_.get()) |
220 layout_manager_->OnWindowAddedToLayout(child); | 231 layout_manager_->OnWindowAddedToLayout(child); |
221 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child)); | 232 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowAdded(child)); |
222 } | 233 } |
223 | 234 |
224 void Window::AddTransientChild(Window* child) { | 235 void Window::AddTransientChild(Window* child) { |
225 if (child->transient_parent_) | 236 if (child->transient_parent_) |
226 child->transient_parent_->RemoveTransientChild(child); | 237 child->transient_parent_->RemoveTransientChild(child); |
227 DCHECK(std::find(transient_children_.begin(), transient_children_.end(), | 238 DCHECK(std::find(transient_children_.begin(), transient_children_.end(), |
(...skipping 15 matching lines...) Expand all Loading... |
243 Windows::iterator i = std::find(children_.begin(), children_.end(), child); | 254 Windows::iterator i = std::find(children_.begin(), children_.end(), child); |
244 DCHECK(i != children_.end()); | 255 DCHECK(i != children_.end()); |
245 if (layout_manager_.get()) | 256 if (layout_manager_.get()) |
246 layout_manager_->OnWillRemoveWindowFromLayout(child); | 257 layout_manager_->OnWillRemoveWindowFromLayout(child); |
247 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); | 258 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWillRemoveWindow(child)); |
248 aura::Window* desktop = child->GetDesktop(); | 259 aura::Window* desktop = child->GetDesktop(); |
249 child->parent_ = NULL; | 260 child->parent_ = NULL; |
250 if (desktop) | 261 if (desktop) |
251 desktop->WindowDetachedFromDesktop(child); | 262 desktop->WindowDetachedFromDesktop(child); |
252 layer_->Remove(child->layer_.get()); | 263 layer_->Remove(child->layer_.get()); |
| 264 if (child->shadow_.get()) |
| 265 layer_->Remove(child->shadow_->layer()); |
253 children_.erase(i); | 266 children_.erase(i); |
254 } | 267 } |
255 | 268 |
256 Window* Window::GetChildById(int id) { | 269 Window* Window::GetChildById(int id) { |
257 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id)); | 270 return const_cast<Window*>(const_cast<const Window*>(this)->GetChildById(id)); |
258 } | 271 } |
259 | 272 |
260 const Window* Window::GetChildById(int id) const { | 273 const Window* Window::GetChildById(int id) const { |
261 Windows::const_iterator i; | 274 Windows::const_iterator i; |
262 for (i = children_.begin(); i != children_.end(); ++i) { | 275 for (i = children_.begin(); i != children_.end(); ++i) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 if (iter == prop_map_.end()) | 411 if (iter == prop_map_.end()) |
399 return NULL; | 412 return NULL; |
400 return iter->second; | 413 return iter->second; |
401 } | 414 } |
402 | 415 |
403 int Window::GetIntProperty(const char* name) const { | 416 int Window::GetIntProperty(const char* name) const { |
404 return static_cast<int>(reinterpret_cast<intptr_t>( | 417 return static_cast<int>(reinterpret_cast<intptr_t>( |
405 GetProperty(name))); | 418 GetProperty(name))); |
406 } | 419 } |
407 | 420 |
| 421 void Window::SetShadowVisible(bool visible) { |
| 422 show_shadow_ = visible; |
| 423 if (visible && !shadow_.get() && layer()) |
| 424 InitShadow(); |
| 425 else if (shadow_.get()) |
| 426 shadow_->layer()->SetVisible(visible); |
| 427 } |
| 428 |
408 Desktop* Window::GetDesktop() { | 429 Desktop* Window::GetDesktop() { |
409 return parent_ ? parent_->GetDesktop() : NULL; | 430 return parent_ ? parent_->GetDesktop() : NULL; |
410 } | 431 } |
411 | 432 |
412 void Window::WindowDetachedFromDesktop(aura::Window* window) { | 433 void Window::WindowDetachedFromDesktop(aura::Window* window) { |
413 } | 434 } |
414 | 435 |
415 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) { | 436 void Window::SetBoundsInternal(const gfx::Rect& new_bounds) { |
416 const gfx::Rect old_bounds = layer_->GetTargetBounds(); | 437 const gfx::Rect old_bounds = layer_->GetTargetBounds(); |
417 | 438 |
418 // Always need to set the layer's bounds -- even if it is to the same thing. | 439 // Always need to set the layer's bounds -- even if it is to the same thing. |
419 // This may cause important side effects such as stopping animation. | 440 // This may cause important side effects such as stopping animation. |
420 layer_->SetBounds(new_bounds); | 441 layer_->SetBounds(new_bounds); |
| 442 if (shadow_.get()) |
| 443 shadow_->SetContentBounds(new_bounds); |
421 | 444 |
422 // If we're not changing the effective bounds, then we can bail early and skip | 445 // If we're not changing the effective bounds, then we can bail early and skip |
423 // notifying our listeners. | 446 // notifying our listeners. |
424 if (old_bounds == new_bounds) | 447 if (old_bounds == new_bounds) |
425 return; | 448 return; |
426 | 449 |
427 if (layout_manager_.get()) | 450 if (layout_manager_.get()) |
428 layout_manager_->OnWindowResized(); | 451 layout_manager_->OnWindowResized(); |
429 if (delegate_) | 452 if (delegate_) |
430 delegate_->OnBoundsChanged(old_bounds, new_bounds); | 453 delegate_->OnBoundsChanged(old_bounds, new_bounds); |
431 } | 454 } |
432 | 455 |
433 void Window::SetVisible(bool visible) { | 456 void Window::SetVisible(bool visible) { |
434 if (visible == layer_->visible()) | 457 if (visible == layer_->visible()) |
435 return; // No change. | 458 return; // No change. |
436 | 459 |
437 bool was_visible = IsVisible(); | 460 bool was_visible = IsVisible(); |
438 layer_->SetVisible(visible); | 461 layer_->SetVisible(visible); |
439 bool is_visible = IsVisible(); | 462 bool is_visible = IsVisible(); |
440 if (was_visible != is_visible) { | 463 if (was_visible != is_visible) { |
441 SchedulePaint(); | 464 SchedulePaint(); |
442 if (delegate_) | 465 if (delegate_) |
443 delegate_->OnWindowVisibilityChanged(is_visible); | 466 delegate_->OnWindowVisibilityChanged(is_visible); |
444 } | 467 } |
| 468 |
| 469 if (shadow_.get()) |
| 470 shadow_->layer()->SetVisible(show_shadow_ && visible); |
| 471 |
445 if (parent_ && parent_->layout_manager_.get()) | 472 if (parent_ && parent_->layout_manager_.get()) |
446 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible); | 473 parent_->layout_manager_->OnChildWindowVisibilityChanged(this, visible); |
447 FOR_EACH_OBSERVER(WindowObserver, observers_, | 474 FOR_EACH_OBSERVER(WindowObserver, observers_, |
448 OnWindowVisibilityChanged(this, visible)); | 475 OnWindowVisibilityChanged(this, visible)); |
449 } | 476 } |
450 | 477 |
451 void Window::SchedulePaint() { | 478 void Window::SchedulePaint() { |
452 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height())); | 479 SchedulePaintInRect(gfx::Rect(0, 0, bounds().width(), bounds().height())); |
453 } | 480 } |
454 | 481 |
(...skipping 28 matching lines...) Expand all Loading... |
483 if (match) | 510 if (match) |
484 return match; | 511 return match; |
485 | 512 |
486 if (for_event_handling && child->StopsEventPropagation()) | 513 if (for_event_handling && child->StopsEventPropagation()) |
487 break; | 514 break; |
488 } | 515 } |
489 | 516 |
490 return delegate_ ? this : NULL; | 517 return delegate_ ? this : NULL; |
491 } | 518 } |
492 | 519 |
| 520 void Window::InitShadow() { |
| 521 DCHECK(layer()); |
| 522 |
| 523 shadow_.reset(new internal::Shadow()); |
| 524 shadow_->Init(); |
| 525 if (parent_) { |
| 526 // Stack the shadow directly below |layer_|. |
| 527 parent_->layer_->Add(shadow_->layer()); |
| 528 // TODO(derat): Add a MoveBelow() method and use that instead (although we |
| 529 // then run the risk of things getting stacked between a window and its |
| 530 // shadow). |
| 531 parent_->layer_->MoveAbove(shadow_->layer(), layer_.get()); |
| 532 parent_->layer_->MoveAbove(layer_.get(), shadow_->layer()); |
| 533 } |
| 534 |
| 535 shadow_->SetContentBounds(bounds()); |
| 536 shadow_->layer()->SetVisible(show_shadow_); |
| 537 } |
| 538 |
493 void Window::OnPaintLayer(gfx::Canvas* canvas) { | 539 void Window::OnPaintLayer(gfx::Canvas* canvas) { |
494 if (delegate_) | 540 if (delegate_) |
495 delegate_->OnPaint(canvas); | 541 delegate_->OnPaint(canvas); |
496 } | 542 } |
497 | 543 |
498 } // namespace aura | 544 } // namespace aura |
OLD | NEW |