Chromium Code Reviews| Index: ash/wm/maximize_bubble_controller.cc |
| diff --git a/ash/wm/maximize_bubble_controller.cc b/ash/wm/maximize_bubble_controller.cc |
| index 601a9997a97936d66e1b3f3b71143b8a7164c650..96280ed3bb82af5c9185ab886450bdb99d3a0b29 100644 |
| --- a/ash/wm/maximize_bubble_controller.cc |
| +++ b/ash/wm/maximize_bubble_controller.cc |
| @@ -11,12 +11,15 @@ |
| #include "base/timer.h" |
| #include "grit/ash_strings.h" |
| #include "grit/ui_resources.h" |
| +#include "third_party/skia/include/core/SkPath.h" |
| #include "ui/aura/event.h" |
| #include "ui/aura/focus_manager.h" |
| #include "ui/aura/window.h" |
| +#include "ui/base/animation/animation.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/gfx/canvas.h" |
| +#include "ui/gfx/path.h" |
| #include "ui/gfx/screen.h" |
| #include "ui/views/bubble/bubble_delegate.h" |
| #include "ui/views/bubble/bubble_frame_view.h" |
| @@ -42,13 +45,18 @@ const SkColor kBubbleTextColor = SK_ColorWHITE; |
| // The line width of the bubble. |
| const int kLineWidth = 1; |
| +// The spacing for the top and bottom of the info label. |
| +const int kLabelSpacing = 4; |
| + |
| // The pixel dimensions of the arrow. |
| const int kArrowHeight = 10; |
| const int kArrowWidth = 20; |
| // The delay of the bubble appearance. |
| const int kBubbleAppearanceDelayMS = 200; |
| -const int kAnimationDurationForPopupMS = 200; |
| + |
| +// The animation offset in y for the bubble when appearing. |
| +const int kBubbleAnimationOffsetY = 5; |
| class MaximizeBubbleBorder : public views::BubbleBorder { |
| public: |
| @@ -63,6 +71,10 @@ class MaximizeBubbleBorder : public views::BubbleBorder { |
| // Overridden from views::Border. |
| virtual void Paint(const views::View& view, |
| gfx::Canvas* canvas) const OVERRIDE; |
| + |
| + // Get the mouse active area of the window. |
|
sky
2012/08/07 23:11:18
Move this above overriden methods.
Mr4D (OOO till 08-26)
2012/08/08 01:02:28
Done.
|
| + void GetMask(gfx::Path* mask); |
| + |
| private: |
| views::View* anchor_; |
| views::View* content_view_; |
| @@ -149,6 +161,24 @@ void MaximizeBubbleBorder::Paint(const views::View& view, |
| canvas->DrawPath(path, paint); |
| } |
| +void MaximizeBubbleBorder::GetMask(gfx::Path* mask) { |
| + gfx::Insets inset; |
| + GetInsets(&inset); |
| + // Note: Even though the tip could be added as activatable, it is left out |
| + // since it would not change the action behavior in any way plus it makes |
| + // more sense to keep the focus on the underlying button for clicks. |
| + int left = inset.left() - kLineWidth; |
| + int right = inset.left() + content_view_->width() + kLineWidth; |
| + int top = inset.top() - kLineWidth; |
| + int bottom = inset.top() + content_view_->height() + kLineWidth; |
| + mask->moveTo(left, top); |
| + mask->lineTo(right, top); |
| + mask->lineTo(right, bottom); |
| + mask->lineTo(left, bottom); |
| + mask->lineTo(left, top); |
| + mask->close(); |
| +} |
| + |
| } // namespace |
| namespace ash { |
| @@ -191,6 +221,13 @@ class MaximizeBubbleController::Bubble : public views::BubbleDelegateView, |
| // Overridden from views::BubbleDelegateView. |
| virtual gfx::Rect GetAnchorRect() OVERRIDE; |
| + // Since the window delegate does not support horizontal shifts, this |
|
sky
2012/08/07 23:11:18
This comment doesn't make any sense. Either way, m
Mr4D (OOO till 08-26)
2012/08/08 01:02:28
Done.
|
| + // function will add this behavior to the animation. |
| + virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; |
| + |
| + // Overridden from views::WidgetDelegateView. |
| + virtual bool HasHitTestMask() const OVERRIDE; |
| + virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE; |
| // Implementation of MouseWatcherListener. |
| virtual void MouseMovedOutOfHost(); |
| @@ -230,6 +267,12 @@ class MaximizeBubbleController::Bubble : public views::BubbleDelegateView, |
| // The content accessor of the menu. |
| BubbleContentsView* contents_view_; |
| + // The bubble border. |
| + MaximizeBubbleBorder* bubble_border_; |
| + |
| + // The rectangle before the animation starts. |
| + gfx::Rect initial_position_; |
| + |
| // The mouse watcher which takes care of out of window hover events. |
| scoped_ptr<views::MouseWatcher> mouse_watcher_; |
| @@ -316,7 +359,8 @@ MaximizeBubbleController::Bubble::Bubble(MaximizeBubbleController* owner) |
| shutting_down_(false), |
| owner_(owner), |
| bubble_widget_(NULL), |
| - contents_view_(NULL) { |
| + contents_view_(NULL), |
| + bubble_border_(NULL) { |
| set_margins(gfx::Insets()); |
| // The window needs to be owned by the root so that the SnapSizer does not |
| @@ -348,35 +392,16 @@ MaximizeBubbleController::Bubble::Bubble(MaximizeBubbleController* owner) |
| SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
| bubble_widget_->non_client_view()->frame_view()->set_background(NULL); |
| - MaximizeBubbleBorder* bubble_border = new MaximizeBubbleBorder( |
| - this, |
| - anchor_view()); |
| - GetBubbleFrameView()->SetBubbleBorder(bubble_border); |
| + bubble_border_ = new MaximizeBubbleBorder(this, anchor_view()); |
| + GetBubbleFrameView()->SetBubbleBorder(bubble_border_); |
| GetBubbleFrameView()->set_background(NULL); |
| // Recalculate size with new border. |
| SizeToContents(); |
| - // Setup animation. |
| - ash::SetWindowVisibilityAnimationType( |
| - bubble_widget_->GetNativeWindow(), |
| - ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| - ash::SetWindowVisibilityAnimationTransition( |
| - bubble_widget_->GetNativeWindow(), |
| - ash::ANIMATE_BOTH); |
| - ash::SetWindowVisibilityAnimationDuration( |
| - bubble_widget_->GetNativeWindow(), |
| - base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS)); |
| - |
| - Show(); |
| - // We don't want to lose the focus on our parent window because the button |
| - // would otherwise lose the highlight when the "helper bubble" is shown. |
| - views::Widget* widget = |
| - owner_->frame_maximize_button()->parent()->GetWidget(); |
| - if (widget) { |
| - aura::Window* parent_window = widget->GetNativeWindow(); |
| - parent_window->GetFocusManager()->SetFocusedWindow(parent_window, NULL); |
| - } |
| + initial_position_ = bubble_widget_->GetNativeWindow()->bounds(); |
|
sky
2012/08/07 23:11:18
Do you really need this here since you only care a
Mr4D (OOO till 08-26)
2012/08/08 01:02:28
Done.
|
| + StartFade(true); |
| + |
| mouse_watcher_.reset(new views::MouseWatcher( |
| new BubbleMouseWatcherHost(this), |
| this)); |
| @@ -402,6 +427,32 @@ gfx::Rect MaximizeBubbleController::Bubble::GetAnchorRect() { |
| return anchor_rect; |
| } |
| +void MaximizeBubbleController::Bubble::AnimationProgressed( |
| + const ui::Animation* animation) OVERRIDE { |
| + // First do everything needed for the fade by calling the base function. |
| + BubbleDelegateView::AnimationProgressed(animation); |
| + // When fading in we are done. |
| + if (!shutting_down_) |
| + return; |
| + // Upon fade out an additional shift is required. |
| + int shift = ceil((1.0 - animation->GetCurrentValue()) * |
|
sky
2012/08/07 23:11:18
animation->CurrentValueBetween(...);
Mr4D (OOO till 08-26)
2012/08/08 01:02:28
Done.
|
| + kBubbleAnimationOffsetY); |
| + gfx::Rect rect = initial_position_; |
| + |
| + rect.set_y(rect.y() + shift); |
| + bubble_widget_->GetNativeWindow()->SetBounds(rect); |
| +} |
| + |
| +bool MaximizeBubbleController::Bubble::HasHitTestMask() const { |
| + return bubble_border_ != NULL; |
| +} |
| + |
| +void MaximizeBubbleController::Bubble::GetHitTestMask(gfx::Path* mask) const { |
| + DCHECK(mask); |
| + DCHECK(bubble_border_); |
| + bubble_border_->GetMask(mask); |
| +} |
| + |
| void MaximizeBubbleController::Bubble::MouseMovedOutOfHost() { |
| if (!owner_ || shutting_down_) |
| return; |
| @@ -421,12 +472,18 @@ bool MaximizeBubbleController::Bubble::Contains( |
| views::MouseWatcherHost::MouseEventType type) { |
| if (!owner_ || shutting_down_) |
| return false; |
| + bool inside_button = |
| + owner_->frame_maximize_button()->GetBoundsInScreen().Contains( |
| + screen_point); |
| + if (!owner_->frame_maximize_button()->is_snap_enabled() && inside_button) { |
| + SetSnapType(controller()->is_maximized() ? SNAP_RESTORE : SNAP_MAXIMIZE); |
| + return true; |
| + } |
| // Check if either a gesture is taking place (=> bubble stays no matter what |
| // the mouse does) or the mouse is over the maximize button or the bubble |
| // content. |
| return (owner_->frame_maximize_button()->is_snap_enabled() || |
| - owner_->frame_maximize_button()->GetBoundsInScreen().Contains( |
| - screen_point) || |
| + inside_button || |
| contents_view_->GetBoundsInScreen().Contains(screen_point)); |
| } |
| @@ -459,8 +516,9 @@ void MaximizeBubbleController::Bubble::ControllerRequestsCloseAndDelete() { |
| shutting_down_ = true; |
| owner_ = NULL; |
| - // Close the widget asynchronously. |
| - bubble_widget_->Close(); |
| + // Close the widget asynchronously after the hide animation is finished. |
| + initial_position_ = bubble_widget_->GetNativeWindow()->bounds(); |
| + StartFade(false); |
| } |
| void MaximizeBubbleController::Bubble::SetSnapType(SnapType snap_type) { |
| @@ -545,6 +603,8 @@ BubbleContentsView::BubbleContentsView( |
| label_view_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); |
| label_view_->SetBackgroundColor(kBubbleBackgroundColor); |
| label_view_->SetEnabledColor(kBubbleTextColor); |
| + label_view_->set_border(views::Border::CreateEmptyBorder( |
| + kLabelSpacing, 0, kLabelSpacing, 0)); |
| AddChildView(label_view_); |
| } |