| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/views/tabs/dragged_tab_controller.h" | 5 #include "chrome/browser/views/tabs/dragged_tab_controller.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "app/animation.h" | 10 #include "app/animation.h" |
| 11 #include "app/gfx/canvas.h" | 11 #include "app/gfx/canvas.h" |
| 12 #include "app/l10n_util.h" |
| 12 #include "app/resource_bundle.h" | 13 #include "app/resource_bundle.h" |
| 13 #include "chrome/browser/browser_window.h" | 14 #include "chrome/browser/browser_window.h" |
| 14 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 15 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
| 15 #include "chrome/browser/tab_contents/tab_contents.h" | 16 #include "chrome/browser/tab_contents/tab_contents.h" |
| 16 #include "chrome/browser/metrics/user_metrics.h" | 17 #include "chrome/browser/metrics/user_metrics.h" |
| 17 #include "chrome/browser/views/frame/browser_view.h" | 18 #include "chrome/browser/views/frame/browser_view.h" |
| 18 #include "chrome/browser/views/tabs/dragged_tab_view.h" | 19 #include "chrome/browser/views/tabs/dragged_tab_view.h" |
| 19 #include "chrome/browser/views/tabs/native_view_photobooth.h" | 20 #include "chrome/browser/views/tabs/native_view_photobooth.h" |
| 20 #include "chrome/browser/views/tabs/tab.h" | 21 #include "chrome/browser/views/tabs/tab.h" |
| 21 #include "chrome/browser/views/tabs/tab_strip.h" | 22 #include "chrome/browser/views/tabs/tab_strip.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 paint.setColor(SkColorSetRGB(108, 108, 108)); | 64 paint.setColor(SkColorSetRGB(108, 108, 108)); |
| 64 paint.setStyle(SkPaint::kFill_Style); | 65 paint.setStyle(SkPaint::kFill_Style); |
| 65 canvas->drawRoundRect(outer_rect, SkIntToScalar(kRoundedRectRadius), | 66 canvas->drawRoundRect(outer_rect, SkIntToScalar(kRoundedRectRadius), |
| 66 SkIntToScalar(kRoundedRectRadius), paint); | 67 SkIntToScalar(kRoundedRectRadius), paint); |
| 67 | 68 |
| 68 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 69 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 69 | 70 |
| 70 SkBitmap* high_icon = rb.GetBitmapNamed(IDR_DOCK_HIGH); | 71 SkBitmap* high_icon = rb.GetBitmapNamed(IDR_DOCK_HIGH); |
| 71 SkBitmap* wide_icon = rb.GetBitmapNamed(IDR_DOCK_WIDE); | 72 SkBitmap* wide_icon = rb.GetBitmapNamed(IDR_DOCK_WIDE); |
| 72 | 73 |
| 74 bool rtl_ui = l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT; |
| 75 if (rtl_ui) { |
| 76 // Flip canvas to draw the mirrored tab images for RTL UI. |
| 77 canvas->save(); |
| 78 canvas->TranslateInt(width(), 0); |
| 79 canvas->ScaleInt(-1, 1); |
| 80 } |
| 81 int x_of_active_tab = -1; |
| 82 int x_of_inactive_tab = -1; |
| 73 switch (type_) { | 83 switch (type_) { |
| 74 case DockInfo::LEFT_OF_WINDOW: | 84 case DockInfo::LEFT_OF_WINDOW: |
| 75 case DockInfo::LEFT_HALF: | 85 case DockInfo::LEFT_HALF: |
| 76 canvas->DrawBitmapInt(*high_icon, | 86 if (!rtl_ui) { |
| 77 width() / 2 - high_icon->width() - kTabSpacing / 2, | 87 x_of_active_tab = width() / 2 - high_icon->width() - kTabSpacing / 2; |
| 78 (height() - high_icon->height()) / 2); | 88 x_of_inactive_tab = width() / 2 + kTabSpacing / 2; |
| 89 } else { |
| 90 // Adjust x axis for RTL UI after flippping canvas. |
| 91 x_of_active_tab = width() / 2 + kTabSpacing / 2; |
| 92 x_of_inactive_tab = width() / 2 - high_icon->width() - |
| 93 kTabSpacing / 2; |
| 94 } |
| 95 canvas->DrawBitmapInt(*high_icon, x_of_active_tab, |
| 96 (height() - high_icon->height()) / 2); |
| 79 if (type_ == DockInfo::LEFT_OF_WINDOW) { | 97 if (type_ == DockInfo::LEFT_OF_WINDOW) { |
| 80 DrawBitmapWithAlpha(canvas, *high_icon, width() / 2 + kTabSpacing / 2, | 98 DrawBitmapWithAlpha(canvas, *high_icon, x_of_inactive_tab, |
| 81 (height() - high_icon->height()) / 2); | 99 (height() - high_icon->height()) / 2); |
| 82 } | 100 } |
| 83 break; | 101 break; |
| 84 | 102 |
| 85 | 103 |
| 86 case DockInfo::RIGHT_OF_WINDOW: | 104 case DockInfo::RIGHT_OF_WINDOW: |
| 87 case DockInfo::RIGHT_HALF: | 105 case DockInfo::RIGHT_HALF: |
| 88 canvas->DrawBitmapInt(*high_icon, width() / 2 + kTabSpacing / 2, | 106 if (!rtl_ui) { |
| 107 x_of_active_tab = width() / 2 + kTabSpacing / 2; |
| 108 x_of_inactive_tab = width() / 2 - high_icon->width() - |
| 109 kTabSpacing / 2; |
| 110 } else { |
| 111 // Adjust x axis for RTL UI after flippping canvas. |
| 112 x_of_active_tab = width() / 2 - high_icon->width() - kTabSpacing / 2; |
| 113 x_of_inactive_tab = width() / 2 + kTabSpacing / 2; |
| 114 } |
| 115 canvas->DrawBitmapInt(*high_icon, x_of_active_tab, |
| 89 (height() - high_icon->height()) / 2); | 116 (height() - high_icon->height()) / 2); |
| 90 if (type_ == DockInfo::RIGHT_OF_WINDOW) { | 117 if (type_ == DockInfo::RIGHT_OF_WINDOW) { |
| 91 DrawBitmapWithAlpha(canvas, *high_icon, | 118 DrawBitmapWithAlpha(canvas, *high_icon, x_of_inactive_tab, |
| 92 width() / 2 - high_icon->width() - kTabSpacing / 2, | 119 (height() - high_icon->height()) / 2); |
| 93 (height() - high_icon->height()) / 2); | |
| 94 } | 120 } |
| 95 break; | 121 break; |
| 96 | 122 |
| 97 case DockInfo::TOP_OF_WINDOW: | 123 case DockInfo::TOP_OF_WINDOW: |
| 98 canvas->DrawBitmapInt(*wide_icon, (width() - wide_icon->width()) / 2, | 124 canvas->DrawBitmapInt(*wide_icon, (width() - wide_icon->width()) / 2, |
| 99 height() / 2 - high_icon->height()); | 125 height() / 2 - high_icon->height()); |
| 100 break; | 126 break; |
| 101 | 127 |
| 102 case DockInfo::MAXIMIZE: { | 128 case DockInfo::MAXIMIZE: { |
| 103 SkBitmap* max_icon = rb.GetBitmapNamed(IDR_DOCK_MAX); | 129 SkBitmap* max_icon = rb.GetBitmapNamed(IDR_DOCK_MAX); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 114 DrawBitmapWithAlpha(canvas, *wide_icon, | 140 DrawBitmapWithAlpha(canvas, *wide_icon, |
| 115 (width() - wide_icon->width()) / 2, | 141 (width() - wide_icon->width()) / 2, |
| 116 height() / 2 - kTabSpacing / 2 - wide_icon->height()); | 142 height() / 2 - kTabSpacing / 2 - wide_icon->height()); |
| 117 } | 143 } |
| 118 break; | 144 break; |
| 119 | 145 |
| 120 default: | 146 default: |
| 121 NOTREACHED(); | 147 NOTREACHED(); |
| 122 break; | 148 break; |
| 123 } | 149 } |
| 150 if (rtl_ui) |
| 151 canvas->restore(); |
| 124 } | 152 } |
| 125 | 153 |
| 126 private: | 154 private: |
| 127 void DrawBitmapWithAlpha(gfx::Canvas* canvas, const SkBitmap& image, | 155 void DrawBitmapWithAlpha(gfx::Canvas* canvas, const SkBitmap& image, |
| 128 int x, int y) { | 156 int x, int y) { |
| 129 SkPaint paint; | 157 SkPaint paint; |
| 130 paint.setAlpha(128); | 158 paint.setAlpha(128); |
| 131 canvas->DrawBitmapInt(image, x, y, paint); | 159 canvas->DrawBitmapInt(image, x, y, paint); |
| 132 } | 160 } |
| 133 | 161 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 // contents to NULL, otherwise if the view is animating to its destination | 322 // contents to NULL, otherwise if the view is animating to its destination |
| 295 // bounds, it won't be able to clean up properly since its cleanup routine | 323 // bounds, it won't be able to clean up properly since its cleanup routine |
| 296 // uses GetIndexForDraggedContents, which will be invalid. | 324 // uses GetIndexForDraggedContents, which will be invalid. |
| 297 view_.reset(NULL); | 325 view_.reset(NULL); |
| 298 SetDraggedContents(NULL); // This removes our observer. | 326 SetDraggedContents(NULL); // This removes our observer. |
| 299 } | 327 } |
| 300 | 328 |
| 301 void DraggedTabController::CaptureDragInfo(const gfx::Point& mouse_offset) { | 329 void DraggedTabController::CaptureDragInfo(const gfx::Point& mouse_offset) { |
| 302 start_screen_point_ = GetCursorScreenPoint(); | 330 start_screen_point_ = GetCursorScreenPoint(); |
| 303 mouse_offset_ = mouse_offset; | 331 mouse_offset_ = mouse_offset; |
| 332 InitWindowCreatePoint(); |
| 304 } | 333 } |
| 305 | 334 |
| 306 void DraggedTabController::Drag() { | 335 void DraggedTabController::Drag() { |
| 307 bring_to_front_timer_.Stop(); | 336 bring_to_front_timer_.Stop(); |
| 308 | 337 |
| 309 // Before we get to dragging anywhere, ensure that we consider ourselves | 338 // Before we get to dragging anywhere, ensure that we consider ourselves |
| 310 // attached to the source tabstrip. | 339 // attached to the source tabstrip. |
| 311 if (source_tab_->IsVisible() && CanStartDrag()) | 340 if (source_tab_->IsVisible() && CanStartDrag()) |
| 312 Attach(source_tabstrip_, gfx::Point()); | 341 Attach(source_tabstrip_, gfx::Point()); |
| 313 | 342 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 void DraggedTabController::DidProcessEvent(GdkEvent* event) { | 483 void DraggedTabController::DidProcessEvent(GdkEvent* event) { |
| 455 NOTIMPLEMENTED(); | 484 NOTIMPLEMENTED(); |
| 456 } | 485 } |
| 457 #endif | 486 #endif |
| 458 | 487 |
| 459 /////////////////////////////////////////////////////////////////////////////// | 488 /////////////////////////////////////////////////////////////////////////////// |
| 460 // DraggedTabController, private: | 489 // DraggedTabController, private: |
| 461 | 490 |
| 462 void DraggedTabController::InitWindowCreatePoint() { | 491 void DraggedTabController::InitWindowCreatePoint() { |
| 463 window_create_point_.SetPoint(mouse_offset_.x(), mouse_offset_.y()); | 492 window_create_point_.SetPoint(mouse_offset_.x(), mouse_offset_.y()); |
| 464 Tab* first_tab = attached_tabstrip_->GetTabAt(0); | 493 // window_create_point_ is only used in CompleteDrag() (through |
| 494 // GetWindowCreatePoint() to get the start point of the docked window) when |
| 495 // the attached_tabstrip_ is NULL and all the window's related bound |
| 496 // information are obtained from source_tabstrip_. So, we need to get the |
| 497 // first_tab based on source_tabstrip_, not attached_tabstrip_. Otherwise, |
| 498 // the window_create_point_ is not in the correct coordinate system. Please |
| 499 // refer to http://crbug.com/6223 comment #15 for detailed information. |
| 500 Tab* first_tab = source_tabstrip_->GetTabAt(0); |
| 465 views::View::ConvertPointToWidget(first_tab, &window_create_point_); | 501 views::View::ConvertPointToWidget(first_tab, &window_create_point_); |
| 466 } | 502 } |
| 467 | 503 |
| 468 gfx::Point DraggedTabController::GetWindowCreatePoint() const { | 504 gfx::Point DraggedTabController::GetWindowCreatePoint() const { |
| 469 gfx::Point cursor_point = GetCursorScreenPoint(); | 505 gfx::Point cursor_point = GetCursorScreenPoint(); |
| 470 if (dock_info_.type() != DockInfo::NONE) { | 506 if (dock_info_.type() != DockInfo::NONE) { |
| 471 // If we're going to dock, we need to return the exact coordinate, | 507 // If we're going to dock, we need to return the exact coordinate, |
| 472 // otherwise we may attempt to maximize on the wrong monitor. | 508 // otherwise we may attempt to maximize on the wrong monitor. |
| 473 return cursor_point; | 509 return cursor_point; |
| 474 } | 510 } |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 screen_point.y() <= upper_threshold) { | 717 screen_point.y() <= upper_threshold) { |
| 682 return tabstrip; | 718 return tabstrip; |
| 683 } | 719 } |
| 684 } | 720 } |
| 685 return NULL; | 721 return NULL; |
| 686 } | 722 } |
| 687 | 723 |
| 688 void DraggedTabController::Attach(TabStrip* attached_tabstrip, | 724 void DraggedTabController::Attach(TabStrip* attached_tabstrip, |
| 689 const gfx::Point& screen_point) { | 725 const gfx::Point& screen_point) { |
| 690 attached_tabstrip_ = attached_tabstrip; | 726 attached_tabstrip_ = attached_tabstrip; |
| 691 InitWindowCreatePoint(); | |
| 692 attached_tabstrip_->GenerateIdealBounds(); | 727 attached_tabstrip_->GenerateIdealBounds(); |
| 693 | 728 |
| 694 // We don't need the photo-booth while we're attached. | 729 // We don't need the photo-booth while we're attached. |
| 695 photobooth_.reset(NULL); | 730 photobooth_.reset(NULL); |
| 696 | 731 |
| 697 Tab* tab = GetTabMatchingDraggedContents(attached_tabstrip_); | 732 Tab* tab = GetTabMatchingDraggedContents(attached_tabstrip_); |
| 698 | 733 |
| 699 // Update the View first, so we can ask it for its bounds and determine | 734 // Update the View first, so we can ask it for its bounds and determine |
| 700 // where to insert the hidden Tab. | 735 // where to insert the hidden Tab. |
| 701 | 736 |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 default: | 1079 default: |
| 1045 NOTREACHED(); | 1080 NOTREACHED(); |
| 1046 break; | 1081 break; |
| 1047 } | 1082 } |
| 1048 } | 1083 } |
| 1049 // Compel the model to construct a new window for the detached TabContents. | 1084 // Compel the model to construct a new window for the detached TabContents. |
| 1050 gfx::Rect browser_rect = source_tabstrip_->GetWindow()->GetBounds(); | 1085 gfx::Rect browser_rect = source_tabstrip_->GetWindow()->GetBounds(); |
| 1051 gfx::Rect window_bounds( | 1086 gfx::Rect window_bounds( |
| 1052 GetWindowCreatePoint(), | 1087 GetWindowCreatePoint(), |
| 1053 gfx::Size(browser_rect.width(), browser_rect.height())); | 1088 gfx::Size(browser_rect.width(), browser_rect.height())); |
| 1089 // When modifying the following if statement, please make sure not to |
| 1090 // introduce issue listed in http://crbug.com/6223 comment #11. |
| 1091 bool rtl_ui = (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT); |
| 1092 bool has_dock_position = (dock_info_.type() != DockInfo::NONE); |
| 1093 if (rtl_ui && has_dock_position) { |
| 1094 // Mirror X axis so the docked tab is aligned using the mouse click as |
| 1095 // the top-right corner. |
| 1096 window_bounds.set_x(window_bounds.x() - window_bounds.width()); |
| 1097 } |
| 1054 Browser* new_browser = | 1098 Browser* new_browser = |
| 1055 source_tabstrip_->model()->delegate()->CreateNewStripWithContents( | 1099 source_tabstrip_->model()->delegate()->CreateNewStripWithContents( |
| 1056 dragged_contents_, window_bounds, dock_info_); | 1100 dragged_contents_, window_bounds, dock_info_); |
| 1057 new_browser->window()->Show(); | 1101 new_browser->window()->Show(); |
| 1058 CleanUpHiddenFrame(); | 1102 CleanUpHiddenFrame(); |
| 1059 } | 1103 } |
| 1060 | 1104 |
| 1061 return destroy_immediately; | 1105 return destroy_immediately; |
| 1062 } | 1106 } |
| 1063 | 1107 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1189 | 1233 |
| 1190 // The previous call made the window appear on top of the dragged window, | 1234 // The previous call made the window appear on top of the dragged window, |
| 1191 // move the dragged window to the front. | 1235 // move the dragged window to the front. |
| 1192 SetWindowPos(view_->GetWidget()->GetNativeView(), HWND_TOP, 0, 0, 0, 0, | 1236 SetWindowPos(view_->GetWidget()->GetNativeView(), HWND_TOP, 0, 0, 0, 0, |
| 1193 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | 1237 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); |
| 1194 #else | 1238 #else |
| 1195 NOTIMPLEMENTED(); | 1239 NOTIMPLEMENTED(); |
| 1196 #endif | 1240 #endif |
| 1197 } | 1241 } |
| 1198 } | 1242 } |
| OLD | NEW |