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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: athena/screen/modal_window_controller.cc
diff --git a/athena/screen/modal_window_controller.cc b/athena/screen/modal_window_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..71a19ff56500c26bed9cfcd778ddc5dc5d6df2ee
--- /dev/null
+++ b/athena/screen/modal_window_controller.cc
@@ -0,0 +1,146 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "athena/screen/modal_window_controller.h"
+
+#include "athena/screen/public/screen_manager.h"
+#include "base/message_loop/message_loop.h"
+#include "ui/aura/window.h"
+#include "ui/aura/window_property.h"
+#include "ui/compositor/layer.h"
+#include "ui/compositor/layer_animation_observer.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/wm/core/window_animations.h"
+
+namespace athena {
+namespace {
+
+DEFINE_OWNED_WINDOW_PROPERTY_KEY(ModalWindowController,
+ kModalWindowControllerKey,
+ NULL);
+
+} // namespace
+
+// static
+ModalWindowController* ModalWindowController::Get(aura::Window* container) {
+ ModalWindowController* controller =
+ container->GetProperty(kModalWindowControllerKey);
+ CHECK(controller);
+ return controller;
+}
+
+ModalWindowController::ModalWindowController(int priority)
+ : modal_container_(NULL),
+ dimmer_window_(new aura::Window(NULL)),
+ dimmed_(false) {
+ ScreenManager::ContainerParams params("ModalContainer", priority);
+ params.can_activate_children = true;
+ params.block_events = true;
+ modal_container_ = ScreenManager::Get()->CreateContainer(params);
+ modal_container_->SetProperty(kModalWindowControllerKey, this);
+
+ dimmer_window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
+ dimmer_window_->Init(aura::WINDOW_LAYER_SOLID_COLOR);
+ dimmer_window_->layer()->SetColor(SK_ColorBLACK);
+ dimmer_window_->layer()->SetOpacity(0.0f);
+ dimmer_window_->Show();
+
+ modal_container_->AddChild(dimmer_window_);
+ modal_container_->AddObserver(this);
+
+ UpdateDimmerWindowBounds();
+}
+
+ModalWindowController::~ModalWindowController() {
+ if (modal_container_)
+ modal_container_->RemoveObserver(this);
+}
+
+void ModalWindowController::OnWindowAdded(aura::Window* child) {
+ DCHECK_NE(child, dimmer_window_);
+ if (IsChildWindow(child)) {
+ child->AddObserver(this);
+ UpdateDimming(NULL);
+ }
+}
+
+void ModalWindowController::OnWindowVisibilityChanged(aura::Window* window,
+ bool visible) {
+ if (IsChildWindow(window))
+ UpdateDimming(NULL);
+}
+
+void ModalWindowController::OnWindowBoundsChanged(aura::Window* window,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {
+ if (window == modal_container_)
+ UpdateDimmerWindowBounds();
+}
+
+void ModalWindowController::OnWindowDestroyed(aura::Window* window) {
+ UpdateDimming(window);
+}
+
+bool ModalWindowController::IsChildWindow(aura::Window* child) const {
+ return child->parent() == modal_container_ && child != dimmer_window_;
+}
+
+void ModalWindowController::UpdateDimmerWindowBounds() {
+ gfx::Rect bounds(modal_container_->bounds().size());
+ dimmer_window_->SetBounds(bounds);
+}
+
+void ModalWindowController::UpdateDimming(aura::Window* ignore) {
+ if (!modal_container_ || !dimmer_window_)
+ return;
+ bool should_delete = true;
+ for (aura::Window* window : modal_container_->children()) {
+ if (window == dimmer_window_ || window == ignore)
+ continue;
+ should_delete = false;
+ if (window->TargetVisibility()) {
+ SetDimmed(true);
+ return;
+ }
+ }
+ SetDimmed(false);
+
+ if (should_delete) {
+ // Remove the container from root so that the container becomes
+ // invisible, but don't delete it until next event execution
+ // because the call stack may still have and use the pointer.
+ modal_container_->RemoveObserver(this);
+ modal_container_->parent()->RemoveChild(modal_container_);
+ base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, modal_container_);
+ modal_container_ = NULL;
+ dimmer_window_ = NULL;
+ }
+}
+
+void ModalWindowController::SetDimmed(bool dimmed) {
+ const float kDimmedOpacity = 0.4f;
+
+ if (!dimmer_window_ || dimmed_ == dimmed)
+ return;
+ dimmed_ = dimmed;
+
+ const int kDimmAnimationDurationMs = 500;
+ if (dimmed) {
+ ui::ScopedLayerAnimationSettings settings(
+ dimmer_window_->layer()->GetAnimator());
+ settings.SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kDimmAnimationDurationMs));
+ dimmer_window_->layer()->SetOpacity(kDimmedOpacity);
+ } else {
+ // ScopedHidingAnimationSettings will detach the animating and
+ // recreate layers for the container so that animation can continue
+ // even if the container is removed immediately.
+ wm::ScopedHidingAnimationSettings settings(modal_container_);
+ settings.layer_animation_settings()->SetTransitionDuration(
+ base::TimeDelta::FromMilliseconds(kDimmAnimationDurationMs));
+ modal_container_->layer()->SetOpacity(0.0f);
+ }
+}
+
+} // namespace athena
« 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