Chromium Code Reviews| Index: chrome/browser/ui/views/ash/tab_scrubber.cc |
| diff --git a/chrome/browser/ui/views/ash/tab_scrubber.cc b/chrome/browser/ui/views/ash/tab_scrubber.cc |
| index 23e26b88dd05e7ab761641c8e2582a0c9d2c3c8e..5626d45d2f50cef353ab832da9cc4c44d2346ac3 100644 |
| --- a/chrome/browser/ui/views/ash/tab_scrubber.cc |
| +++ b/chrome/browser/ui/views/ash/tab_scrubber.cc |
| @@ -16,6 +16,20 @@ |
| #include "content/public/browser/notification_source.h" |
| #include "ui/aura/window.h" |
| #include "ui/base/events/event.h" |
| +#include "ui/base/events/event_utils.h" |
| + |
| +namespace { |
| +Tab* GetTabAt(TabStrip* tab_strip, gfx::Point point) { |
| + for (int i = 0; i < tab_strip->tab_count(); ++i) { |
| + Tab* tab = tab_strip->tab_at(i); |
| + if (tab_strip->tab_at(i)->bounds().Contains(point)) |
| + return tab; |
| + } |
| + return NULL; |
| +} |
| + |
| +const int kInitialTabOffset = 10; |
|
sky
2012/11/28 23:36:19
nit: constants before methods, and add a descripti
|
| +} |
| // static |
| TabScrubber* TabScrubber::GetInstance() { |
| @@ -28,59 +42,68 @@ TabScrubber* TabScrubber::GetInstance() { |
| TabScrubber::TabScrubber() |
| : scrubbing_(false), |
| browser_(NULL), |
| - initial_tab_index_(-1), |
| - initial_x_(-1) { |
| + scroll_x_(-1), |
| + scroll_y_(-1) { |
| ash::Shell::GetInstance()->AddPreTargetHandler(this); |
| } |
| TabScrubber::~TabScrubber() { |
| } |
| -ui::EventResult TabScrubber::OnMouseEvent(ui::MouseEvent* event) { |
| - Browser* browser = GetActiveBrowser(); |
| +ui::EventResult TabScrubber::OnScrollEvent(ui::ScrollEvent* event) { |
| + if (event->type() == ui::ET_SCROLL_FLING_CANCEL) { |
| + if (scrubbing_) |
| + StopScrubbing(); |
| + return ui::ER_UNHANDLED; |
| + } |
| - if (!(event->type() == ui::ET_MOUSE_PRESSED || |
| - event->type() == ui::ET_MOUSE_DRAGGED || |
| - event->type() == ui::ET_MOUSE_RELEASED)) |
| + if (event->finger_count() != 3 || |
| + event->type() != ui::ET_SCROLL) |
| return ui::ER_UNHANDLED; |
| - if (!browser || |
| - (event->type() == ui::ET_MOUSE_RELEASED) || |
| - !(event->flags() & ui::EF_CONTROL_DOWN) || |
| - !(event->flags() & ui::EF_LEFT_MOUSE_BUTTON) || |
| - (browser_ && browser != browser_)) { |
| + Browser* browser = GetActiveBrowser(); |
| + if (!browser || (browser_ && browser != browser_)) { |
| if (scrubbing_) |
| StopScrubbing(); |
| return ui::ER_UNHANDLED; |
| } |
| + BrowserView* browser_view = |
| + BrowserView::GetBrowserViewForNativeWindow( |
|
sky
2012/11/28 23:36:19
BrowserView::GetBrowserViewForBrowser(browser);
|
| + browser->window()->GetNativeWindow()); |
| + TabStrip* tab_strip = browser_view->tabstrip(); |
| + |
| + float x_offset = -event->x_offset(); |
| if (!scrubbing_) { |
| scrubbing_ = true; |
| - initial_x_ = event->x(); |
| browser_ = browser; |
| - initial_tab_index_ = browser_->active_index(); |
| + Tab* initial_tab = tab_strip->tab_at(browser_->active_index()); |
| + scroll_x_ = initial_tab->x(); |
| + scroll_x_ += (x_offset < 0) ? |
| + kInitialTabOffset : initial_tab->width() - kInitialTabOffset; |
| + scroll_y_ = initial_tab->height() / 2; |
| registrar_.Add( |
| this, |
| chrome::NOTIFICATION_BROWSER_CLOSING, |
| content::Source<Browser>(browser_)); |
| - } else { |
| - BrowserView* browser_view = |
| - BrowserView::GetBrowserViewForNativeWindow( |
| - browser_->window()->GetNativeWindow()); |
| - TabStrip* tab_strip = browser_view->tabstrip(); |
| - Tab* initial_tab = tab_strip->tab_at(initial_tab_index_); |
| - if (!initial_tab) { |
| - StopScrubbing(); |
| - return ui::ER_UNHANDLED; |
| - } |
| - |
| - gfx::Point tab_point((initial_tab->width() / 2) + event->x() - initial_x_, |
| - initial_tab->height() / 2); |
| - Tab* new_tab = tab_strip->GetTabAt(initial_tab, tab_point); |
| - if (new_tab && !new_tab->IsActive()) { |
| - int new_index = tab_strip->GetModelIndexOfTab(new_tab); |
| - browser->tab_strip_model()->ActivateTabAt(new_index, true); |
| - } |
| + } |
| + |
| + if (ui::IsNaturalScrollEnabled()) |
| + scroll_x_ += event->x_offset(); |
| + else |
| + scroll_x_ -= event->x_offset(); |
| + Tab* first_tab = tab_strip->tab_at(0); |
| + Tab* last_tab = tab_strip->tab_at(tab_strip->tab_count() - 1); |
| + if (scroll_x_ < first_tab->x()) |
| + scroll_x_ = first_tab->x(); |
| + if (scroll_x_ > last_tab->bounds().right()) |
| + scroll_x_ = last_tab->bounds().right(); |
| + |
| + gfx::Point tab_point(scroll_x_, scroll_y_); |
| + Tab* new_tab = GetTabAt(tab_strip, tab_point); |
| + if (new_tab && !new_tab->IsActive()) { |
| + int new_index = tab_strip->GetModelIndexOfTab(new_tab); |
| + browser->tab_strip_model()->ActivateTabAt(new_index, true); |
| } |
| return ui::ER_CONSUMED; |
| @@ -107,11 +130,13 @@ Browser* TabScrubber::GetActiveBrowser() { |
| } |
| void TabScrubber::StopScrubbing() { |
| + if (!scrubbing_) |
| + return; |
| + |
| registrar_.Remove( |
| this, |
| chrome::NOTIFICATION_BROWSER_CLOSING, |
| content::Source<Browser>(browser_)); |
| scrubbing_ = false; |
| browser_ = NULL; |
| - initial_tab_index_ = -1; |
| } |