summaryrefslogtreecommitdiffstats
path: root/ash/wm/resize_shadow.cc
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-16 22:30:48 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-16 22:30:48 +0000
commitb0fcb0e709bc2731e6e71fbee0eb31b8a1ba7213 (patch)
tree091b318d966de6961cca373b1aef6dc79e1301bd /ash/wm/resize_shadow.cc
parent6f98f122e37c62262d9547a91d28b1bbaa6b90d2 (diff)
downloadchromium_src-b0fcb0e709bc2731e6e71fbee0eb31b8a1ba7213.zip
chromium_src-b0fcb0e709bc2731e6e71fbee0eb31b8a1ba7213.tar.gz
chromium_src-b0fcb0e709bc2731e6e71fbee0eb31b8a1ba7213.tar.bz2
Ash: Add resize border shadow effect
* Add ResizeShadow that uses solid-color layers to draw the resize border shadow effect. * Add ResizeShadowController to create ResizeShadows and track bounds changes for windows. * Wire both into ToplevelWindowEventFilter to track mouse move/enter events near (but not inside) the window frame. BUG=118325 TEST=visual, hover mouse near window edges, drag windows Review URL: https://chromiumcodereview.appspot.com/9677070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm/resize_shadow.cc')
-rw-r--r--ash/wm/resize_shadow.cc171
1 files changed, 171 insertions, 0 deletions
diff --git a/ash/wm/resize_shadow.cc b/ash/wm/resize_shadow.cc
new file mode 100644
index 0000000..983fdfb
--- /dev/null
+++ b/ash/wm/resize_shadow.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2012 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 "ash/wm/resize_shadow.h"
+
+#include "grit/ui_resources.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/aura/window.h"
+#include "ui/base/animation/slide_animation.h"
+#include "ui/base/hit_test.h"
+#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
+
+namespace {
+
+// Height or width for the resize border shadow.
+const int kShadowSize = 6;
+// Amount to inset the resize effect from the window corners.
+const int kShadowInset = 4;
+// Color for resize effect.
+const SkColor kShadowLayerColor = SkColorSetRGB(0, 0, 0);
+// Final opacity for resize effect.
+const int kShadowTargetOpacity = 64;
+// Animation time for resize effect in milliseconds.
+const int kShadowSlideDurationMs = 200;
+
+} // namespace
+
+namespace ash {
+namespace internal {
+
+ResizeShadow::ResizeShadow() {}
+
+ResizeShadow::~ResizeShadow() {}
+
+void ResizeShadow::Init(aura::Window* window) {
+ ui::Layer* parent = window->layer();
+ InitLayer(parent, &top_layer_);
+ InitLayer(parent, &left_layer_);
+ InitLayer(parent, &right_layer_);
+ InitLayer(parent, &bottom_layer_);
+ InitAnimation(&top_animation_);
+ InitAnimation(&left_animation_);
+ InitAnimation(&right_animation_);
+ InitAnimation(&bottom_animation_);
+}
+
+void ResizeShadow::ShowForHitTest(int hit_test) {
+ // TODO(jamescook): Add support for top_left, top_right, bottom_left, and
+ // bottom_right corners. This approach matches the mocks but looks a little
+ // funny.
+ bool top = false;
+ bool left = false;
+ bool right = false;
+ bool bottom = false;
+ switch (hit_test) {
+ case HTTOPLEFT:
+ top = true;
+ left = true;
+ break;
+ case HTTOP:
+ top = true;
+ break;
+ case HTTOPRIGHT:
+ top = true;
+ right = true;
+ break;
+ case HTLEFT:
+ left = true;
+ break;
+ case HTRIGHT:
+ right = true;
+ break;
+ case HTBOTTOMLEFT:
+ left = true;
+ bottom = true;
+ break;
+ case HTBOTTOM:
+ bottom = true;
+ break;
+ case HTBOTTOMRIGHT:
+ bottom = true;
+ right = true;
+ break;
+ default:
+ break;
+ }
+ if (top)
+ top_animation_->Show();
+ else
+ top_animation_->Hide();
+ if (left)
+ left_animation_->Show();
+ else
+ left_animation_->Hide();
+ if (right)
+ right_animation_->Show();
+ else
+ right_animation_->Hide();
+ if (bottom)
+ bottom_animation_->Show();
+ else
+ bottom_animation_->Hide();
+}
+
+void ResizeShadow::Hide() {
+ // Small optimization since we frequently invoke Hide().
+ if (top_animation_->IsShowing() ||
+ left_animation_->IsShowing() ||
+ right_animation_->IsShowing() ||
+ bottom_animation_->IsShowing())
+ ShowForHitTest(HTNOWHERE);
+}
+
+void ResizeShadow::Layout(const gfx::Rect& bounds) {
+ // Position the resize border effects near the window edges.
+ top_layer_->SetBounds(gfx::Rect(kShadowInset,
+ -kShadowSize,
+ bounds.width() - 2 * kShadowInset,
+ kShadowSize));
+ bottom_layer_->SetBounds(gfx::Rect(kShadowInset,
+ bounds.height(),
+ bounds.width() - 2 * kShadowInset,
+ kShadowSize));
+ left_layer_->SetBounds(gfx::Rect(-kShadowSize,
+ kShadowInset,
+ kShadowSize,
+ bounds.height() - 2 * kShadowInset));
+ right_layer_->SetBounds(gfx::Rect(bounds.width(),
+ kShadowInset,
+ kShadowSize,
+ bounds.height() - 2 * kShadowInset));
+}
+
+void ResizeShadow::AnimationProgressed(const ui::Animation* animation) {
+ int opacity = animation->CurrentValueBetween(0, kShadowTargetOpacity);
+ if (animation == top_animation_.get())
+ UpdateLayerOpacity(top_layer_.get(), opacity);
+ else if (animation == left_animation_.get())
+ UpdateLayerOpacity(left_layer_.get(), opacity);
+ else if (animation == right_animation_.get())
+ UpdateLayerOpacity(right_layer_.get(), opacity);
+ else if (animation == bottom_animation_.get())
+ UpdateLayerOpacity(bottom_layer_.get(), opacity);
+}
+
+void ResizeShadow::InitLayer(ui::Layer* parent,
+ scoped_ptr<ui::Layer>* new_layer) {
+ // Use solid colors because they don't require video memory.
+ new_layer->reset(new ui::Layer(ui::Layer::LAYER_SOLID_COLOR));
+ // Transparency must be part of the color for solid color layers.
+ // Start fully transparent so we can smoothly animate in.
+ new_layer->get()->SetColor(SkColorSetARGB(0, 0, 0, 0));
+ new_layer->get()->SetVisible(false);
+ parent->Add(new_layer->get());
+}
+
+void ResizeShadow::InitAnimation(scoped_ptr<ui::SlideAnimation>* animation) {
+ animation->reset(new ui::SlideAnimation(this));
+ animation->get()->SetSlideDuration(kShadowSlideDurationMs);
+}
+
+void ResizeShadow::UpdateLayerOpacity(ui::Layer* layer, int opacity) {
+ SkColor color = SkColorSetA(kShadowLayerColor, opacity);
+ layer->SetColor(color);
+ layer->SetVisible(opacity != 0);
+}
+
+} // namespace internal
+} // namespace ash