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/multi_window_resize_controller.h" | 5 #include "ash/wm/workspace/multi_window_resize_controller.h" |
6 | 6 |
| 7 #include "ash/screen_ash.h" |
7 #include "ash/shell.h" | 8 #include "ash/shell.h" |
8 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
9 #include "ash/wm/window_animations.h" | 10 #include "ash/wm/window_animations.h" |
10 #include "ash/wm/workspace/workspace_event_filter.h" | 11 #include "ash/wm/workspace/workspace_event_filter.h" |
11 #include "ash/wm/workspace/workspace_window_resizer.h" | 12 #include "ash/wm/workspace/workspace_window_resizer.h" |
12 #include "grit/ui_resources.h" | 13 #include "grit/ui_resources.h" |
| 14 #include "ui/aura/client/screen_position_client.h" |
13 #include "ui/aura/event_filter.h" | 15 #include "ui/aura/event_filter.h" |
14 #include "ui/aura/root_window.h" | 16 #include "ui/aura/root_window.h" |
15 #include "ui/aura/shared/compound_event_filter.h" | 17 #include "ui/aura/shared/compound_event_filter.h" |
16 #include "ui/aura/window.h" | 18 #include "ui/aura/window.h" |
17 #include "ui/aura/window_delegate.h" | 19 #include "ui/aura/window_delegate.h" |
18 #include "ui/base/hit_test.h" | 20 #include "ui/base/hit_test.h" |
19 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
20 #include "ui/gfx/canvas.h" | 22 #include "ui/gfx/canvas.h" |
21 #include "ui/gfx/image/image.h" | 23 #include "ui/gfx/image/image.h" |
22 #include "ui/gfx/screen.h" | 24 #include "ui/gfx/screen.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 }; | 113 }; |
112 | 114 |
113 // MouseWatcherHost implementation for MultiWindowResizeController. Forwards | 115 // MouseWatcherHost implementation for MultiWindowResizeController. Forwards |
114 // Contains() to MultiWindowResizeController. | 116 // Contains() to MultiWindowResizeController. |
115 class MultiWindowResizeController::ResizeMouseWatcherHost : | 117 class MultiWindowResizeController::ResizeMouseWatcherHost : |
116 public views::MouseWatcherHost { | 118 public views::MouseWatcherHost { |
117 public: | 119 public: |
118 ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {} | 120 ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {} |
119 | 121 |
120 // MouseWatcherHost overrides: | 122 // MouseWatcherHost overrides: |
121 virtual bool Contains(const gfx::Point& screen_point, | 123 virtual bool Contains(const gfx::Point& point_in_screen, |
122 MouseEventType type) OVERRIDE { | 124 MouseEventType type) OVERRIDE { |
123 return host_->IsOverWindows(screen_point); | 125 return host_->IsOverWindows(point_in_screen); |
124 } | 126 } |
125 | 127 |
126 private: | 128 private: |
127 MultiWindowResizeController* host_; | 129 MultiWindowResizeController* host_; |
128 | 130 |
129 DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost); | 131 DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost); |
130 }; | 132 }; |
131 | 133 |
132 MultiWindowResizeController::ResizeWindows::ResizeWindows() | 134 MultiWindowResizeController::ResizeWindows::ResizeWindows() |
133 : window1(NULL), | 135 : window1(NULL), |
(...skipping 15 matching lines...) Expand all Loading... |
149 : resize_widget_(NULL), | 151 : resize_widget_(NULL), |
150 grid_size_(0) { | 152 grid_size_(0) { |
151 } | 153 } |
152 | 154 |
153 MultiWindowResizeController::~MultiWindowResizeController() { | 155 MultiWindowResizeController::~MultiWindowResizeController() { |
154 Hide(); | 156 Hide(); |
155 } | 157 } |
156 | 158 |
157 void MultiWindowResizeController::Show(Window* window, | 159 void MultiWindowResizeController::Show(Window* window, |
158 int component, | 160 int component, |
159 const gfx::Point& point) { | 161 const gfx::Point& point_in_window) { |
160 // When the resize widget is showing we ignore Show() requests. Instead we | 162 // When the resize widget is showing we ignore Show() requests. Instead we |
161 // only care about mouse movements from MouseWatcher. This is necessary as | 163 // only care about mouse movements from MouseWatcher. This is necessary as |
162 // WorkspaceEventFilter only sees mouse movements over the windows, not all | 164 // WorkspaceEventFilter only sees mouse movements over the windows, not all |
163 // windows or over the desktop. | 165 // windows or over the desktop. |
164 if (resize_widget_) | 166 if (resize_widget_) |
165 return; | 167 return; |
166 | 168 |
167 ResizeWindows windows(DetermineWindows(window, component, point)); | 169 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); |
168 if (IsShowing()) { | 170 if (IsShowing()) { |
169 if (windows_.Equals(windows)) | 171 if (windows_.Equals(windows)) |
170 return; // Over the same windows. | 172 return; // Over the same windows. |
171 DelayedHide(); | 173 DelayedHide(); |
172 } | 174 } |
173 | 175 |
174 if (!windows.is_valid()) | 176 if (!windows.is_valid()) |
175 return; | 177 return; |
176 Hide(); | 178 Hide(); |
177 windows_ = windows; | 179 windows_ = windows; |
178 windows_.window1->AddObserver(this); | 180 windows_.window1->AddObserver(this); |
179 windows_.window2->AddObserver(this); | 181 windows_.window2->AddObserver(this); |
180 show_location_ = point; | 182 show_location_in_parent_ = point_in_window; |
181 Window::ConvertPointToWindow(window, window->parent(), &show_location_); | 183 Window::ConvertPointToWindow( |
| 184 window, window->parent(), &show_location_in_parent_); |
182 if (show_timer_.IsRunning()) | 185 if (show_timer_.IsRunning()) |
183 return; | 186 return; |
184 show_timer_.Start(FROM_HERE, | 187 show_timer_.Start(FROM_HERE, |
185 base::TimeDelta::FromMilliseconds(kShowDelayMS), | 188 base::TimeDelta::FromMilliseconds(kShowDelayMS), |
186 this, &MultiWindowResizeController::ShowNow); | 189 this, &MultiWindowResizeController::ShowNow); |
187 } | 190 } |
188 | 191 |
189 void MultiWindowResizeController::Hide() { | 192 void MultiWindowResizeController::Hide() { |
190 hide_timer_.Stop(); | 193 hide_timer_.Stop(); |
191 if (window_resizer_.get()) | 194 if (window_resizer_.get()) |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 params.can_activate = false; | 365 params.can_activate = false; |
363 ResizeView* view = new ResizeView(this, windows_.direction); | 366 ResizeView* view = new ResizeView(this, windows_.direction); |
364 params.delegate = new views::WidgetDelegateView; | 367 params.delegate = new views::WidgetDelegateView; |
365 resize_widget_->set_focus_on_creation(false); | 368 resize_widget_->set_focus_on_creation(false); |
366 resize_widget_->Init(params); | 369 resize_widget_->Init(params); |
367 SetWindowVisibilityAnimationType( | 370 SetWindowVisibilityAnimationType( |
368 resize_widget_->GetNativeWindow(), | 371 resize_widget_->GetNativeWindow(), |
369 WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | 372 WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
370 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); | 373 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); |
371 resize_widget_->SetContentsView(view); | 374 resize_widget_->SetContentsView(view); |
372 show_bounds_ = CalculateResizeWidgetBounds(show_location_); | 375 show_bounds_in_screen_ = ScreenAsh::ConvertRectToScreen( |
373 resize_widget_->SetBounds(show_bounds_); | 376 windows_.window1->parent(), |
| 377 CalculateResizeWidgetBounds(show_location_in_parent_)); |
| 378 resize_widget_->SetBounds(show_bounds_in_screen_); |
374 resize_widget_->Show(); | 379 resize_widget_->Show(); |
375 mouse_watcher_.reset(new views::MouseWatcher( | 380 mouse_watcher_.reset(new views::MouseWatcher( |
376 new ResizeMouseWatcherHost(this), | 381 new ResizeMouseWatcherHost(this), |
377 this)); | 382 this)); |
378 mouse_watcher_->set_notify_on_exit_time( | 383 mouse_watcher_->set_notify_on_exit_time( |
379 base::TimeDelta::FromMilliseconds(kHideDelayMS)); | 384 base::TimeDelta::FromMilliseconds(kHideDelayMS)); |
380 mouse_watcher_->Start(); | 385 mouse_watcher_->Start(); |
381 } | 386 } |
382 | 387 |
383 bool MultiWindowResizeController::IsShowing() const { | 388 bool MultiWindowResizeController::IsShowing() const { |
384 return resize_widget_ || show_timer_.IsRunning(); | 389 return resize_widget_ || show_timer_.IsRunning(); |
385 } | 390 } |
386 | 391 |
387 void MultiWindowResizeController::StartResize( | 392 void MultiWindowResizeController::StartResize( |
388 const gfx::Point& screen_location) { | 393 const gfx::Point& location_in_screen) { |
389 DCHECK(!window_resizer_.get()); | 394 DCHECK(!window_resizer_.get()); |
390 DCHECK(windows_.is_valid()); | 395 DCHECK(windows_.is_valid()); |
391 hide_timer_.Stop(); | 396 hide_timer_.Stop(); |
392 gfx::Point parent_location(screen_location); | 397 gfx::Point location_in_parent(location_in_screen); |
393 aura::Window::ConvertPointToWindow( | 398 aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())-> |
394 windows_.window1->GetRootWindow(), windows_.window1->parent(), | 399 ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent); |
395 &parent_location); | |
396 std::vector<aura::Window*> windows; | 400 std::vector<aura::Window*> windows; |
397 windows.push_back(windows_.window2); | 401 windows.push_back(windows_.window2); |
398 FindWindowsTouching(windows_.window2, windows_.direction, | 402 FindWindowsTouching(windows_.window2, windows_.direction, |
399 &windows_.other_windows); | 403 &windows_.other_windows); |
400 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { | 404 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { |
401 windows_.other_windows[i]->AddObserver(this); | 405 windows_.other_windows[i]->AddObserver(this); |
402 windows.push_back(windows_.other_windows[i]); | 406 windows.push_back(windows_.other_windows[i]); |
403 } | 407 } |
404 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; | 408 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; |
405 window_resizer_.reset(WorkspaceWindowResizer::Create( | 409 window_resizer_.reset(WorkspaceWindowResizer::Create( |
406 windows_.window1, parent_location, component, windows)); | 410 windows_.window1, location_in_parent, component, windows)); |
407 } | 411 } |
408 | 412 |
409 void MultiWindowResizeController::Resize(const gfx::Point& screen_location, | 413 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, |
410 int event_flags) { | 414 int event_flags) { |
411 gfx::Point parent_location(screen_location); | 415 gfx::Point location_in_parent(location_in_screen); |
412 aura::Window::ConvertPointToWindow(windows_.window1->GetRootWindow(), | 416 aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())-> |
413 windows_.window1->parent(), | 417 ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent); |
414 &parent_location); | 418 window_resizer_->Drag(location_in_parent, event_flags); |
415 window_resizer_->Drag(parent_location, event_flags); | 419 gfx::Rect bounds = ScreenAsh::ConvertRectToScreen( |
416 gfx::Rect bounds = CalculateResizeWidgetBounds(parent_location); | 420 windows_.window1->parent(), |
| 421 CalculateResizeWidgetBounds(location_in_parent)); |
| 422 |
417 if (windows_.direction == LEFT_RIGHT) | 423 if (windows_.direction == LEFT_RIGHT) |
418 bounds.set_y(show_bounds_.y()); | 424 bounds.set_y(show_bounds_in_screen_.y()); |
419 else | 425 else |
420 bounds.set_x(show_bounds_.x()); | 426 bounds.set_x(show_bounds_in_screen_.x()); |
421 resize_widget_->SetBounds(bounds); | 427 resize_widget_->SetBounds(bounds); |
422 } | 428 } |
423 | 429 |
424 void MultiWindowResizeController::CompleteResize(int event_flags) { | 430 void MultiWindowResizeController::CompleteResize(int event_flags) { |
425 window_resizer_->CompleteDrag(event_flags); | 431 window_resizer_->CompleteDrag(event_flags); |
426 window_resizer_.reset(); | 432 window_resizer_.reset(); |
427 | 433 |
428 // Mouse may still be over resizer, if not hide. | 434 // Mouse may still be over resizer, if not hide. |
429 gfx::Point screen_loc = gfx::Screen::GetCursorScreenPoint(); | 435 gfx::Point screen_loc = gfx::Screen::GetCursorScreenPoint(); |
430 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) | 436 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) |
431 Hide(); | 437 Hide(); |
432 } | 438 } |
433 | 439 |
434 void MultiWindowResizeController::CancelResize() { | 440 void MultiWindowResizeController::CancelResize() { |
435 if (!window_resizer_.get()) | 441 if (!window_resizer_.get()) |
436 return; // Happens if window was destroyed and we nuked the WindowResizer. | 442 return; // Happens if window was destroyed and we nuked the WindowResizer. |
437 window_resizer_->RevertDrag(); | 443 window_resizer_->RevertDrag(); |
438 window_resizer_.reset(); | 444 window_resizer_.reset(); |
439 Hide(); | 445 Hide(); |
440 } | 446 } |
441 | 447 |
442 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( | 448 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( |
443 const gfx::Point& location) const { | 449 const gfx::Point& location_in_parent) const { |
444 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); | 450 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); |
445 int x = 0, y = 0; | 451 int x = 0, y = 0; |
446 if (windows_.direction == LEFT_RIGHT) { | 452 if (windows_.direction == LEFT_RIGHT) { |
447 x = windows_.window1->bounds().right() - pref.width() / 2; | 453 x = windows_.window1->bounds().right() - pref.width() / 2; |
448 y = location.y() + kResizeWidgetPadding; | 454 y = location_in_parent.y() + kResizeWidgetPadding; |
449 if (y + pref.height() / 2 > windows_.window1->bounds().bottom() && | 455 if (y + pref.height() / 2 > windows_.window1->bounds().bottom() && |
450 y + pref.height() / 2 > windows_.window2->bounds().bottom()) { | 456 y + pref.height() / 2 > windows_.window2->bounds().bottom()) { |
451 y = location.y() - kResizeWidgetPadding - pref.height(); | 457 y = location_in_parent.y() - kResizeWidgetPadding - pref.height(); |
452 } | 458 } |
453 } else { | 459 } else { |
454 x = location.x() + kResizeWidgetPadding; | 460 x = location_in_parent.x() + kResizeWidgetPadding; |
455 if (x + pref.height() / 2 > windows_.window1->bounds().right() && | 461 if (x + pref.height() / 2 > windows_.window1->bounds().right() && |
456 x + pref.height() / 2 > windows_.window2->bounds().right()) { | 462 x + pref.height() / 2 > windows_.window2->bounds().right()) { |
457 x = location.x() - kResizeWidgetPadding - pref.width(); | 463 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); |
458 } | 464 } |
459 y = windows_.window1->bounds().bottom() - pref.height() / 2; | 465 y = windows_.window1->bounds().bottom() - pref.height() / 2; |
460 } | 466 } |
461 return gfx::Rect(x, y, pref.width(), pref.height()); | 467 return gfx::Rect(x, y, pref.width(), pref.height()); |
462 } | 468 } |
463 | 469 |
464 bool MultiWindowResizeController::IsOverWindows( | 470 bool MultiWindowResizeController::IsOverWindows( |
465 const gfx::Point& screen_location) const { | 471 const gfx::Point& location_in_screen) const { |
466 if (window_resizer_.get()) | 472 if (window_resizer_.get()) |
467 return true; // Ignore hides while actively resizing. | 473 return true; // Ignore hides while actively resizing. |
468 | 474 |
469 if (resize_widget_->GetWindowBoundsInScreen().Contains(screen_location)) | 475 if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen)) |
470 return true; | 476 return true; |
471 | 477 |
472 int hit1, hit2; | 478 int hit1, hit2; |
473 if (windows_.direction == TOP_BOTTOM) { | 479 if (windows_.direction == TOP_BOTTOM) { |
474 hit1 = HTBOTTOM; | 480 hit1 = HTBOTTOM; |
475 hit2 = HTTOP; | 481 hit2 = HTTOP; |
476 } else { | 482 } else { |
477 hit1 = HTRIGHT; | 483 hit1 = HTRIGHT; |
478 hit2 = HTLEFT; | 484 hit2 = HTLEFT; |
479 } | 485 } |
480 | 486 |
481 return IsOverWindow(windows_.window1, screen_location, hit1) || | 487 return IsOverWindow(windows_.window1, location_in_screen, hit1) || |
482 IsOverWindow(windows_.window2, screen_location, hit2); | 488 IsOverWindow(windows_.window2, location_in_screen, hit2); |
483 } | 489 } |
484 | 490 |
485 bool MultiWindowResizeController::IsOverWindow( | 491 bool MultiWindowResizeController::IsOverWindow( |
486 aura::Window* window, | 492 aura::Window* window, |
487 const gfx::Point& screen_location, | 493 const gfx::Point& location_in_screen, |
488 int component) const { | 494 int component) const { |
489 if (!window->delegate()) | 495 if (!window->delegate()) |
490 return false; | 496 return false; |
491 | 497 |
492 gfx::Point window_loc(screen_location); | 498 gfx::Point window_loc(location_in_screen); |
493 aura::Window::ConvertPointToWindow( | 499 aura::Window::ConvertPointToWindow( |
494 window->GetRootWindow(), window, &window_loc); | 500 window->GetRootWindow(), window, &window_loc); |
495 return window->HitTest(window_loc) && | 501 return window->HitTest(window_loc) && |
496 window->delegate()->GetNonClientComponent(window_loc) == component; | 502 window->delegate()->GetNonClientComponent(window_loc) == component; |
497 } | 503 } |
498 | 504 |
499 } // namespace internal | 505 } // namespace internal |
500 } // namespace ash | 506 } // namespace ash |
OLD | NEW |