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 |