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 "chrome/browser/ui/views/ash/tab_scrubber.h" | 5 #include "chrome/browser/ui/views/ash/tab_scrubber.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/wm/window_util.h" | 8 #include "ash/wm/window_util.h" |
| 9 #include "chrome/browser/ui/browser.h" | 9 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/browser/ui/browser_finder.h" | 10 #include "chrome/browser/ui/browser_finder.h" |
| 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 12 #include "chrome/browser/ui/views/frame/browser_view.h" | 12 #include "chrome/browser/ui/views/frame/browser_view.h" |
| 13 #include "chrome/browser/ui/views/tabs/tab.h" | 13 #include "chrome/browser/ui/views/tabs/tab.h" |
| 14 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 14 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 15 #include "chrome/common/chrome_notification_types.h" | 15 #include "chrome/common/chrome_notification_types.h" |
| 16 #include "content/public/browser/notification_source.h" | 16 #include "content/public/browser/notification_source.h" |
| 17 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
| 18 #include "ui/base/events/event.h" | 18 #include "ui/base/events/event.h" |
| 19 #include "ui/base/events/event_utils.h" | |
| 20 | |
| 21 namespace { | |
| 22 Tab* GetTabAt(TabStrip* tab_strip, gfx::Point point) { | |
| 23 for (int i = 0; i < tab_strip->tab_count(); ++i) { | |
| 24 Tab* tab = tab_strip->tab_at(i); | |
| 25 if (tab_strip->tab_at(i)->bounds().Contains(point)) | |
| 26 return tab; | |
| 27 } | |
| 28 return NULL; | |
| 29 } | |
| 30 | |
| 31 const int kInitialTabOffset = 10; | |
|
sky
2012/11/28 23:36:19
nit: constants before methods, and add a descripti
| |
| 32 } | |
| 19 | 33 |
| 20 // static | 34 // static |
| 21 TabScrubber* TabScrubber::GetInstance() { | 35 TabScrubber* TabScrubber::GetInstance() { |
| 22 static TabScrubber* instance = NULL; | 36 static TabScrubber* instance = NULL; |
| 23 if (!instance) | 37 if (!instance) |
| 24 instance = new TabScrubber(); | 38 instance = new TabScrubber(); |
| 25 return instance; | 39 return instance; |
| 26 } | 40 } |
| 27 | 41 |
| 28 TabScrubber::TabScrubber() | 42 TabScrubber::TabScrubber() |
| 29 : scrubbing_(false), | 43 : scrubbing_(false), |
| 30 browser_(NULL), | 44 browser_(NULL), |
| 31 initial_tab_index_(-1), | 45 scroll_x_(-1), |
| 32 initial_x_(-1) { | 46 scroll_y_(-1) { |
| 33 ash::Shell::GetInstance()->AddPreTargetHandler(this); | 47 ash::Shell::GetInstance()->AddPreTargetHandler(this); |
| 34 } | 48 } |
| 35 | 49 |
| 36 TabScrubber::~TabScrubber() { | 50 TabScrubber::~TabScrubber() { |
| 37 } | 51 } |
| 38 | 52 |
| 39 ui::EventResult TabScrubber::OnMouseEvent(ui::MouseEvent* event) { | 53 ui::EventResult TabScrubber::OnScrollEvent(ui::ScrollEvent* event) { |
| 40 Browser* browser = GetActiveBrowser(); | 54 if (event->type() == ui::ET_SCROLL_FLING_CANCEL) { |
| 41 | |
| 42 if (!(event->type() == ui::ET_MOUSE_PRESSED || | |
| 43 event->type() == ui::ET_MOUSE_DRAGGED || | |
| 44 event->type() == ui::ET_MOUSE_RELEASED)) | |
| 45 return ui::ER_UNHANDLED; | |
| 46 | |
| 47 if (!browser || | |
| 48 (event->type() == ui::ET_MOUSE_RELEASED) || | |
| 49 !(event->flags() & ui::EF_CONTROL_DOWN) || | |
| 50 !(event->flags() & ui::EF_LEFT_MOUSE_BUTTON) || | |
| 51 (browser_ && browser != browser_)) { | |
| 52 if (scrubbing_) | 55 if (scrubbing_) |
| 53 StopScrubbing(); | 56 StopScrubbing(); |
| 54 return ui::ER_UNHANDLED; | 57 return ui::ER_UNHANDLED; |
| 55 } | 58 } |
| 56 | 59 |
| 60 if (event->finger_count() != 3 || | |
| 61 event->type() != ui::ET_SCROLL) | |
| 62 return ui::ER_UNHANDLED; | |
| 63 | |
| 64 Browser* browser = GetActiveBrowser(); | |
| 65 if (!browser || (browser_ && browser != browser_)) { | |
| 66 if (scrubbing_) | |
| 67 StopScrubbing(); | |
| 68 return ui::ER_UNHANDLED; | |
| 69 } | |
| 70 | |
| 71 BrowserView* browser_view = | |
| 72 BrowserView::GetBrowserViewForNativeWindow( | |
|
sky
2012/11/28 23:36:19
BrowserView::GetBrowserViewForBrowser(browser);
| |
| 73 browser->window()->GetNativeWindow()); | |
| 74 TabStrip* tab_strip = browser_view->tabstrip(); | |
| 75 | |
| 76 float x_offset = -event->x_offset(); | |
| 57 if (!scrubbing_) { | 77 if (!scrubbing_) { |
| 58 scrubbing_ = true; | 78 scrubbing_ = true; |
| 59 initial_x_ = event->x(); | |
| 60 browser_ = browser; | 79 browser_ = browser; |
| 61 initial_tab_index_ = browser_->active_index(); | 80 Tab* initial_tab = tab_strip->tab_at(browser_->active_index()); |
| 81 scroll_x_ = initial_tab->x(); | |
| 82 scroll_x_ += (x_offset < 0) ? | |
| 83 kInitialTabOffset : initial_tab->width() - kInitialTabOffset; | |
| 84 scroll_y_ = initial_tab->height() / 2; | |
| 62 registrar_.Add( | 85 registrar_.Add( |
| 63 this, | 86 this, |
| 64 chrome::NOTIFICATION_BROWSER_CLOSING, | 87 chrome::NOTIFICATION_BROWSER_CLOSING, |
| 65 content::Source<Browser>(browser_)); | 88 content::Source<Browser>(browser_)); |
| 66 } else { | 89 } |
| 67 BrowserView* browser_view = | |
| 68 BrowserView::GetBrowserViewForNativeWindow( | |
| 69 browser_->window()->GetNativeWindow()); | |
| 70 TabStrip* tab_strip = browser_view->tabstrip(); | |
| 71 Tab* initial_tab = tab_strip->tab_at(initial_tab_index_); | |
| 72 if (!initial_tab) { | |
| 73 StopScrubbing(); | |
| 74 return ui::ER_UNHANDLED; | |
| 75 } | |
| 76 | 90 |
| 77 gfx::Point tab_point((initial_tab->width() / 2) + event->x() - initial_x_, | 91 if (ui::IsNaturalScrollEnabled()) |
| 78 initial_tab->height() / 2); | 92 scroll_x_ += event->x_offset(); |
| 79 Tab* new_tab = tab_strip->GetTabAt(initial_tab, tab_point); | 93 else |
| 80 if (new_tab && !new_tab->IsActive()) { | 94 scroll_x_ -= event->x_offset(); |
| 81 int new_index = tab_strip->GetModelIndexOfTab(new_tab); | 95 Tab* first_tab = tab_strip->tab_at(0); |
| 82 browser->tab_strip_model()->ActivateTabAt(new_index, true); | 96 Tab* last_tab = tab_strip->tab_at(tab_strip->tab_count() - 1); |
| 83 } | 97 if (scroll_x_ < first_tab->x()) |
| 98 scroll_x_ = first_tab->x(); | |
| 99 if (scroll_x_ > last_tab->bounds().right()) | |
| 100 scroll_x_ = last_tab->bounds().right(); | |
| 101 | |
| 102 gfx::Point tab_point(scroll_x_, scroll_y_); | |
| 103 Tab* new_tab = GetTabAt(tab_strip, tab_point); | |
| 104 if (new_tab && !new_tab->IsActive()) { | |
| 105 int new_index = tab_strip->GetModelIndexOfTab(new_tab); | |
| 106 browser->tab_strip_model()->ActivateTabAt(new_index, true); | |
| 84 } | 107 } |
| 85 | 108 |
| 86 return ui::ER_CONSUMED; | 109 return ui::ER_CONSUMED; |
| 87 } | 110 } |
| 88 | 111 |
| 89 void TabScrubber::Observe(int type, | 112 void TabScrubber::Observe(int type, |
| 90 const content::NotificationSource& source, | 113 const content::NotificationSource& source, |
| 91 const content::NotificationDetails& details) { | 114 const content::NotificationDetails& details) { |
| 92 DCHECK(type == chrome::NOTIFICATION_BROWSER_CLOSING && | 115 DCHECK(type == chrome::NOTIFICATION_BROWSER_CLOSING && |
| 93 content::Source<Browser>(source).ptr() == browser_); | 116 content::Source<Browser>(source).ptr() == browser_); |
| 94 StopScrubbing(); | 117 StopScrubbing(); |
| 95 } | 118 } |
| 96 | 119 |
| 97 Browser* TabScrubber::GetActiveBrowser() { | 120 Browser* TabScrubber::GetActiveBrowser() { |
| 98 aura::Window* active_window = ash::wm::GetActiveWindow(); | 121 aura::Window* active_window = ash::wm::GetActiveWindow(); |
| 99 if (!active_window) | 122 if (!active_window) |
| 100 return NULL; | 123 return NULL; |
| 101 | 124 |
| 102 Browser* browser = browser::FindBrowserWithWindow(active_window); | 125 Browser* browser = browser::FindBrowserWithWindow(active_window); |
| 103 if (!browser || browser->type() != Browser::TYPE_TABBED) | 126 if (!browser || browser->type() != Browser::TYPE_TABBED) |
| 104 return NULL; | 127 return NULL; |
| 105 | 128 |
| 106 return browser; | 129 return browser; |
| 107 } | 130 } |
| 108 | 131 |
| 109 void TabScrubber::StopScrubbing() { | 132 void TabScrubber::StopScrubbing() { |
| 133 if (!scrubbing_) | |
| 134 return; | |
| 135 | |
| 110 registrar_.Remove( | 136 registrar_.Remove( |
| 111 this, | 137 this, |
| 112 chrome::NOTIFICATION_BROWSER_CLOSING, | 138 chrome::NOTIFICATION_BROWSER_CLOSING, |
| 113 content::Source<Browser>(browser_)); | 139 content::Source<Browser>(browser_)); |
| 114 scrubbing_ = false; | 140 scrubbing_ = false; |
| 115 browser_ = NULL; | 141 browser_ = NULL; |
| 116 initial_tab_index_ = -1; | |
| 117 } | 142 } |
| OLD | NEW |