Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/wm/maximize_bubble_controller.h" | 5 #include "ash/wm/maximize_bubble_controller.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
| 9 #include "ash/wm/window_animations.h" | 9 #include "ash/wm/window_animations.h" |
| 10 #include "ash/wm/workspace/frame_maximize_button.h" | 10 #include "ash/wm/workspace/frame_maximize_button.h" |
| 11 #include "base/timer.h" | 11 #include "base/timer.h" |
| 12 #include "grit/ash_strings.h" | 12 #include "grit/ash_strings.h" |
| 13 #include "grit/ui_resources.h" | 13 #include "grit/ui_resources.h" |
| 14 #include "third_party/skia/include/core/SkPath.h" | |
| 14 #include "ui/aura/event.h" | 15 #include "ui/aura/event.h" |
| 15 #include "ui/aura/focus_manager.h" | 16 #include "ui/aura/focus_manager.h" |
| 16 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
| 18 #include "ui/base/animation/animation.h" | |
| 17 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
| 18 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
| 19 #include "ui/gfx/canvas.h" | 21 #include "ui/gfx/canvas.h" |
| 22 #include "ui/gfx/path.h" | |
| 20 #include "ui/gfx/screen.h" | 23 #include "ui/gfx/screen.h" |
| 21 #include "ui/views/bubble/bubble_delegate.h" | 24 #include "ui/views/bubble/bubble_delegate.h" |
| 22 #include "ui/views/bubble/bubble_frame_view.h" | 25 #include "ui/views/bubble/bubble_frame_view.h" |
| 23 #include "ui/views/controls/button/button.h" | 26 #include "ui/views/controls/button/button.h" |
| 24 #include "ui/views/controls/button/image_button.h" | 27 #include "ui/views/controls/button/image_button.h" |
| 25 #include "ui/views/controls/label.h" | 28 #include "ui/views/controls/label.h" |
| 26 #include "ui/views/events/event.h" | 29 #include "ui/views/events/event.h" |
| 27 #include "ui/views/layout/box_layout.h" | 30 #include "ui/views/layout/box_layout.h" |
| 28 #include "ui/views/mouse_watcher.h" | 31 #include "ui/views/mouse_watcher.h" |
| 29 #include "ui/views/widget/widget.h" | 32 #include "ui/views/widget/widget.h" |
| 30 | 33 |
| 31 namespace { | 34 namespace { |
| 32 | 35 |
| 33 // The spacing between two buttons. | 36 // The spacing between two buttons. |
| 34 const int kLayoutSpacing = -1; | 37 const int kLayoutSpacing = -1; |
| 35 | 38 |
| 36 // The background color. | 39 // The background color. |
| 37 const SkColor kBubbleBackgroundColor = 0xc8141414; | 40 const SkColor kBubbleBackgroundColor = 0xc8141414; |
| 38 | 41 |
| 39 // The text color within the bubble. | 42 // The text color within the bubble. |
| 40 const SkColor kBubbleTextColor = SK_ColorWHITE; | 43 const SkColor kBubbleTextColor = SK_ColorWHITE; |
| 41 | 44 |
| 42 // The line width of the bubble. | 45 // The line width of the bubble. |
| 43 const int kLineWidth = 1; | 46 const int kLineWidth = 1; |
| 44 | 47 |
| 48 // The spacing for the top and bottom of the info label. | |
| 49 const int kLabelSpacing = 4; | |
| 50 | |
| 45 // The pixel dimensions of the arrow. | 51 // The pixel dimensions of the arrow. |
| 46 const int kArrowHeight = 10; | 52 const int kArrowHeight = 10; |
| 47 const int kArrowWidth = 20; | 53 const int kArrowWidth = 20; |
| 48 | 54 |
| 49 // The delay of the bubble appearance. | 55 // The delay of the bubble appearance. |
| 50 const int kBubbleAppearanceDelayMS = 200; | 56 const int kBubbleAppearanceDelayMS = 200; |
| 51 const int kAnimationDurationForPopupMS = 200; | 57 |
| 58 // The animation offset in y for the bubble when appearing. | |
| 59 const int kBubbleAnimationOffsetY = 5; | |
| 52 | 60 |
| 53 class MaximizeBubbleBorder : public views::BubbleBorder { | 61 class MaximizeBubbleBorder : public views::BubbleBorder { |
| 54 public: | 62 public: |
| 55 MaximizeBubbleBorder(views::View* content_view, views::View* anchor); | 63 MaximizeBubbleBorder(views::View* content_view, views::View* anchor); |
| 56 | 64 |
| 57 virtual ~MaximizeBubbleBorder() {} | 65 virtual ~MaximizeBubbleBorder() {} |
| 58 | 66 |
| 59 // Overridden from views::BubbleBorder to match the design specs. | 67 // Overridden from views::BubbleBorder to match the design specs. |
| 60 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, | 68 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, |
| 61 const gfx::Size& contents_size) const OVERRIDE; | 69 const gfx::Size& contents_size) const OVERRIDE; |
| 62 | 70 |
| 63 // Overridden from views::Border. | 71 // Overridden from views::Border. |
| 64 virtual void Paint(const views::View& view, | 72 virtual void Paint(const views::View& view, |
| 65 gfx::Canvas* canvas) const OVERRIDE; | 73 gfx::Canvas* canvas) const OVERRIDE; |
| 74 | |
| 75 // 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.
| |
| 76 void GetMask(gfx::Path* mask); | |
| 77 | |
| 66 private: | 78 private: |
| 67 views::View* anchor_; | 79 views::View* anchor_; |
| 68 views::View* content_view_; | 80 views::View* content_view_; |
| 69 | 81 |
| 70 DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleBorder); | 82 DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleBorder); |
| 71 }; | 83 }; |
| 72 | 84 |
| 73 MaximizeBubbleBorder::MaximizeBubbleBorder(views::View* content_view, | 85 MaximizeBubbleBorder::MaximizeBubbleBorder(views::View* content_view, |
| 74 views::View* anchor) | 86 views::View* anchor) |
| 75 : views::BubbleBorder(views::BubbleBorder::TOP_RIGHT, | 87 : views::BubbleBorder(views::BubbleBorder::TOP_RIGHT, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); | 154 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
| 143 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), | 155 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), |
| 144 SkIntToScalar(left_base_y)); | 156 SkIntToScalar(left_base_y)); |
| 145 | 157 |
| 146 SkPaint paint; | 158 SkPaint paint; |
| 147 paint.setStyle(SkPaint::kFill_Style); | 159 paint.setStyle(SkPaint::kFill_Style); |
| 148 paint.setColor(kBubbleBackgroundColor); | 160 paint.setColor(kBubbleBackgroundColor); |
| 149 canvas->DrawPath(path, paint); | 161 canvas->DrawPath(path, paint); |
| 150 } | 162 } |
| 151 | 163 |
| 164 void MaximizeBubbleBorder::GetMask(gfx::Path* mask) { | |
| 165 gfx::Insets inset; | |
| 166 GetInsets(&inset); | |
| 167 // Note: Even though the tip could be added as activatable, it is left out | |
| 168 // since it would not change the action behavior in any way plus it makes | |
| 169 // more sense to keep the focus on the underlying button for clicks. | |
| 170 int left = inset.left() - kLineWidth; | |
| 171 int right = inset.left() + content_view_->width() + kLineWidth; | |
| 172 int top = inset.top() - kLineWidth; | |
| 173 int bottom = inset.top() + content_view_->height() + kLineWidth; | |
| 174 mask->moveTo(left, top); | |
| 175 mask->lineTo(right, top); | |
| 176 mask->lineTo(right, bottom); | |
| 177 mask->lineTo(left, bottom); | |
| 178 mask->lineTo(left, top); | |
| 179 mask->close(); | |
| 180 } | |
| 181 | |
| 152 } // namespace | 182 } // namespace |
| 153 | 183 |
| 154 namespace ash { | 184 namespace ash { |
| 155 | 185 |
| 156 class BubbleContentsButtonRow; | 186 class BubbleContentsButtonRow; |
| 157 class BubbleContentsView; | 187 class BubbleContentsView; |
| 158 class BubbleDialogButton; | 188 class BubbleDialogButton; |
| 159 | 189 |
| 160 // The mouse watcher host which makes sure that the bubble does not get closed | 190 // The mouse watcher host which makes sure that the bubble does not get closed |
| 161 // while the mouse cursor is over the maximize button or the balloon content. | 191 // while the mouse cursor is over the maximize button or the balloon content. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 184 public views::MouseWatcherListener { | 214 public views::MouseWatcherListener { |
| 185 public: | 215 public: |
| 186 explicit Bubble(MaximizeBubbleController* owner); | 216 explicit Bubble(MaximizeBubbleController* owner); |
| 187 virtual ~Bubble() {} | 217 virtual ~Bubble() {} |
| 188 | 218 |
| 189 // The window of the menu under which the SnapSizer will get created. | 219 // The window of the menu under which the SnapSizer will get created. |
| 190 aura::Window* GetBubbleWindow(); | 220 aura::Window* GetBubbleWindow(); |
| 191 | 221 |
| 192 // Overridden from views::BubbleDelegateView. | 222 // Overridden from views::BubbleDelegateView. |
| 193 virtual gfx::Rect GetAnchorRect() OVERRIDE; | 223 virtual gfx::Rect GetAnchorRect() OVERRIDE; |
| 224 // 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.
| |
| 225 // function will add this behavior to the animation. | |
| 226 virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; | |
| 227 | |
| 228 // Overridden from views::WidgetDelegateView. | |
| 229 virtual bool HasHitTestMask() const OVERRIDE; | |
| 230 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE; | |
| 194 | 231 |
| 195 // Implementation of MouseWatcherListener. | 232 // Implementation of MouseWatcherListener. |
| 196 virtual void MouseMovedOutOfHost(); | 233 virtual void MouseMovedOutOfHost(); |
| 197 | 234 |
| 198 // Implementation of MouseWatcherHost. | 235 // Implementation of MouseWatcherHost. |
| 199 virtual bool Contains(const gfx::Point& screen_point, | 236 virtual bool Contains(const gfx::Point& screen_point, |
| 200 views::MouseWatcherHost::MouseEventType type); | 237 views::MouseWatcherHost::MouseEventType type); |
| 201 | 238 |
| 202 // Overridden from views::View. | 239 // Overridden from views::View. |
| 203 virtual gfx::Size GetPreferredSize() OVERRIDE; | 240 virtual gfx::Size GetPreferredSize() OVERRIDE; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 223 | 260 |
| 224 // Our owning class. | 261 // Our owning class. |
| 225 MaximizeBubbleController* owner_; | 262 MaximizeBubbleController* owner_; |
| 226 | 263 |
| 227 // The widget which contains our menu and the bubble border. | 264 // The widget which contains our menu and the bubble border. |
| 228 views::Widget* bubble_widget_; | 265 views::Widget* bubble_widget_; |
| 229 | 266 |
| 230 // The content accessor of the menu. | 267 // The content accessor of the menu. |
| 231 BubbleContentsView* contents_view_; | 268 BubbleContentsView* contents_view_; |
| 232 | 269 |
| 270 // The bubble border. | |
| 271 MaximizeBubbleBorder* bubble_border_; | |
| 272 | |
| 273 // The rectangle before the animation starts. | |
| 274 gfx::Rect initial_position_; | |
| 275 | |
| 233 // The mouse watcher which takes care of out of window hover events. | 276 // The mouse watcher which takes care of out of window hover events. |
| 234 scoped_ptr<views::MouseWatcher> mouse_watcher_; | 277 scoped_ptr<views::MouseWatcher> mouse_watcher_; |
| 235 | 278 |
| 236 DISALLOW_COPY_AND_ASSIGN(Bubble); | 279 DISALLOW_COPY_AND_ASSIGN(Bubble); |
| 237 }; | 280 }; |
| 238 | 281 |
| 239 // A class that creates all buttons and put them into a view. | 282 // A class that creates all buttons and put them into a view. |
| 240 class BubbleContentsButtonRow : public views::View, | 283 class BubbleContentsButtonRow : public views::View, |
| 241 public views::ButtonListener { | 284 public views::ButtonListener { |
| 242 public: | 285 public: |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 | 352 |
| 310 DISALLOW_COPY_AND_ASSIGN(BubbleDialogButton); | 353 DISALLOW_COPY_AND_ASSIGN(BubbleDialogButton); |
| 311 }; | 354 }; |
| 312 | 355 |
| 313 MaximizeBubbleController::Bubble::Bubble(MaximizeBubbleController* owner) | 356 MaximizeBubbleController::Bubble::Bubble(MaximizeBubbleController* owner) |
| 314 : views::BubbleDelegateView(owner->frame_maximize_button(), | 357 : views::BubbleDelegateView(owner->frame_maximize_button(), |
| 315 views::BubbleBorder::TOP_RIGHT), | 358 views::BubbleBorder::TOP_RIGHT), |
| 316 shutting_down_(false), | 359 shutting_down_(false), |
| 317 owner_(owner), | 360 owner_(owner), |
| 318 bubble_widget_(NULL), | 361 bubble_widget_(NULL), |
| 319 contents_view_(NULL) { | 362 contents_view_(NULL), |
| 363 bubble_border_(NULL) { | |
| 320 set_margins(gfx::Insets()); | 364 set_margins(gfx::Insets()); |
| 321 | 365 |
| 322 // The window needs to be owned by the root so that the SnapSizer does not | 366 // The window needs to be owned by the root so that the SnapSizer does not |
| 323 // cover it upon animation. | 367 // cover it upon animation. |
| 324 aura::Window* parent = Shell::GetContainer( | 368 aura::Window* parent = Shell::GetContainer( |
| 325 Shell::GetActiveRootWindow(), | 369 Shell::GetActiveRootWindow(), |
| 326 internal::kShellWindowId_LauncherContainer); | 370 internal::kShellWindowId_LauncherContainer); |
| 327 set_parent_window(parent); | 371 set_parent_window(parent); |
| 328 | 372 |
| 329 set_notify_enter_exit_on_child(true); | 373 set_notify_enter_exit_on_child(true); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 341 contents_view_ = new BubbleContentsView(this); | 385 contents_view_ = new BubbleContentsView(this); |
| 342 AddChildView(contents_view_); | 386 AddChildView(contents_view_); |
| 343 | 387 |
| 344 // Note that the returned widget has an observer which points to our | 388 // Note that the returned widget has an observer which points to our |
| 345 // functions. | 389 // functions. |
| 346 bubble_widget_ = views::BubbleDelegateView::CreateBubble(this); | 390 bubble_widget_ = views::BubbleDelegateView::CreateBubble(this); |
| 347 | 391 |
| 348 SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | 392 SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
| 349 bubble_widget_->non_client_view()->frame_view()->set_background(NULL); | 393 bubble_widget_->non_client_view()->frame_view()->set_background(NULL); |
| 350 | 394 |
| 351 MaximizeBubbleBorder* bubble_border = new MaximizeBubbleBorder( | 395 bubble_border_ = new MaximizeBubbleBorder(this, anchor_view()); |
| 352 this, | 396 GetBubbleFrameView()->SetBubbleBorder(bubble_border_); |
| 353 anchor_view()); | |
| 354 GetBubbleFrameView()->SetBubbleBorder(bubble_border); | |
| 355 GetBubbleFrameView()->set_background(NULL); | 397 GetBubbleFrameView()->set_background(NULL); |
| 356 | 398 |
| 357 // Recalculate size with new border. | 399 // Recalculate size with new border. |
| 358 SizeToContents(); | 400 SizeToContents(); |
| 359 | 401 |
| 360 // Setup animation. | 402 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.
| |
| 361 ash::SetWindowVisibilityAnimationType( | 403 StartFade(true); |
| 362 bubble_widget_->GetNativeWindow(), | |
| 363 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | |
| 364 ash::SetWindowVisibilityAnimationTransition( | |
| 365 bubble_widget_->GetNativeWindow(), | |
| 366 ash::ANIMATE_BOTH); | |
| 367 ash::SetWindowVisibilityAnimationDuration( | |
| 368 bubble_widget_->GetNativeWindow(), | |
| 369 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS)); | |
| 370 | 404 |
| 371 Show(); | |
| 372 // We don't want to lose the focus on our parent window because the button | |
| 373 // would otherwise lose the highlight when the "helper bubble" is shown. | |
| 374 views::Widget* widget = | |
| 375 owner_->frame_maximize_button()->parent()->GetWidget(); | |
| 376 if (widget) { | |
| 377 aura::Window* parent_window = widget->GetNativeWindow(); | |
| 378 parent_window->GetFocusManager()->SetFocusedWindow(parent_window, NULL); | |
| 379 } | |
| 380 mouse_watcher_.reset(new views::MouseWatcher( | 405 mouse_watcher_.reset(new views::MouseWatcher( |
| 381 new BubbleMouseWatcherHost(this), | 406 new BubbleMouseWatcherHost(this), |
| 382 this)); | 407 this)); |
| 383 mouse_watcher_->Start(); | 408 mouse_watcher_->Start(); |
| 384 } | 409 } |
| 385 | 410 |
| 386 bool BubbleMouseWatcherHost::Contains( | 411 bool BubbleMouseWatcherHost::Contains( |
| 387 const gfx::Point& screen_point, | 412 const gfx::Point& screen_point, |
| 388 views::MouseWatcherHost::MouseEventType type) { | 413 views::MouseWatcherHost::MouseEventType type) { |
| 389 return bubble_->Contains(screen_point, type); | 414 return bubble_->Contains(screen_point, type); |
| 390 } | 415 } |
| 391 | 416 |
| 392 aura::Window* MaximizeBubbleController::Bubble::GetBubbleWindow() { | 417 aura::Window* MaximizeBubbleController::Bubble::GetBubbleWindow() { |
| 393 return bubble_widget_ ? bubble_widget_->GetNativeWindow() : NULL; | 418 return bubble_widget_ ? bubble_widget_->GetNativeWindow() : NULL; |
| 394 } | 419 } |
| 395 | 420 |
| 396 gfx::Rect MaximizeBubbleController::Bubble::GetAnchorRect() { | 421 gfx::Rect MaximizeBubbleController::Bubble::GetAnchorRect() { |
| 397 if (!owner_) | 422 if (!owner_) |
| 398 return gfx::Rect(); | 423 return gfx::Rect(); |
| 399 | 424 |
| 400 gfx::Rect anchor_rect = | 425 gfx::Rect anchor_rect = |
| 401 owner_->frame_maximize_button()->GetBoundsInScreen(); | 426 owner_->frame_maximize_button()->GetBoundsInScreen(); |
| 402 return anchor_rect; | 427 return anchor_rect; |
| 403 } | 428 } |
| 404 | 429 |
| 430 void MaximizeBubbleController::Bubble::AnimationProgressed( | |
| 431 const ui::Animation* animation) OVERRIDE { | |
| 432 // First do everything needed for the fade by calling the base function. | |
| 433 BubbleDelegateView::AnimationProgressed(animation); | |
| 434 // When fading in we are done. | |
| 435 if (!shutting_down_) | |
| 436 return; | |
| 437 // Upon fade out an additional shift is required. | |
| 438 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.
| |
| 439 kBubbleAnimationOffsetY); | |
| 440 gfx::Rect rect = initial_position_; | |
| 441 | |
| 442 rect.set_y(rect.y() + shift); | |
| 443 bubble_widget_->GetNativeWindow()->SetBounds(rect); | |
| 444 } | |
| 445 | |
| 446 bool MaximizeBubbleController::Bubble::HasHitTestMask() const { | |
| 447 return bubble_border_ != NULL; | |
| 448 } | |
| 449 | |
| 450 void MaximizeBubbleController::Bubble::GetHitTestMask(gfx::Path* mask) const { | |
| 451 DCHECK(mask); | |
| 452 DCHECK(bubble_border_); | |
| 453 bubble_border_->GetMask(mask); | |
| 454 } | |
| 455 | |
| 405 void MaximizeBubbleController::Bubble::MouseMovedOutOfHost() { | 456 void MaximizeBubbleController::Bubble::MouseMovedOutOfHost() { |
| 406 if (!owner_ || shutting_down_) | 457 if (!owner_ || shutting_down_) |
| 407 return; | 458 return; |
| 408 // When we leave the bubble, we might be still be in gesture mode or over | 459 // When we leave the bubble, we might be still be in gesture mode or over |
| 409 // the maximize button. So only close if none of the other cases apply. | 460 // the maximize button. So only close if none of the other cases apply. |
| 410 if (!owner_->frame_maximize_button()->is_snap_enabled()) { | 461 if (!owner_->frame_maximize_button()->is_snap_enabled()) { |
| 411 gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint(); | 462 gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint(); |
| 412 if (!owner_->frame_maximize_button()->GetBoundsInScreen().Contains( | 463 if (!owner_->frame_maximize_button()->GetBoundsInScreen().Contains( |
| 413 screen_location)) { | 464 screen_location)) { |
| 414 owner_->RequestDestructionThroughOwner(); | 465 owner_->RequestDestructionThroughOwner(); |
| 415 } | 466 } |
| 416 } | 467 } |
| 417 } | 468 } |
| 418 | 469 |
| 419 bool MaximizeBubbleController::Bubble::Contains( | 470 bool MaximizeBubbleController::Bubble::Contains( |
| 420 const gfx::Point& screen_point, | 471 const gfx::Point& screen_point, |
| 421 views::MouseWatcherHost::MouseEventType type) { | 472 views::MouseWatcherHost::MouseEventType type) { |
| 422 if (!owner_ || shutting_down_) | 473 if (!owner_ || shutting_down_) |
| 423 return false; | 474 return false; |
| 475 bool inside_button = | |
| 476 owner_->frame_maximize_button()->GetBoundsInScreen().Contains( | |
| 477 screen_point); | |
| 478 if (!owner_->frame_maximize_button()->is_snap_enabled() && inside_button) { | |
| 479 SetSnapType(controller()->is_maximized() ? SNAP_RESTORE : SNAP_MAXIMIZE); | |
| 480 return true; | |
| 481 } | |
| 424 // Check if either a gesture is taking place (=> bubble stays no matter what | 482 // Check if either a gesture is taking place (=> bubble stays no matter what |
| 425 // the mouse does) or the mouse is over the maximize button or the bubble | 483 // the mouse does) or the mouse is over the maximize button or the bubble |
| 426 // content. | 484 // content. |
| 427 return (owner_->frame_maximize_button()->is_snap_enabled() || | 485 return (owner_->frame_maximize_button()->is_snap_enabled() || |
| 428 owner_->frame_maximize_button()->GetBoundsInScreen().Contains( | 486 inside_button || |
| 429 screen_point) || | |
| 430 contents_view_->GetBoundsInScreen().Contains(screen_point)); | 487 contents_view_->GetBoundsInScreen().Contains(screen_point)); |
| 431 } | 488 } |
| 432 | 489 |
| 433 gfx::Size MaximizeBubbleController::Bubble::GetPreferredSize() { | 490 gfx::Size MaximizeBubbleController::Bubble::GetPreferredSize() { |
| 434 return contents_view_->GetPreferredSize(); | 491 return contents_view_->GetPreferredSize(); |
| 435 } | 492 } |
| 436 | 493 |
| 437 void MaximizeBubbleController::Bubble::OnWidgetClosing(views::Widget* widget) { | 494 void MaximizeBubbleController::Bubble::OnWidgetClosing(views::Widget* widget) { |
| 438 if (bubble_widget_ != widget) | 495 if (bubble_widget_ != widget) |
| 439 return; | 496 return; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 452 anchor_widget()->RemoveObserver(this); | 509 anchor_widget()->RemoveObserver(this); |
| 453 } | 510 } |
| 454 | 511 |
| 455 void MaximizeBubbleController::Bubble::ControllerRequestsCloseAndDelete() { | 512 void MaximizeBubbleController::Bubble::ControllerRequestsCloseAndDelete() { |
| 456 // This only gets called from the owning base class once it is deleted. | 513 // This only gets called from the owning base class once it is deleted. |
| 457 if (shutting_down_) | 514 if (shutting_down_) |
| 458 return; | 515 return; |
| 459 shutting_down_ = true; | 516 shutting_down_ = true; |
| 460 owner_ = NULL; | 517 owner_ = NULL; |
| 461 | 518 |
| 462 // Close the widget asynchronously. | 519 // Close the widget asynchronously after the hide animation is finished. |
| 463 bubble_widget_->Close(); | 520 initial_position_ = bubble_widget_->GetNativeWindow()->bounds(); |
| 521 StartFade(false); | |
| 464 } | 522 } |
| 465 | 523 |
| 466 void MaximizeBubbleController::Bubble::SetSnapType(SnapType snap_type) { | 524 void MaximizeBubbleController::Bubble::SetSnapType(SnapType snap_type) { |
| 467 if (contents_view_) | 525 if (contents_view_) |
| 468 contents_view_->SetSnapType(snap_type); | 526 contents_view_->SetSnapType(snap_type); |
| 469 } | 527 } |
| 470 | 528 |
| 471 BubbleContentsButtonRow::BubbleContentsButtonRow( | 529 BubbleContentsButtonRow::BubbleContentsButtonRow( |
| 472 MaximizeBubbleController::Bubble* bubble) | 530 MaximizeBubbleController::Bubble* bubble) |
| 473 : bubble_(bubble), | 531 : bubble_(bubble), |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 views::Background::CreateSolidBackground(kBubbleBackgroundColor)); | 596 views::Background::CreateSolidBackground(kBubbleBackgroundColor)); |
| 539 | 597 |
| 540 buttons_view_ = new BubbleContentsButtonRow(bubble); | 598 buttons_view_ = new BubbleContentsButtonRow(bubble); |
| 541 AddChildView(buttons_view_); | 599 AddChildView(buttons_view_); |
| 542 | 600 |
| 543 label_view_ = new views::Label(); | 601 label_view_ = new views::Label(); |
| 544 SetSnapType(SNAP_NONE); | 602 SetSnapType(SNAP_NONE); |
| 545 label_view_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); | 603 label_view_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); |
| 546 label_view_->SetBackgroundColor(kBubbleBackgroundColor); | 604 label_view_->SetBackgroundColor(kBubbleBackgroundColor); |
| 547 label_view_->SetEnabledColor(kBubbleTextColor); | 605 label_view_->SetEnabledColor(kBubbleTextColor); |
| 606 label_view_->set_border(views::Border::CreateEmptyBorder( | |
| 607 kLabelSpacing, 0, kLabelSpacing, 0)); | |
| 548 AddChildView(label_view_); | 608 AddChildView(label_view_); |
| 549 } | 609 } |
| 550 | 610 |
| 551 // Set the label content to reflect the currently selected |snap_type|. | 611 // Set the label content to reflect the currently selected |snap_type|. |
| 552 // This function can be executed through the frame maximize button as well as | 612 // This function can be executed through the frame maximize button as well as |
| 553 // through hover operations. | 613 // through hover operations. |
| 554 void BubbleContentsView::SetSnapType(SnapType snap_type) { | 614 void BubbleContentsView::SetSnapType(SnapType snap_type) { |
| 555 if (!bubble_->controller()) | 615 if (!bubble_->controller()) |
| 556 return; | 616 return; |
| 557 | 617 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 button_row_->ButtonHovered(this); | 733 button_row_->ButtonHovered(this); |
| 674 views::ImageButton::OnMouseEntered(event); | 734 views::ImageButton::OnMouseEntered(event); |
| 675 } | 735 } |
| 676 | 736 |
| 677 void BubbleDialogButton::OnMouseExited(const views::MouseEvent& event) { | 737 void BubbleDialogButton::OnMouseExited(const views::MouseEvent& event) { |
| 678 button_row_->ButtonHovered(NULL); | 738 button_row_->ButtonHovered(NULL); |
| 679 views::ImageButton::OnMouseExited(event); | 739 views::ImageButton::OnMouseExited(event); |
| 680 } | 740 } |
| 681 | 741 |
| 682 } // namespace ash | 742 } // namespace ash |
| OLD | NEW |