 Chromium Code Reviews
 Chromium Code Reviews| OLD | NEW | 
|---|---|
| 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> | |
| 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 Loading... | |
| 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 bool TouchTabStrip::OnMousePressed(const views::MouseEvent& event) { | |
| 
rjkroege
2011/03/28 22:07:40
these need unit tests.
 
wyck
2011/03/30 15:53:11
Unit tests are 100% completely new territory for m
 
wyck
2011/04/06 14:51:09
Is this what's holding up this CL?
 | |
| 170 // When we press the mouse button, we begin a drag | |
| 171 BeginScroll(event.location()); | |
| 
rjkroege
2011/03/28 22:07:40
I thought we had discussed creating synthetic even
 
wyck
2011/03/30 15:53:11
We did.  I have added a TODO comment.
 | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 bool TouchTabStrip::OnMouseDragged(const views::MouseEvent& event) { | |
| 176 ContinueScroll(event.location()); | |
| 177 DoLayout(); | |
| 178 SchedulePaint(); | |
| 179 return true; | |
| 180 } | |
| 181 | |
| 182 void TouchTabStrip::OnMouseReleased(const views::MouseEvent& event, | |
| 183 bool canceled) { | |
| 184 EndScroll(event.location()); | |
| 185 SchedulePaint(); | |
| 186 } | |
| 187 | |
| 188 void TouchTabStrip::BeginScroll(const gfx::Point& point ) { | |
| 189 initial_mouse_x_ = point.x(); | |
| 190 initial_scroll_offset_ = scroll_offset_; | |
| 191 initial_tab_ = static_cast<TouchTab*>(GetTabAtLocal(point)); | |
| 192 } | |
| 193 | |
| 194 void TouchTabStrip::ContinueScroll(const gfx::Point& point) { | |
| 195 int delta_x = point.x() - initial_mouse_x_; | |
| 196 if (std::abs(delta_x) > kScrollThreshold) | |
| 197 scrolling_ = true; | |
| 198 if (scrolling_) | |
| 199 ScrollTo(delta_x); | |
| 200 // and layout | |
| 201 } | |
| 202 | |
| 203 void TouchTabStrip::EndScroll(const gfx::Point& point) { | |
| 204 int delta_x = point.x() - initial_mouse_x_; | |
| 205 if (scrolling_) { | |
| 206 scrolling_ = false; | |
| 207 ScrollTo(delta_x); | |
| 208 StopAnimating(false); | |
| 209 GenerateIdealBounds(); | |
| 210 AnimateToIdealBounds(); | |
| 211 } else { | |
| 212 TouchTab* tab = static_cast<TouchTab*>(GetTabAtLocal(point)); | |
| 213 if (tab && tab == initial_tab_) | |
| 214 SelectTab(tab); | |
| 215 DoLayout(); | |
| 216 } | |
| 217 initial_tab_ = NULL; | |
| 218 } | |
| 219 | |
| 220 void TouchTabStrip::ScrollTo(int delta_x) { | |
| 
rjkroege
2011/03/28 22:07:40
I would have thought that there should be a schedu
 
wyck
2011/03/30 15:53:11
This function is just doing the math for setting t
 | |
| 221 scroll_offset_ = initial_scroll_offset_ + delta_x; | |
| 222 // Limit the scrolling here. | |
| 223 // When scrolling beyond the limits of min and max offsets, the displacement | |
| 224 // is adjusted to 25% of what would normally applied (divided by 4). | |
| 225 // Perhaps in the future, Hooke's law could be used to model more physically | |
| 226 // based spring-like behavior. | |
| 227 int max_scroll_offset = 0; // Because there's never content to the left of 0. | |
| 228 if (scroll_offset_ > max_scroll_offset) { | |
| 229 if (scrolling_) { | |
| 230 scroll_offset_ = max_scroll_offset | |
| 231 + std::min((scroll_offset_ - max_scroll_offset) / 4, | |
| 232 kTouchTabWidth); | |
| 233 } else { | |
| 234 scroll_offset_ = max_scroll_offset; | |
| 235 } | |
| 236 } | |
| 237 if (scroll_offset_ < min_scroll_offset_) { | |
| 238 if (scrolling_) { | |
| 239 scroll_offset_ = min_scroll_offset_ | |
| 240 + std::max((scroll_offset_ - min_scroll_offset_) / 4, | |
| 241 -kTouchTabWidth); | |
| 242 } else { | |
| 243 scroll_offset_ = min_scroll_offset_; | |
| 244 } | |
| 245 } | |
| 246 } | |
| 247 | |
| 153 TouchTab* TouchTabStrip::GetTabAtTabDataIndex(int tab_data_index) const { | 248 TouchTab* TouchTabStrip::GetTabAtTabDataIndex(int tab_data_index) const { | 
| 154 return static_cast<TouchTab*>(base_tab_at_tab_index(tab_data_index)); | 249 return static_cast<TouchTab*>(base_tab_at_tab_index(tab_data_index)); | 
| 155 } | 250 } | 
| 156 | 251 | 
| 157 //////////////////////////////////////////////////////////////////////////////// | 252 //////////////////////////////////////////////////////////////////////////////// | 
| 158 // TouchTabStrip, private: | 253 // TouchTabStrip, private: | 
| 159 | 254 | 
| 160 void TouchTabStrip::Init() { | 255 void TouchTabStrip::Init() { | 
| 161 SetID(VIEW_ID_TAB_STRIP); | 256 SetID(VIEW_ID_TAB_STRIP); | 
| 162 } | 257 } | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 last_tapped_view_ = view; | 331 last_tapped_view_ = view; | 
| 237 return TOUCH_STATUS_UNKNOWN; | 332 return TOUCH_STATUS_UNKNOWN; | 
| 238 } | 333 } | 
| 239 | 334 | 
| 240 void TouchTabStrip::ViewHierarchyChanged(bool is_add, | 335 void TouchTabStrip::ViewHierarchyChanged(bool is_add, | 
| 241 View* parent, | 336 View* parent, | 
| 242 View* child) { | 337 View* child) { | 
| 243 if (!is_add && last_tapped_view_ == child) | 338 if (!is_add && last_tapped_view_ == child) | 
| 244 last_tapped_view_ = NULL; | 339 last_tapped_view_ = NULL; | 
| 245 } | 340 } | 
| OLD | NEW |