| 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/workspace/frame_maximize_button.h" | 5 #include "ash/wm/workspace/frame_maximize_button.h" |
| 6 | 6 |
| 7 #include "ash/launcher/launcher.h" | 7 #include "ash/launcher/launcher.h" |
| 8 #include "ash/screen_ash.h" | 8 #include "ash/screen_ash.h" |
| 9 #include "ash/shell.h" | 9 #include "ash/shell.h" |
| 10 #include "ash/wm/property_util.h" | 10 #include "ash/wm/property_util.h" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 frame_(frame), | 106 frame_(frame), |
| 107 is_snap_enabled_(false), | 107 is_snap_enabled_(false), |
| 108 exceeded_drag_threshold_(false), | 108 exceeded_drag_threshold_(false), |
| 109 window_(NULL), | 109 window_(NULL), |
| 110 snap_type_(SNAP_NONE) { | 110 snap_type_(SNAP_NONE) { |
| 111 // TODO(sky): nuke this. It's temporary while we don't have good images. | 111 // TODO(sky): nuke this. It's temporary while we don't have good images. |
| 112 SetImageAlignment(ALIGN_LEFT, ALIGN_BOTTOM); | 112 SetImageAlignment(ALIGN_LEFT, ALIGN_BOTTOM); |
| 113 } | 113 } |
| 114 | 114 |
| 115 FrameMaximizeButton::~FrameMaximizeButton() { | 115 FrameMaximizeButton::~FrameMaximizeButton() { |
| 116 // Before the window gets destroyed, the maximizer dialog needs to be shut |
| 117 // down since it would otherwise call into a deleted object. |
| 118 maximizer_.reset(); |
| 116 if (window_) | 119 if (window_) |
| 117 OnWindowDestroying(window_); | 120 OnWindowDestroying(window_); |
| 118 } | 121 } |
| 119 | 122 |
| 120 void FrameMaximizeButton::SnapButtonHovered(SnapType type) { | 123 void FrameMaximizeButton::SnapButtonHovered(SnapType type) { |
| 121 // Make sure to only show hover operations when no button is pressed and | 124 // Make sure to only show hover operations when no button is pressed and |
| 122 // a similar snap operation in progress does not get re-applied. | 125 // a similar snap operation in progress does not get re-applied. |
| 123 if (is_snap_enabled_ || (type == snap_type_ && snap_sizer_.get())) | 126 if (is_snap_enabled_ || (type == snap_type_ && snap_sizer_.get())) |
| 124 return; | 127 return; |
| 125 // Prime the mouse location with the center of the (local) button. | 128 // Prime the mouse location with the center of the (local) button. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 144 return; | 147 return; |
| 145 default: | 148 default: |
| 146 // We should not come here. | 149 // We should not come here. |
| 147 NOTREACHED(); | 150 NOTREACHED(); |
| 148 } | 151 } |
| 149 UpdateSnap(location); | 152 UpdateSnap(location); |
| 150 } | 153 } |
| 151 | 154 |
| 152 void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { | 155 void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { |
| 153 DCHECK_NE(snap_type_, SNAP_NONE); | 156 DCHECK_NE(snap_type_, SNAP_NONE); |
| 157 Cancel(true); |
| 158 // Tell our menu to close. |
| 159 maximizer_.reset(); |
| 154 snap_type_ = snap_type; | 160 snap_type_ = snap_type; |
| 155 Snap(); | 161 // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, |
| 156 // Remove any pending snap previews. | 162 // The ownership of the snap_sizer is taken now. |
| 157 SnapButtonHovered(SNAP_NONE); | 163 scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); |
| 158 // At this point the operation has been performed and the menu should be | 164 Snap(snap_sizer.get()); |
| 159 // closed - if not, it'll get now closed. | |
| 160 maximizer_.reset(); | |
| 161 } | 165 } |
| 162 | 166 |
| 163 void FrameMaximizeButton::DestroyMaximizeMenu() { | 167 void FrameMaximizeButton::DestroyMaximizeMenu() { |
| 164 maximizer_.reset(); | 168 maximizer_.reset(); |
| 165 } | 169 } |
| 166 | 170 |
| 167 void FrameMaximizeButton::OnWindowBoundsChanged( | 171 void FrameMaximizeButton::OnWindowBoundsChanged( |
| 168 aura::Window* window, | 172 aura::Window* window, |
| 169 const gfx::Rect& old_bounds, | 173 const gfx::Rect& old_bounds, |
| 170 const gfx::Rect& new_bounds) { | 174 const gfx::Rect& new_bounds) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 maximizer_.reset(); | 318 maximizer_.reset(); |
| 315 | 319 |
| 316 if (!should_snap || snap_type_ == SNAP_NONE) | 320 if (!should_snap || snap_type_ == SNAP_NONE) |
| 317 return false; | 321 return false; |
| 318 | 322 |
| 319 SetState(BS_NORMAL); | 323 SetState(BS_NORMAL); |
| 320 // SetState will not call SchedulePaint() if state was already set to | 324 // SetState will not call SchedulePaint() if state was already set to |
| 321 // BS_NORMAL during a drag. | 325 // BS_NORMAL during a drag. |
| 322 SchedulePaint(); | 326 SchedulePaint(); |
| 323 phantom_window_.reset(); | 327 phantom_window_.reset(); |
| 324 Snap(); | 328 // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, |
| 329 // The ownership of the snap_sizer is taken now. |
| 330 scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); |
| 331 Snap(snap_sizer.get()); |
| 325 return true; | 332 return true; |
| 326 } | 333 } |
| 327 | 334 |
| 328 void FrameMaximizeButton::Cancel(bool keep_menu_open) { | 335 void FrameMaximizeButton::Cancel(bool keep_menu_open) { |
| 329 if (!keep_menu_open) { | 336 if (!keep_menu_open) { |
| 330 maximizer_.reset(); | 337 maximizer_.reset(); |
| 331 UninstallEventFilter(); | 338 UninstallEventFilter(); |
| 332 is_snap_enabled_ = false; | 339 is_snap_enabled_ = false; |
| 340 snap_sizer_.reset(); |
| 333 } | 341 } |
| 334 phantom_window_.reset(); | 342 phantom_window_.reset(); |
| 335 snap_sizer_.reset(); | |
| 336 snap_type_ = SNAP_NONE; | 343 snap_type_ = SNAP_NONE; |
| 337 update_timer_.Stop(); | 344 update_timer_.Stop(); |
| 338 SchedulePaint(); | 345 SchedulePaint(); |
| 339 } | 346 } |
| 340 | 347 |
| 341 void FrameMaximizeButton::InstallEventFilter() { | 348 void FrameMaximizeButton::InstallEventFilter() { |
| 342 if (escape_event_filter_.get()) | 349 if (escape_event_filter_.get()) |
| 343 return; | 350 return; |
| 344 | 351 |
| 345 escape_event_filter_.reset(new EscapeEventFilter(this)); | 352 escape_event_filter_.reset(new EscapeEventFilter(this)); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 snap_edge, grid_size)); | 394 snap_edge, grid_size)); |
| 388 } | 395 } |
| 389 if (!phantom_window_.get()) { | 396 if (!phantom_window_.get()) { |
| 390 phantom_window_.reset(new internal::PhantomWindowController( | 397 phantom_window_.reset(new internal::PhantomWindowController( |
| 391 frame_->GetWidget()->GetNativeWindow())); | 398 frame_->GetWidget()->GetNativeWindow())); |
| 392 } | 399 } |
| 393 if (maximizer_.get()) { | 400 if (maximizer_.get()) { |
| 394 phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow()); | 401 phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow()); |
| 395 maximizer_->SetSnapType(snap_type_); | 402 maximizer_->SetSnapType(snap_type_); |
| 396 } | 403 } |
| 397 phantom_window_->Show(ScreenBoundsForType(snap_type_)); | 404 phantom_window_->Show(ScreenBoundsForType(snap_type_, snap_sizer_.get())); |
| 398 } | 405 } |
| 399 | 406 |
| 400 SnapType FrameMaximizeButton::SnapTypeForLocation( | 407 SnapType FrameMaximizeButton::SnapTypeForLocation( |
| 401 const gfx::Point& location) const { | 408 const gfx::Point& location) const { |
| 402 int delta_x = location.x() - press_location_.x(); | 409 int delta_x = location.x() - press_location_.x(); |
| 403 int delta_y = location.y() - press_location_.y(); | 410 int delta_y = location.y() - press_location_.y(); |
| 404 if (!views::View::ExceededDragThreshold(delta_x, delta_y)) | 411 if (!views::View::ExceededDragThreshold(delta_x, delta_y)) |
| 405 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; | 412 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; |
| 406 else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x) | 413 else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x) |
| 407 return SNAP_LEFT; | 414 return SNAP_LEFT; |
| 408 else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x) | 415 else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x) |
| 409 return SNAP_RIGHT; | 416 return SNAP_RIGHT; |
| 410 else if (delta_y > 0) | 417 else if (delta_y > 0) |
| 411 return SNAP_MINIMIZE; | 418 return SNAP_MINIMIZE; |
| 412 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; | 419 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; |
| 413 } | 420 } |
| 414 | 421 |
| 415 gfx::Rect FrameMaximizeButton::ScreenBoundsForType(SnapType type) const { | 422 gfx::Rect FrameMaximizeButton::ScreenBoundsForType( |
| 423 SnapType type, |
| 424 SnapSizer* snap_sizer) const { |
| 416 aura::Window* window = frame_->GetWidget()->GetNativeWindow(); | 425 aura::Window* window = frame_->GetWidget()->GetNativeWindow(); |
| 417 switch (type) { | 426 switch (type) { |
| 418 case SNAP_LEFT: | 427 case SNAP_LEFT: |
| 419 case SNAP_RIGHT: | 428 case SNAP_RIGHT: |
| 429 DCHECK(snap_sizer); |
| 420 return ScreenAsh::ConvertRectToScreen( | 430 return ScreenAsh::ConvertRectToScreen( |
| 421 frame_->GetWidget()->GetNativeView()->parent(), | 431 frame_->GetWidget()->GetNativeView()->parent(), |
| 422 snap_sizer_->target_bounds()); | 432 snap_sizer->target_bounds()); |
| 423 case SNAP_MAXIMIZE: | 433 case SNAP_MAXIMIZE: |
| 424 return ScreenAsh::ConvertRectToScreen( | 434 return ScreenAsh::ConvertRectToScreen( |
| 425 window->parent(), | 435 window->parent(), |
| 426 ScreenAsh::GetMaximizedWindowBoundsInParent(window)); | 436 ScreenAsh::GetMaximizedWindowBoundsInParent(window)); |
| 427 case SNAP_MINIMIZE: { | 437 case SNAP_MINIMIZE: { |
| 428 Launcher* launcher = Shell::GetInstance()->launcher(); | 438 Launcher* launcher = Shell::GetInstance()->launcher(); |
| 429 gfx::Rect item_rect(launcher->GetScreenBoundsOfItemIconForWindow(window)); | 439 gfx::Rect item_rect(launcher->GetScreenBoundsOfItemIconForWindow(window)); |
| 430 if (!item_rect.IsEmpty()) { | 440 if (!item_rect.IsEmpty()) { |
| 431 // PhantomWindowController insets slightly, outset it so the phantom | 441 // PhantomWindowController insets slightly, outset it so the phantom |
| 432 // doesn't appear inset. | 442 // doesn't appear inset. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 446 return gfx::Rect(); | 456 return gfx::Rect(); |
| 447 } | 457 } |
| 448 | 458 |
| 449 gfx::Point FrameMaximizeButton::LocationForSnapSizer( | 459 gfx::Point FrameMaximizeButton::LocationForSnapSizer( |
| 450 const gfx::Point& location) const { | 460 const gfx::Point& location) const { |
| 451 gfx::Point result(location); | 461 gfx::Point result(location); |
| 452 views::View::ConvertPointToScreen(this, &result); | 462 views::View::ConvertPointToScreen(this, &result); |
| 453 return result; | 463 return result; |
| 454 } | 464 } |
| 455 | 465 |
| 456 void FrameMaximizeButton::Snap() { | 466 void FrameMaximizeButton::Snap(SnapSizer* snap_sizer) { |
| 457 switch (snap_type_) { | 467 switch (snap_type_) { |
| 458 case SNAP_LEFT: | 468 case SNAP_LEFT: |
| 459 case SNAP_RIGHT: | 469 case SNAP_RIGHT: |
| 470 DCHECK(snap_sizer); |
| 460 if (frame_->GetWidget()->IsMaximized()) { | 471 if (frame_->GetWidget()->IsMaximized()) { |
| 461 ash::SetRestoreBoundsInScreen(frame_->GetWidget()->GetNativeWindow(), | 472 ash::SetRestoreBoundsInScreen(frame_->GetWidget()->GetNativeWindow(), |
| 462 ScreenBoundsForType(snap_type_)); | 473 ScreenBoundsForType(snap_type_, |
| 474 snap_sizer)); |
| 463 frame_->GetWidget()->Restore(); | 475 frame_->GetWidget()->Restore(); |
| 464 } else { | 476 } else { |
| 465 frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_)); | 477 frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_, |
| 478 snap_sizer)); |
| 466 } | 479 } |
| 467 break; | 480 break; |
| 468 case SNAP_MAXIMIZE: | 481 case SNAP_MAXIMIZE: |
| 469 frame_->GetWidget()->Maximize(); | 482 frame_->GetWidget()->Maximize(); |
| 470 break; | 483 break; |
| 471 case SNAP_MINIMIZE: | 484 case SNAP_MINIMIZE: |
| 472 frame_->GetWidget()->Minimize(); | 485 frame_->GetWidget()->Minimize(); |
| 473 break; | 486 break; |
| 474 case SNAP_RESTORE: | 487 case SNAP_RESTORE: |
| 475 frame_->GetWidget()->Restore(); | 488 frame_->GetWidget()->Restore(); |
| 476 break; | 489 break; |
| 477 case SNAP_NONE: | 490 case SNAP_NONE: |
| 478 NOTREACHED(); | 491 NOTREACHED(); |
| 479 } | 492 } |
| 480 } | 493 } |
| 481 | 494 |
| 482 } // namespace ash | 495 } // namespace ash |
| OLD | NEW |