Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: chrome/browser/ui/touch/tabs/touch_tab_strip.cc

Issue 6750007: Scrolling Tabs (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: TODO for transformable views Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/touch/tabs/touch_tab_strip.h" 5 #include "chrome/browser/ui/touch/tabs/touch_tab_strip.h"
6 6
7 #include <cmath>
sky 2011/04/06 15:11:50 Can these be sorted?
wyck 2011/04/06 20:14:24 Done.
8 #include <algorithm>
9
7 #include "chrome/browser/ui/touch/tabs/touch_tab.h" 10 #include "chrome/browser/ui/touch/tabs/touch_tab.h"
8 #include "chrome/browser/ui/view_ids.h" 11 #include "chrome/browser/ui/view_ids.h"
9 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" 12 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h"
10 #include "ui/gfx/canvas_skia.h" 13 #include "ui/gfx/canvas_skia.h"
11 #include "views/metrics.h" 14 #include "views/metrics.h"
12 #include "views/window/non_client_view.h" 15 #include "views/window/non_client_view.h"
13 #include "views/window/window.h" 16 #include "views/window/window.h"
14 17
15 static const int kTouchTabStripHeight = 64; 18 static const int kTouchTabStripHeight = 64;
16 static const int kTouchTabWidth = 64; 19 static const int kTouchTabWidth = 64;
17 static const int kTouchTabHeight = 64; 20 static const int kTouchTabHeight = 64;
21 static const int kScrollThreshold = 4;
18 22
19 TouchTabStrip::TouchTabStrip(TabStripController* controller) 23 TouchTabStrip::TouchTabStrip(TabStripController* controller)
20 : BaseTabStrip(controller, BaseTabStrip::HORIZONTAL_TAB_STRIP), 24 : BaseTabStrip(controller, BaseTabStrip::HORIZONTAL_TAB_STRIP),
21 in_tab_close_(false), 25 in_tab_close_(false),
22 last_tap_time_(base::Time::FromInternalValue(0)), 26 last_tap_time_(base::Time::FromInternalValue(0)),
23 last_tapped_view_(NULL) { 27 last_tapped_view_(NULL),
28 initial_mouse_x_(0),
29 initial_scroll_offset_(0),
30 scroll_offset_(0),
31 scrolling_(false),
32 initial_tab_(NULL),
33 min_scroll_offset_(0) {
24 Init(); 34 Init();
25 } 35 }
26 36
27 TouchTabStrip::~TouchTabStrip() { 37 TouchTabStrip::~TouchTabStrip() {
28 // The animations may reference the tabs. Shut down the animation before we 38 // The animations may reference the tabs. Shut down the animation before we
29 // delete the tabs. 39 // delete the tabs.
30 StopAnimating(false); 40 StopAnimating(false);
31 41
32 DestroyDragController(); 42 DestroyDragController();
33 43
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 return in_tab_close_; 131 return in_tab_close_;
122 } 132 }
123 133
124 void TouchTabStrip::GenerateIdealBounds() { 134 void TouchTabStrip::GenerateIdealBounds() {
125 gfx::Rect bounds; 135 gfx::Rect bounds;
126 int tab_x = 0; 136 int tab_x = 0;
127 int tab_y = 0; 137 int tab_y = 0;
128 for (int i = 0; i < tab_count(); ++i) { 138 for (int i = 0; i < tab_count(); ++i) {
129 TouchTab* tab = GetTabAtTabDataIndex(i); 139 TouchTab* tab = GetTabAtTabDataIndex(i);
130 if (!tab->closing()) { 140 if (!tab->closing()) {
131 set_ideal_bounds(i, gfx::Rect(tab_x, tab_y, kTouchTabWidth, 141 int x = tab_x + scroll_offset_;
132 kTouchTabHeight)); 142 if (tab->IsSelected()) {
143 // limit the extent to which this tab can be displaced.
144 x = std::min(std::max(0, x), width() - kTouchTabWidth);
145 }
146 set_ideal_bounds(i, gfx::Rect(x, tab_y,
147 kTouchTabWidth, kTouchTabHeight));
133 // offset the next tab to the right by the width of this tab 148 // offset the next tab to the right by the width of this tab
134 tab_x += kTouchTabWidth; 149 tab_x += kTouchTabWidth;
135 } 150 }
136 } 151 }
152 min_scroll_offset_ = std::min(0, width() - tab_x);
137 } 153 }
138 154
139 void TouchTabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs, 155 void TouchTabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs,
140 BaseTab* active_tab, 156 BaseTab* active_tab,
141 const gfx::Point& location, 157 const gfx::Point& location,
142 bool initial_drag) { 158 bool initial_drag) {
143 // Not needed as dragging isn't supported. 159 // Not needed as dragging isn't supported.
144 NOTIMPLEMENTED(); 160 NOTIMPLEMENTED();
145 } 161 }
146 162
147 int TouchTabStrip::GetSizeNeededForTabs(const std::vector<BaseTab*>& tabs) { 163 int TouchTabStrip::GetSizeNeededForTabs(const std::vector<BaseTab*>& tabs) {
148 // Not needed as dragging isn't supported. 164 // Not needed as dragging isn't supported.
149 NOTIMPLEMENTED(); 165 NOTIMPLEMENTED();
150 return 0; 166 return 0;
151 } 167 }
152 168
169 // TODO(wyck): Someday we might like to get a "scroll" interaction event by way
170 // of views, triggered by the gesture manager, and/or mouse scroll wheel.
171 // For now, we're just handling a single scroll with these mouse events:
172 // OnMousePressed, OnMouseDragged, and OnMouseReleased.
173
174 bool TouchTabStrip::OnMousePressed(const views::MouseEvent& event) {
175 // When we press the mouse button, we begin a drag
176 BeginScroll(event.location());
177 return true;
178 }
179
180 bool TouchTabStrip::OnMouseDragged(const views::MouseEvent& event) {
181 ContinueScroll(event.location());
182 DoLayout();
183 SchedulePaint();
184 return true;
185 }
186
187 void TouchTabStrip::OnMouseReleased(const views::MouseEvent& event,
188 bool canceled) {
189 if (canceled) {
190 // Cancel the scroll by scrolling back to the initial position (deltax = 0).
191 ScrollTo(0);
192 StopAnimating(false);
193 GenerateIdealBounds();
194 AnimateToIdealBounds();
195 } else {
196 EndScroll(event.location());
197 }
198 SchedulePaint();
199 }
200
201 void TouchTabStrip::BeginScroll(const gfx::Point& point ) {
202 initial_mouse_x_ = point.x();
203 initial_scroll_offset_ = scroll_offset_;
204 initial_tab_ = static_cast<TouchTab*>(GetTabAtLocal(point));
205 }
206
207 void TouchTabStrip::ContinueScroll(const gfx::Point& point) {
208 int delta_x = point.x() - initial_mouse_x_;
209 if (std::abs(delta_x) > kScrollThreshold)
210 scrolling_ = true;
211 if (scrolling_)
212 ScrollTo(delta_x);
213 // and layout
sky 2011/04/06 15:11:50 This comment doesn't make sense.
wyck 2011/04/06 20:14:24 Right, sorry. That was a note to myself to move t
214 }
215
216 void TouchTabStrip::EndScroll(const gfx::Point& point) {
217 int delta_x = point.x() - initial_mouse_x_;
218 if (scrolling_) {
219 scrolling_ = false;
220 ScrollTo(delta_x);
221 StopAnimating(false);
222 GenerateIdealBounds();
223 AnimateToIdealBounds();
224 } else {
225 TouchTab* tab = static_cast<TouchTab*>(GetTabAtLocal(point));
226 if (tab && tab == initial_tab_)
sky 2011/04/06 15:11:50 Don't you always want to select the tab at the loc
wyck 2011/04/06 20:14:24 No, I was thinking it works like a button, where i
227 SelectTab(tab);
228 DoLayout();
229 }
230 initial_tab_ = NULL;
231 }
232
233 void TouchTabStrip::ScrollTo(int delta_x) {
234 scroll_offset_ = initial_scroll_offset_ + delta_x;
235 // Limit the scrolling here.
236 // When scrolling beyond the limits of min and max offsets, the displacement
237 // is adjusted to 25% of what would normally applied (divided by 4).
238 // Perhaps in the future, Hooke's law could be used to model more physically
239 // based spring-like behavior.
240 int max_scroll_offset = 0; // Because there's never content to the left of 0.
241 if (scroll_offset_ > max_scroll_offset) {
242 if (scrolling_) {
243 scroll_offset_ = max_scroll_offset
244 + std::min((scroll_offset_ - max_scroll_offset) / 4,
245 kTouchTabWidth);
246 } else {
247 scroll_offset_ = max_scroll_offset;
248 }
249 }
250 if (scroll_offset_ < min_scroll_offset_) {
251 if (scrolling_) {
252 scroll_offset_ = min_scroll_offset_
253 + std::max((scroll_offset_ - min_scroll_offset_) / 4,
254 -kTouchTabWidth);
255 } else {
256 scroll_offset_ = min_scroll_offset_;
257 }
258 }
259 }
260
153 TouchTab* TouchTabStrip::GetTabAtTabDataIndex(int tab_data_index) const { 261 TouchTab* TouchTabStrip::GetTabAtTabDataIndex(int tab_data_index) const {
154 return static_cast<TouchTab*>(base_tab_at_tab_index(tab_data_index)); 262 return static_cast<TouchTab*>(base_tab_at_tab_index(tab_data_index));
155 } 263 }
156 264
157 //////////////////////////////////////////////////////////////////////////////// 265 ////////////////////////////////////////////////////////////////////////////////
158 // TouchTabStrip, private: 266 // TouchTabStrip, private:
159 267
160 void TouchTabStrip::Init() { 268 void TouchTabStrip::Init() {
161 SetID(VIEW_ID_TAB_STRIP); 269 SetID(VIEW_ID_TAB_STRIP);
162 } 270 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 last_tapped_view_ = view; 344 last_tapped_view_ = view;
237 return TOUCH_STATUS_UNKNOWN; 345 return TOUCH_STATUS_UNKNOWN;
238 } 346 }
239 347
240 void TouchTabStrip::ViewHierarchyChanged(bool is_add, 348 void TouchTabStrip::ViewHierarchyChanged(bool is_add,
241 View* parent, 349 View* parent,
242 View* child) { 350 View* child) {
243 if (!is_add && last_tapped_view_ == child) 351 if (!is_add && last_tapped_view_ == child)
244 last_tapped_view_ = NULL; 352 last_tapped_view_ = NULL;
245 } 353 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698