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

Side by Side Diff: athena/screen/modal_window_controller.cc

Issue 662763002: Support modal windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git/+/master
Patch Set: fix leaks Created 6 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "athena/screen/modal_window_controller.h"
6
7 #include "athena/screen/public/screen_manager.h"
8 #include "base/message_loop/message_loop.h"
9 #include "ui/aura/window.h"
10 #include "ui/aura/window_property.h"
11 #include "ui/compositor/layer.h"
12 #include "ui/compositor/layer_animation_observer.h"
13 #include "ui/compositor/scoped_layer_animation_settings.h"
14 #include "ui/wm/core/window_animations.h"
15
16 namespace athena {
17 namespace {
18
19 DEFINE_OWNED_WINDOW_PROPERTY_KEY(ModalWindowController,
20 kModalWindowControllerKey,
21 NULL);
22
23 } // namespace
24
25 // static
26 ModalWindowController* ModalWindowController::Get(aura::Window* container) {
27 ModalWindowController* controller =
28 container->GetProperty(kModalWindowControllerKey);
29 CHECK(controller);
30 return controller;
31 }
32
33 ModalWindowController::ModalWindowController(int priority)
34 : modal_container_(NULL),
35 dimmer_window_(new aura::Window(NULL)),
36 dimmed_(false) {
37 ScreenManager::ContainerParams params("ModalContainer", priority);
38 params.can_activate_children = true;
39 params.block_events = true;
40 modal_container_ = ScreenManager::Get()->CreateContainer(params);
41 modal_container_->SetProperty(kModalWindowControllerKey, this);
42
43 dimmer_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
44 dimmer_window_->Init(aura::WINDOW_LAYER_SOLID_COLOR);
45 dimmer_window_->layer()->SetColor(SK_ColorBLACK);
46 dimmer_window_->layer()->SetOpacity(0.0f);
47 dimmer_window_->Show();
48
49 modal_container_->AddChild(dimmer_window_);
50 modal_container_->AddObserver(this);
51
52 UpdateDimmerWindowBounds();
53 }
54
55 ModalWindowController::~ModalWindowController() {
56 if (modal_container_)
57 modal_container_->RemoveObserver(this);
58 }
59
60 void ModalWindowController::OnWindowAdded(aura::Window* child) {
61 DCHECK_NE(child, dimmer_window_);
62 if (IsChildWindow(child)) {
63 child->AddObserver(this);
64 UpdateDimming(NULL);
65 }
66 }
67
68 void ModalWindowController::OnWindowVisibilityChanged(aura::Window* window,
69 bool visible) {
70 if (IsChildWindow(window))
71 UpdateDimming(NULL);
72 }
73
74 void ModalWindowController::OnWindowBoundsChanged(aura::Window* window,
75 const gfx::Rect& old_bounds,
76 const gfx::Rect& new_bounds) {
77 if (window == modal_container_)
78 UpdateDimmerWindowBounds();
79 }
80
81 void ModalWindowController::OnWindowDestroyed(aura::Window* window) {
82 UpdateDimming(window);
83 }
84
85 bool ModalWindowController::IsChildWindow(aura::Window* child) const {
86 return child->parent() == modal_container_ && child != dimmer_window_;
87 }
88
89 void ModalWindowController::UpdateDimmerWindowBounds() {
90 gfx::Rect bounds(modal_container_->bounds().size());
91 dimmer_window_->SetBounds(bounds);
92 }
93
94 void ModalWindowController::UpdateDimming(aura::Window* ignore) {
95 if (!modal_container_ || !dimmer_window_)
96 return;
97 bool should_delete = true;
98 for (aura::Window* window : modal_container_->children()) {
99 if (window == dimmer_window_ || window == ignore)
100 continue;
101 should_delete = false;
102 if (window->TargetVisibility()) {
103 SetDimmed(true);
104 return;
105 }
106 }
107 SetDimmed(false);
108
109 if (should_delete) {
110 // Remove the container from root so that the container becomes
111 // invisible, but don't delete it until next event execution
112 // because the call stack may still have and use the pointer.
113 modal_container_->RemoveObserver(this);
114 modal_container_->parent()->RemoveChild(modal_container_);
115 base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, modal_container_);
116 modal_container_ = NULL;
117 dimmer_window_ = NULL;
118 }
119 }
120
121 void ModalWindowController::SetDimmed(bool dimmed) {
122 const float kDimmedOpacity = 0.4f;
123
124 if (!dimmer_window_ || dimmed_ == dimmed)
125 return;
126 dimmed_ = dimmed;
127
128 const int kDimmAnimationDurationMs = 500;
129 if (dimmed) {
130 ui::ScopedLayerAnimationSettings settings(
131 dimmer_window_->layer()->GetAnimator());
132 settings.SetTransitionDuration(
133 base::TimeDelta::FromMilliseconds(kDimmAnimationDurationMs));
134 dimmer_window_->layer()->SetOpacity(kDimmedOpacity);
135 } else {
136 // ScopedHidingAnimationSettings will detach the animating and
137 // recreate layers for the container so that animation can continue
138 // even if the container is removed immediately.
139 wm::ScopedHidingAnimationSettings settings(modal_container_);
140 settings.layer_animation_settings()->SetTransitionDuration(
141 base::TimeDelta::FromMilliseconds(kDimmAnimationDurationMs));
142 modal_container_->layer()->SetOpacity(0.0f);
143 }
144 }
145
146 } // namespace athena
OLDNEW
« no previous file with comments | « athena/screen/modal_window_controller.h ('k') | athena/screen/modal_window_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698