| 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 28 matching lines...) Expand all Loading... |
| 199 maximizer_.reset(new MaximizeBubbleController( | 203 maximizer_.reset(new MaximizeBubbleController( |
| 200 this, | 204 this, |
| 201 frame_->GetWidget()->IsMaximized())); | 205 frame_->GetWidget()->IsMaximized())); |
| 202 } | 206 } |
| 203 } | 207 } |
| 204 | 208 |
| 205 void FrameMaximizeButton::OnMouseExited(const views::MouseEvent& event) { | 209 void FrameMaximizeButton::OnMouseExited(const views::MouseEvent& event) { |
| 206 ImageButton::OnMouseExited(event); | 210 ImageButton::OnMouseExited(event); |
| 207 // Remove the bubble menu when the button is not pressed and the mouse is not | 211 // Remove the bubble menu when the button is not pressed and the mouse is not |
| 208 // within the bubble. | 212 // within the bubble. |
| 209 if (!is_snap_enabled_ && maximizer_.get() && maximizer_->GetBubbleWindow()) { | 213 if (!is_snap_enabled_ && maximizer_.get()) { |
| 210 gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint(); | 214 if (maximizer_->GetBubbleWindow()) { |
| 211 if (!maximizer_->GetBubbleWindow()->GetBoundsInScreen().Contains( | 215 gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint(); |
| 212 screen_location)) { | 216 if (!maximizer_->GetBubbleWindow()->GetBoundsInScreen().Contains( |
| 217 screen_location)) { |
| 218 maximizer_.reset(); |
| 219 // Make sure that all remaining snap hover states get removed. |
| 220 SnapButtonHovered(SNAP_NONE); |
| 221 } |
| 222 } else { |
| 223 // The maximize dialog does not show up immediately after creating the |
| 224 // |mazimizer_|. Destroy the dialog therefore before it shows up. |
| 213 maximizer_.reset(); | 225 maximizer_.reset(); |
| 214 // Make sure that all remaining snap hover states get removed. | |
| 215 SnapButtonHovered(SNAP_NONE); | |
| 216 } | 226 } |
| 217 } | 227 } |
| 218 } | 228 } |
| 219 | 229 |
| 220 bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) { | 230 bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) { |
| 221 if (is_snap_enabled_) | 231 if (is_snap_enabled_) |
| 222 ProcessUpdateEvent(event); | 232 ProcessUpdateEvent(event); |
| 223 return ImageButton::OnMouseDragged(event); | 233 return ImageButton::OnMouseDragged(event); |
| 224 } | 234 } |
| 225 | 235 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 maximizer_.reset(); | 324 maximizer_.reset(); |
| 315 | 325 |
| 316 if (!should_snap || snap_type_ == SNAP_NONE) | 326 if (!should_snap || snap_type_ == SNAP_NONE) |
| 317 return false; | 327 return false; |
| 318 | 328 |
| 319 SetState(BS_NORMAL); | 329 SetState(BS_NORMAL); |
| 320 // SetState will not call SchedulePaint() if state was already set to | 330 // SetState will not call SchedulePaint() if state was already set to |
| 321 // BS_NORMAL during a drag. | 331 // BS_NORMAL during a drag. |
| 322 SchedulePaint(); | 332 SchedulePaint(); |
| 323 phantom_window_.reset(); | 333 phantom_window_.reset(); |
| 324 Snap(); | 334 // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, |
| 335 // The ownership of the snap_sizer is taken now. |
| 336 scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); |
| 337 Snap(*snap_sizer.get()); |
| 325 return true; | 338 return true; |
| 326 } | 339 } |
| 327 | 340 |
| 328 void FrameMaximizeButton::Cancel(bool keep_menu_open) { | 341 void FrameMaximizeButton::Cancel(bool keep_menu_open) { |
| 329 if (!keep_menu_open) { | 342 if (!keep_menu_open) { |
| 330 maximizer_.reset(); | 343 maximizer_.reset(); |
| 331 UninstallEventFilter(); | 344 UninstallEventFilter(); |
| 332 is_snap_enabled_ = false; | 345 is_snap_enabled_ = false; |
| 346 snap_sizer_.reset(); |
| 333 } | 347 } |
| 334 phantom_window_.reset(); | 348 phantom_window_.reset(); |
| 335 snap_sizer_.reset(); | |
| 336 snap_type_ = SNAP_NONE; | 349 snap_type_ = SNAP_NONE; |
| 337 update_timer_.Stop(); | 350 update_timer_.Stop(); |
| 338 SchedulePaint(); | 351 SchedulePaint(); |
| 339 } | 352 } |
| 340 | 353 |
| 341 void FrameMaximizeButton::InstallEventFilter() { | 354 void FrameMaximizeButton::InstallEventFilter() { |
| 342 if (escape_event_filter_.get()) | 355 if (escape_event_filter_.get()) |
| 343 return; | 356 return; |
| 344 | 357 |
| 345 escape_event_filter_.reset(new EscapeEventFilter(this)); | 358 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)); | 400 snap_edge, grid_size)); |
| 388 } | 401 } |
| 389 if (!phantom_window_.get()) { | 402 if (!phantom_window_.get()) { |
| 390 phantom_window_.reset(new internal::PhantomWindowController( | 403 phantom_window_.reset(new internal::PhantomWindowController( |
| 391 frame_->GetWidget()->GetNativeWindow())); | 404 frame_->GetWidget()->GetNativeWindow())); |
| 392 } | 405 } |
| 393 if (maximizer_.get()) { | 406 if (maximizer_.get()) { |
| 394 phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow()); | 407 phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow()); |
| 395 maximizer_->SetSnapType(snap_type_); | 408 maximizer_->SetSnapType(snap_type_); |
| 396 } | 409 } |
| 397 phantom_window_->Show(ScreenBoundsForType(snap_type_)); | 410 phantom_window_->Show(ScreenBoundsForType(snap_type_, *snap_sizer_.get())); |
| 398 } | 411 } |
| 399 | 412 |
| 400 SnapType FrameMaximizeButton::SnapTypeForLocation( | 413 SnapType FrameMaximizeButton::SnapTypeForLocation( |
| 401 const gfx::Point& location) const { | 414 const gfx::Point& location) const { |
| 402 int delta_x = location.x() - press_location_.x(); | 415 int delta_x = location.x() - press_location_.x(); |
| 403 int delta_y = location.y() - press_location_.y(); | 416 int delta_y = location.y() - press_location_.y(); |
| 404 if (!views::View::ExceededDragThreshold(delta_x, delta_y)) | 417 if (!views::View::ExceededDragThreshold(delta_x, delta_y)) |
| 405 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; | 418 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; |
| 406 else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x) | 419 else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x) |
| 407 return SNAP_LEFT; | 420 return SNAP_LEFT; |
| 408 else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x) | 421 else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x) |
| 409 return SNAP_RIGHT; | 422 return SNAP_RIGHT; |
| 410 else if (delta_y > 0) | 423 else if (delta_y > 0) |
| 411 return SNAP_MINIMIZE; | 424 return SNAP_MINIMIZE; |
| 412 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; | 425 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; |
| 413 } | 426 } |
| 414 | 427 |
| 415 gfx::Rect FrameMaximizeButton::ScreenBoundsForType(SnapType type) const { | 428 gfx::Rect FrameMaximizeButton::ScreenBoundsForType( |
| 429 SnapType type, |
| 430 const SnapSizer& snap_sizer) const { |
| 416 aura::Window* window = frame_->GetWidget()->GetNativeWindow(); | 431 aura::Window* window = frame_->GetWidget()->GetNativeWindow(); |
| 417 switch (type) { | 432 switch (type) { |
| 418 case SNAP_LEFT: | 433 case SNAP_LEFT: |
| 419 case SNAP_RIGHT: | 434 case SNAP_RIGHT: |
| 420 return ScreenAsh::ConvertRectToScreen( | 435 return ScreenAsh::ConvertRectToScreen( |
| 421 frame_->GetWidget()->GetNativeView()->parent(), | 436 frame_->GetWidget()->GetNativeView()->parent(), |
| 422 snap_sizer_->target_bounds()); | 437 snap_sizer.target_bounds()); |
| 423 case SNAP_MAXIMIZE: | 438 case SNAP_MAXIMIZE: |
| 424 return ScreenAsh::ConvertRectToScreen( | 439 return ScreenAsh::ConvertRectToScreen( |
| 425 window->parent(), | 440 window->parent(), |
| 426 ScreenAsh::GetMaximizedWindowBoundsInParent(window)); | 441 ScreenAsh::GetMaximizedWindowBoundsInParent(window)); |
| 427 case SNAP_MINIMIZE: { | 442 case SNAP_MINIMIZE: { |
| 428 Launcher* launcher = Shell::GetInstance()->launcher(); | 443 Launcher* launcher = Shell::GetInstance()->launcher(); |
| 429 gfx::Rect item_rect(launcher->GetScreenBoundsOfItemIconForWindow(window)); | 444 gfx::Rect item_rect(launcher->GetScreenBoundsOfItemIconForWindow(window)); |
| 430 if (!item_rect.IsEmpty()) { | 445 if (!item_rect.IsEmpty()) { |
| 431 // PhantomWindowController insets slightly, outset it so the phantom | 446 // PhantomWindowController insets slightly, outset it so the phantom |
| 432 // doesn't appear inset. | 447 // doesn't appear inset. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 446 return gfx::Rect(); | 461 return gfx::Rect(); |
| 447 } | 462 } |
| 448 | 463 |
| 449 gfx::Point FrameMaximizeButton::LocationForSnapSizer( | 464 gfx::Point FrameMaximizeButton::LocationForSnapSizer( |
| 450 const gfx::Point& location) const { | 465 const gfx::Point& location) const { |
| 451 gfx::Point result(location); | 466 gfx::Point result(location); |
| 452 views::View::ConvertPointToScreen(this, &result); | 467 views::View::ConvertPointToScreen(this, &result); |
| 453 return result; | 468 return result; |
| 454 } | 469 } |
| 455 | 470 |
| 456 void FrameMaximizeButton::Snap() { | 471 void FrameMaximizeButton::Snap(const SnapSizer& snap_sizer) { |
| 457 switch (snap_type_) { | 472 switch (snap_type_) { |
| 458 case SNAP_LEFT: | 473 case SNAP_LEFT: |
| 459 case SNAP_RIGHT: | 474 case SNAP_RIGHT: |
| 460 if (frame_->GetWidget()->IsMaximized()) { | 475 if (frame_->GetWidget()->IsMaximized()) { |
| 461 ash::SetRestoreBoundsInScreen(frame_->GetWidget()->GetNativeWindow(), | 476 ash::SetRestoreBoundsInScreen(frame_->GetWidget()->GetNativeWindow(), |
| 462 ScreenBoundsForType(snap_type_)); | 477 ScreenBoundsForType(snap_type_, |
| 478 snap_sizer)); |
| 463 frame_->GetWidget()->Restore(); | 479 frame_->GetWidget()->Restore(); |
| 464 } else { | 480 } else { |
| 465 frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_)); | 481 frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_, |
| 482 snap_sizer)); |
| 466 } | 483 } |
| 467 break; | 484 break; |
| 468 case SNAP_MAXIMIZE: | 485 case SNAP_MAXIMIZE: |
| 469 frame_->GetWidget()->Maximize(); | 486 frame_->GetWidget()->Maximize(); |
| 470 break; | 487 break; |
| 471 case SNAP_MINIMIZE: | 488 case SNAP_MINIMIZE: |
| 472 frame_->GetWidget()->Minimize(); | 489 frame_->GetWidget()->Minimize(); |
| 473 break; | 490 break; |
| 474 case SNAP_RESTORE: | 491 case SNAP_RESTORE: |
| 475 frame_->GetWidget()->Restore(); | 492 frame_->GetWidget()->Restore(); |
| 476 break; | 493 break; |
| 477 case SNAP_NONE: | 494 case SNAP_NONE: |
| 478 NOTREACHED(); | 495 NOTREACHED(); |
| 479 } | 496 } |
| 480 } | 497 } |
| 481 | 498 |
| 482 } // namespace ash | 499 } // namespace ash |
| OLD | NEW |