Chromium Code Reviews| 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 |