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

Side by Side Diff: chrome/browser/ui/views/tabs/tab_strip_unittest.cc

Issue 32463003: Modify hit test masks for tabs and tab close buttons (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch for landing Created 7 years, 1 month 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
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_strip.cc ('k') | ui/views/view.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/tabs/tab_strip.h" 5 #include "chrome/browser/ui/views/tabs/tab_strip.h"
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h" 8 #include "chrome/browser/ui/views/tabs/fake_base_tab_strip_controller.h"
9 #include "chrome/browser/ui/views/tabs/tab.h"
9 #include "chrome/browser/ui/views/tabs/tab_strip.h" 10 #include "chrome/browser/ui/views/tabs/tab_strip.h"
10 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" 11 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
11 #include "chrome/browser/ui/views/tabs/tab_strip_observer.h" 12 #include "chrome/browser/ui/views/tabs/tab_strip_observer.h"
12 #include "chrome/test/base/testing_profile.h" 13 #include "chrome/test/base/testing_profile.h"
13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/gfx/path.h"
16 #include "ui/gfx/rect_conversions.h"
17 #include "ui/gfx/skia_util.h"
18 #include "ui/views/view.h"
14 19
15 namespace { 20 namespace {
16 21
17 // Walks up the views hierarchy until it finds a tab view. It returns the 22 // Walks up the views hierarchy until it finds a tab view. It returns the
18 // found tab view, on NULL if none is found. 23 // found tab view, on NULL if none is found.
19 views::View* FindTabView(views::View* view) { 24 views::View* FindTabView(views::View* view) {
20 views::View* current = view; 25 views::View* current = view;
21 while (current && strcmp(current->GetClassName(), Tab::kViewClassName)) { 26 while (current && strcmp(current->GetClassName(), Tab::kViewClassName)) {
22 current = current->parent(); 27 current = current->parent();
23 } 28 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 public: 90 public:
86 TabStripTest() 91 TabStripTest()
87 : controller_(new FakeBaseTabStripController) { 92 : controller_(new FakeBaseTabStripController) {
88 tab_strip_ = new TabStrip(controller_); 93 tab_strip_ = new TabStrip(controller_);
89 controller_->set_tab_strip(tab_strip_); 94 controller_->set_tab_strip(tab_strip_);
90 // Do this to force TabStrip to create the buttons. 95 // Do this to force TabStrip to create the buttons.
91 parent_.AddChildView(tab_strip_); 96 parent_.AddChildView(tab_strip_);
92 } 97 }
93 98
94 protected: 99 protected:
100 // Returns the rectangular hit test region of |tab| in |tab|'s local
101 // coordinate space.
102 gfx::Rect GetTabHitTestMask(Tab* tab) {
103 gfx::Path mask;
104 tab->GetHitTestMask(views::View::HIT_TEST_SOURCE_TOUCH, &mask);
105 return gfx::ToEnclosingRect((gfx::SkRectToRectF(mask.getBounds())));
106 }
107
108 // Returns the rectangular hit test region of the tab close button of
109 // |tab| in |tab|'s coordinate space (including padding if |padding|
110 // is true).
111 gfx::Rect GetTabCloseHitTestMask(Tab* tab, bool padding) {
112 gfx::RectF bounds_f = tab->close_button_->GetContentsBounds();
113 if (padding)
114 bounds_f = tab->close_button_->GetLocalBounds();
115 views::View::ConvertRectToTarget(tab->close_button_, tab, &bounds_f);
116 return gfx::ToEnclosingRect(bounds_f);
117 }
118
95 // Checks whether |tab| contains |point_in_tabstrip_coords|, where the point 119 // Checks whether |tab| contains |point_in_tabstrip_coords|, where the point
96 // is in |tab_strip_| coordinates. 120 // is in |tab_strip_| coordinates.
97 bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords) { 121 bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords) {
98 gfx::Point point_in_tab_coords(point_in_tabstrip_coords); 122 gfx::Point point_in_tab_coords(point_in_tabstrip_coords);
99 views::View::ConvertPointToTarget(tab_strip_, tab, &point_in_tab_coords); 123 views::View::ConvertPointToTarget(tab_strip_, tab, &point_in_tab_coords);
100 return tab->HitTestPoint(point_in_tab_coords); 124 return tab->HitTestPoint(point_in_tab_coords);
101 } 125 }
102 126
103 base::MessageLoopForUI ui_loop_; 127 base::MessageLoopForUI ui_loop_;
104 // Owned by TabStrip. 128 // Owned by TabStrip.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 EXPECT_TRUE(tab_strip_->IsImmersiveStyle()); 223 EXPECT_TRUE(tab_strip_->IsImmersiveStyle());
200 224
201 // Now tabs have the immersive height. 225 // Now tabs have the immersive height.
202 int immersive_height = Tab::GetImmersiveHeight(); 226 int immersive_height = Tab::GetImmersiveHeight();
203 EXPECT_EQ(immersive_height, tab_strip_->GetPreferredSize().height()); 227 EXPECT_EQ(immersive_height, tab_strip_->GetPreferredSize().height());
204 228
205 // Sanity-check immersive tabs are shorter than normal tabs. 229 // Sanity-check immersive tabs are shorter than normal tabs.
206 EXPECT_LT(immersive_height, normal_height); 230 EXPECT_LT(immersive_height, normal_height);
207 } 231 }
208 232
233 // Creates a tab strip in stacked layout mode and verifies the correctness
234 // of hit tests against the visible/occluded regions of a tab and
235 // visible/occluded tab close buttons.
236 TEST_F(TabStripTest, TabHitTestMaskWhenStacked) {
237 tab_strip_->SetBounds(0, 0, 300, 20);
238
239 controller_->AddTab(0, false);
240 controller_->AddTab(1, true);
241 controller_->AddTab(2, false);
242 controller_->AddTab(3, false);
243 ASSERT_EQ(4, tab_strip_->tab_count());
244
245 Tab* left_tab = tab_strip_->tab_at(0);
246 left_tab->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), gfx::Size(200, 20)));
247
248 Tab* active_tab = tab_strip_->tab_at(1);
249 active_tab->SetBoundsRect(gfx::Rect(gfx::Point(150, 0), gfx::Size(200, 20)));
250 ASSERT_TRUE(active_tab->IsActive());
251
252 Tab* right_tab = tab_strip_->tab_at(2);
253 right_tab->SetBoundsRect(gfx::Rect(gfx::Point(300, 0), gfx::Size(200, 20)));
254
255 Tab* most_right_tab = tab_strip_->tab_at(3);
256 most_right_tab->SetBoundsRect(gfx::Rect(gfx::Point(450, 0),
257 gfx::Size(200, 20)));
258
259 // Switch to stacked layout mode and force a layout to ensure tabs stack.
260 tab_strip_->SetLayoutType(TAB_STRIP_LAYOUT_STACKED, false);
261 tab_strip_->DoLayout();
262
263
264 // Tests involving |left_tab|, which has part of its bounds and its tab
265 // close button occluded by |active_tab|.
266
267 // Bounds of the tab's hit test mask.
268 gfx::Rect tab_bounds = GetTabHitTestMask(left_tab);
269 EXPECT_EQ(gfx::Rect(6, 2, 61, 27).ToString(), tab_bounds.ToString());
270
271 // Bounds of the tab close button (without padding) in the tab's
272 // coordinate space.
273 gfx::Rect contents_bounds = GetTabCloseHitTestMask(left_tab, false);
274 // TODO(tdanderson): Uncomment this line once crbug.com/311609 is resolved.
275 //EXPECT_EQ(gfx::Rect(84, 8, 18, 18).ToString(), contents_bounds.ToString());
276
277 // Verify that the tab close button is occluded.
278 EXPECT_FALSE(tab_bounds.Contains(contents_bounds));
279
280 // Hit tests in the non-occuluded region of the tab.
281 EXPECT_TRUE(left_tab->HitTestRect(gfx::Rect(6, 2, 2, 2)));
282 EXPECT_TRUE(left_tab->HitTestRect(gfx::Rect(6, 2, 1, 1)));
283 EXPECT_TRUE(left_tab->HitTestRect(gfx::Rect(30, 15, 1, 1)));
284 EXPECT_TRUE(left_tab->HitTestRect(gfx::Rect(30, 15, 25, 35)));
285 EXPECT_TRUE(left_tab->HitTestRect(gfx::Rect(-10, -5, 20, 30)));
286
287 // Hit tests in the occluded region of the tab.
288 EXPECT_FALSE(left_tab->HitTestRect(gfx::Rect(70, 15, 2, 2)));
289 EXPECT_FALSE(left_tab->HitTestRect(gfx::Rect(70, -15, 30, 40)));
290 EXPECT_FALSE(left_tab->HitTestRect(gfx::Rect(87, 20, 5, 3)));
291
292 // Hit tests completely outside of the tab.
293 EXPECT_FALSE(left_tab->HitTestRect(gfx::Rect(-20, -25, 1, 1)));
294 EXPECT_FALSE(left_tab->HitTestRect(gfx::Rect(-20, -25, 3, 19)));
295
296 // All hit tests against the tab close button should fail because
297 // it is occluded by |active_tab|.
298 views::ImageButton* left_close = left_tab->close_button_;
299 EXPECT_FALSE(left_close->HitTestRect(gfx::Rect(1, 1, 1, 1)));
300 EXPECT_FALSE(left_close->HitTestRect(gfx::Rect(1, 1, 5, 10)));
301 EXPECT_FALSE(left_close->HitTestRect(gfx::Rect(10, 10, 1, 1)));
302 EXPECT_FALSE(left_close->HitTestRect(gfx::Rect(10, 10, 3, 4)));
303
304
305 // Tests involving |active_tab|, which is completely visible.
306
307 tab_bounds = GetTabHitTestMask(active_tab);
308 EXPECT_EQ(gfx::Rect(6, 2, 108, 27).ToString(), tab_bounds.ToString());
309 contents_bounds = GetTabCloseHitTestMask(active_tab, false);
310 // TODO(tdanderson): Uncomment this line once crbug.com/311609 is resolved.
311 //EXPECT_EQ(gfx::Rect(84, 8, 18, 18).ToString(), contents_bounds.ToString());
312
313 // Verify that the tab close button is not occluded.
314 EXPECT_TRUE(tab_bounds.Contains(contents_bounds));
315
316 // Bounds of the tab close button (without padding) in the tab's
317 // coordinate space.
318 gfx::Rect local_bounds = GetTabCloseHitTestMask(active_tab, true);
319 EXPECT_EQ(gfx::Rect(81, 0, 39, 29).ToString(), local_bounds.ToString());
320
321 // Hit tests within the tab.
322 EXPECT_TRUE(active_tab->HitTestRect(gfx::Rect(30, 15, 1, 1)));
323 EXPECT_TRUE(active_tab->HitTestRect(gfx::Rect(30, 15, 2, 2)));
324
325 // Hit tests against the tab close button. Note that if the hit test
326 // source is a mouse, a hit test within the button's padding should fail.
327 views::ImageButton* active_close = active_tab->close_button_;
328 EXPECT_FALSE(active_close->HitTestRect(gfx::Rect(1, 1, 1, 1)));
329 EXPECT_TRUE(active_close->HitTestRect(gfx::Rect(1, 1, 2, 2)));
330 EXPECT_TRUE(active_close->HitTestRect(gfx::Rect(10, 10, 1, 1)));
331 EXPECT_TRUE(active_close->HitTestRect(gfx::Rect(10, 10, 25, 35)));
332
333
334 // Tests involving |most_right_tab|, which has part of its bounds occluded
335 // by |right_tab| but has its tab close button completely visible.
336
337 tab_bounds = GetTabHitTestMask(most_right_tab);
338 EXPECT_EQ(gfx::Rect(84, 2, 30, 27).ToString(), tab_bounds.ToString());
339 contents_bounds = GetTabCloseHitTestMask(active_tab, false);
340 // TODO(tdanderson): Uncomment this line once crbug.com/311609 is resolved.
341 //EXPECT_EQ(gfx::Rect(84, 8, 18, 18).ToString(), contents_bounds.ToString());
342 local_bounds = GetTabCloseHitTestMask(active_tab, true);
343 EXPECT_EQ(gfx::Rect(81, 0, 39, 29).ToString(), local_bounds.ToString());
344
345 // Verify that the tab close button is not occluded.
346 EXPECT_TRUE(tab_bounds.Contains(contents_bounds));
347
348 // Hit tests in the occluded region of the tab.
349 EXPECT_FALSE(most_right_tab->HitTestRect(gfx::Rect(20, 15, 1, 1)));
350 EXPECT_FALSE(most_right_tab->HitTestRect(gfx::Rect(20, 15, 5, 6)));
351
352 // Hit tests in the non-occluded region of the tab.
353 EXPECT_TRUE(most_right_tab->HitTestRect(gfx::Rect(85, 15, 1, 1)));
354 EXPECT_TRUE(most_right_tab->HitTestRect(gfx::Rect(85, 15, 2, 2)));
355
356 // Hit tests against the tab close button. Note that if the hit test
357 // source is a mouse, a hit test within the button's padding should fail.
358 views::ImageButton* most_right_close = most_right_tab->close_button_;
359 EXPECT_FALSE(most_right_close->HitTestRect(gfx::Rect(1, 1, 1, 1)));
360 EXPECT_TRUE(most_right_close->HitTestRect(gfx::Rect(1, 1, 2, 2)));
361 EXPECT_TRUE(most_right_close->HitTestRect(gfx::Rect(10, 10, 1, 1)));
362 EXPECT_TRUE(most_right_close->HitTestRect(gfx::Rect(10, 10, 25, 35)));
363 EXPECT_TRUE(most_right_close->HitTestRect(gfx::Rect(-10, 10, 25, 35)));
364 }
365
209 TEST_F(TabStripTest, GetEventHandlerForOverlappingArea) { 366 TEST_F(TabStripTest, GetEventHandlerForOverlappingArea) {
210 tab_strip_->SetBounds(0, 0, 1000, 20); 367 tab_strip_->SetBounds(0, 0, 1000, 20);
211 368
212 controller_->AddTab(0, false); 369 controller_->AddTab(0, false);
213 controller_->AddTab(1, true); 370 controller_->AddTab(1, true);
214 controller_->AddTab(2, false); 371 controller_->AddTab(2, false);
215 controller_->AddTab(3, false); 372 controller_->AddTab(3, false);
216 ASSERT_EQ(4, tab_strip_->tab_count()); 373 ASSERT_EQ(4, tab_strip_->tab_count());
217 374
218 // Verify that the active tab will be a tooltip handler for points that hit 375 // Verify that the active tab will be a tooltip handler for points that hit
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 ASSERT_TRUE(IsPointInTab(most_right_tab, unactive_overlap)); 486 ASSERT_TRUE(IsPointInTab(most_right_tab, unactive_overlap));
330 487
331 EXPECT_EQ( 488 EXPECT_EQ(
332 right_tab, 489 right_tab,
333 FindTabView(tab_strip_->GetTooltipHandlerForPoint(unactive_overlap))); 490 FindTabView(tab_strip_->GetTooltipHandlerForPoint(unactive_overlap)));
334 491
335 // Confirm that tab strip doe not return tooltip handler for points that 492 // Confirm that tab strip doe not return tooltip handler for points that
336 // don't hit it. 493 // don't hit it.
337 EXPECT_FALSE(tab_strip_->GetTooltipHandlerForPoint(gfx::Point(-1, 2))); 494 EXPECT_FALSE(tab_strip_->GetTooltipHandlerForPoint(gfx::Point(-1, 2)));
338 } 495 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab_strip.cc ('k') | ui/views/view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698