Index: ash/wm/workspace/phantom_window_controller.cc |
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc |
index cebcb2a76510b77be63ce1207d55aa72a164dd5b..31e7d821ab3f5a538fc3584711278cd08a470cd3 100644 |
--- a/ash/wm/workspace/phantom_window_controller.cc |
+++ b/ash/wm/workspace/phantom_window_controller.cc |
@@ -8,12 +8,16 @@ |
#include "ash/shell_window_ids.h" |
#include "ash/wm/coordinate_conversion.h" |
#include "third_party/skia/include/core/SkCanvas.h" |
+#include "ui/aura/client/screen_position_client.h" |
+#include "ui/aura/root_window.h" |
#include "ui/aura/window.h" |
+#include "ui/aura/window_delegate.h" |
#include "ui/aura/window_observer.h" |
#include "ui/base/animation/slide_animation.h" |
#include "ui/compositor/layer.h" |
#include "ui/compositor/scoped_layer_animation_settings.h" |
#include "ui/gfx/canvas.h" |
+#include "ui/gfx/screen.h" |
#include "ui/gfx/skia_util.h" |
#include "ui/views/painter.h" |
#include "ui/views/view.h" |
@@ -30,7 +34,7 @@ const int kInsetSize = 4; |
// Size of the round rect used by EdgePainter. |
const int kRoundRectSize = 4; |
-// Paints the background of the phantom window. |
+// Paints the background of the phantom window for window snapping. |
class EdgePainter : public views::Painter { |
public: |
EdgePainter() {} |
@@ -70,12 +74,51 @@ class EdgePainter : public views::Painter { |
DISALLOW_COPY_AND_ASSIGN(EdgePainter); |
}; |
+// Paints the background of the phantom window for window dragging. |
+class WindowPainter : public views::Painter, |
+ public aura::WindowObserver { |
+ public: |
+ explicit WindowPainter(aura::Window* window) |
+ : window_(window) { |
+ window_->AddObserver(this); |
+ } |
+ |
+ virtual ~WindowPainter() { |
+ if (window_) |
+ window_->RemoveObserver(this); |
+ } |
+ |
+ // views::Painter overrides: |
+ virtual void Paint(gfx::Canvas* canvas, const gfx::Size& size) OVERRIDE { |
+ if (window_ && window_->delegate()) |
+ window_->delegate()->OnPaint(canvas); |
+ } |
+ |
+ private: |
+ // aura::WindowObserver overrides: |
+ virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE { |
+ DCHECK_EQ(window_, window); |
+ window_ = NULL; |
+ } |
+ |
+ aura::Window* window_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WindowPainter); |
+}; |
+ |
} // namespace |
-PhantomWindowController::PhantomWindowController(aura::Window* window) |
+PhantomWindowController::PhantomWindowController(aura::Window* window, |
+ aura::RootWindow* root_window, |
sky
2012/08/09 16:23:16
I would rather see a set_style and SetDestinationD
Yusuke Sato
2012/08/09 20:00:17
Done.
|
+ Style style) |
: window_(window), |
phantom_below_window_(NULL), |
- phantom_widget_(NULL) { |
+ phantom_widget_(NULL), |
+ style_(style) { |
+ if (root_window) { |
+ dst_display_ = |
+ gfx::Screen::GetDisplayMatching(root_window->GetBoundsInScreen()); |
+ } |
} |
PhantomWindowController::~PhantomWindowController() { |
@@ -102,7 +145,7 @@ void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { |
DCHECK(IsShowing()); |
animation_.reset(); |
bounds_ = bounds; |
- phantom_widget_->SetBounds(bounds_); |
+ SetBoundsInternal(bounds); |
} |
void PhantomWindowController::Hide() { |
@@ -115,16 +158,33 @@ bool PhantomWindowController::IsShowing() const { |
return phantom_widget_ != NULL; |
} |
+void PhantomWindowController::SetOpacity(float opacity) { |
+ ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); |
sky
2012/08/09 16:23:16
phantom_widget_ may be NULL.
Yusuke Sato
2012/08/09 20:00:17
Thanks. Done.
|
+ ui::ScopedLayerAnimationSettings scoped_setter(layer->GetAnimator()); |
+ layer->SetOpacity(opacity); |
+} |
+ |
+float PhantomWindowController::GetOpacity() const { |
+ return phantom_widget_->GetNativeWindow()->layer()->opacity(); |
sky
2012/08/09 16:23:16
phanton_widget_ may be NULL.
Yusuke Sato
2012/08/09 20:00:17
Done.
|
+} |
+ |
void PhantomWindowController::AnimationProgressed( |
const ui::Animation* animation) { |
- phantom_widget_->SetBounds( |
- animation->CurrentValueBetween(start_bounds_, bounds_)); |
+ SetBoundsInternal(animation->CurrentValueBetween(start_bounds_, bounds_)); |
} |
void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { |
DCHECK(!phantom_widget_); |
phantom_widget_ = new views::Widget; |
- views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
+ views::Widget::InitParams params; |
+ switch (style_) { |
+ case STYLE_SHADOW: |
+ params.type = views::Widget::InitParams::TYPE_POPUP; |
+ break; |
+ case STYLE_WINDOW: |
+ params.type = views::Widget::InitParams::TYPE_WINDOW; |
sky
2012/08/09 16:23:16
Why does this need to be a WINDOW?
Yusuke Sato
2012/08/09 20:00:17
POPUP is fine. Reverted this part. Thanks.
|
+ break; |
+ } |
params.transparent = true; |
// PhantomWindowController is used by FrameMaximizeButton to highlight the |
// launcher button. Put the phantom in the same window as the launcher so that |
@@ -138,10 +198,18 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { |
phantom_widget_->SetVisibilityChangedAnimationsEnabled(false); |
phantom_widget_->GetNativeWindow()->SetName("PhantomWindow"); |
views::View* content_view = new views::View; |
- content_view->set_background( |
- views::Background::CreateBackgroundPainter(true, new EdgePainter)); |
+ switch (style_) { |
+ case STYLE_SHADOW: |
+ content_view->set_background( |
+ views::Background::CreateBackgroundPainter(true, new EdgePainter)); |
+ break; |
+ case STYLE_WINDOW: |
+ content_view->set_background(views::Background::CreateBackgroundPainter( |
+ true, new WindowPainter(window_))); |
+ break; |
+ } |
phantom_widget_->SetContentsView(content_view); |
- phantom_widget_->SetBounds(bounds); |
+ SetBoundsInternal(bounds); |
if (phantom_below_window_) |
phantom_widget_->StackBelow(phantom_below_window_); |
else |
@@ -154,5 +222,15 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { |
layer->SetOpacity(1); |
} |
+void PhantomWindowController::SetBoundsInternal(const gfx::Rect& bounds) { |
+ aura::Window* window = phantom_widget_->GetNativeWindow(); |
+ aura::client::ScreenPositionClient* screen_position_client = |
+ aura::client::GetScreenPositionClient(window->GetRootWindow()); |
+ if (screen_position_client && dst_display_.id() != -1) |
+ screen_position_client->SetBounds(window, bounds, dst_display_); |
+ else |
+ phantom_widget_->SetBounds(bounds); |
+} |
+ |
} // namespace internal |
} // namespace ash |