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

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

Issue 22891016: Add support for rect-based event targeting in views (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tab strip problems addressed Created 7 years, 2 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) 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.h" 5 #include "chrome/browser/ui/views/tabs/tab.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
(...skipping 21 matching lines...) Expand all
32 #include "ui/base/theme_provider.h" 32 #include "ui/base/theme_provider.h"
33 #include "ui/gfx/animation/animation_container.h" 33 #include "ui/gfx/animation/animation_container.h"
34 #include "ui/gfx/animation/multi_animation.h" 34 #include "ui/gfx/animation/multi_animation.h"
35 #include "ui/gfx/animation/throb_animation.h" 35 #include "ui/gfx/animation/throb_animation.h"
36 #include "ui/gfx/canvas.h" 36 #include "ui/gfx/canvas.h"
37 #include "ui/gfx/color_analysis.h" 37 #include "ui/gfx/color_analysis.h"
38 #include "ui/gfx/favicon_size.h" 38 #include "ui/gfx/favicon_size.h"
39 #include "ui/gfx/font.h" 39 #include "ui/gfx/font.h"
40 #include "ui/gfx/image/image_skia_operations.h" 40 #include "ui/gfx/image/image_skia_operations.h"
41 #include "ui/gfx/path.h" 41 #include "ui/gfx/path.h"
42 #include "ui/gfx/rect_conversions.h"
43 #include "ui/gfx/skia_util.h"
42 #include "ui/gfx/text_elider.h" 44 #include "ui/gfx/text_elider.h"
43 #include "ui/views/controls/button/image_button.h" 45 #include "ui/views/controls/button/image_button.h"
44 #include "ui/views/widget/tooltip_manager.h" 46 #include "ui/views/widget/tooltip_manager.h"
45 #include "ui/views/widget/widget.h" 47 #include "ui/views/widget/widget.h"
46 #include "ui/views/window/non_client_view.h" 48 #include "ui/views/window/non_client_view.h"
47 49
48 #if defined(OS_WIN) 50 #if defined(OS_WIN)
49 #include "win8/util/win8_util.h" 51 #include "win8/util/win8_util.h"
50 #endif 52 #endif
51 53
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 243
242 // Number of steps in the immersive mode loading animation. 244 // Number of steps in the immersive mode loading animation.
243 const int kImmersiveLoadingStepCount = 32; 245 const int kImmersiveLoadingStepCount = 32;
244 246
245 // Scale to resize the current favicon by when projecting. 247 // Scale to resize the current favicon by when projecting.
246 const double kProjectingFaviconResizeScale = 0.75; 248 const double kProjectingFaviconResizeScale = 0.75;
247 249
248 // Scale to resize the projection sheet glow by. 250 // Scale to resize the projection sheet glow by.
249 const double kProjectingGlowResizeScale = 2.0; 251 const double kProjectingGlowResizeScale = 2.0;
250 252
253 const char kTabCloseButtonName[] = "TabCloseButton";
254
251 void DrawIconAtLocation(gfx::Canvas* canvas, 255 void DrawIconAtLocation(gfx::Canvas* canvas,
252 const gfx::ImageSkia& image, 256 const gfx::ImageSkia& image,
253 int image_offset, 257 int image_offset,
254 int dst_x, 258 int dst_x,
255 int dst_y, 259 int dst_y,
256 int icon_width, 260 int icon_width,
257 int icon_height, 261 int icon_height,
258 bool filter, 262 bool filter,
259 const SkPaint& paint) { 263 const SkPaint& paint) {
260 // NOTE: the clipping is a work around for 69528, it shouldn't be necessary. 264 // NOTE: the clipping is a work around for 69528, it shouldn't be necessary.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 // TabCloseButton 354 // TabCloseButton
351 // 355 //
352 // This is a Button subclass that causes middle clicks to be forwarded to the 356 // This is a Button subclass that causes middle clicks to be forwarded to the
353 // parent View by explicitly not handling them in OnMousePressed. 357 // parent View by explicitly not handling them in OnMousePressed.
354 class Tab::TabCloseButton : public views::ImageButton { 358 class Tab::TabCloseButton : public views::ImageButton {
355 public: 359 public:
356 explicit TabCloseButton(Tab* tab) : views::ImageButton(tab), tab_(tab) {} 360 explicit TabCloseButton(Tab* tab) : views::ImageButton(tab), tab_(tab) {}
357 virtual ~TabCloseButton() {} 361 virtual ~TabCloseButton() {}
358 362
359 // Overridden from views::View. 363 // Overridden from views::View.
360 virtual View* GetEventHandlerForPoint(const gfx::Point& point) OVERRIDE { 364 virtual View* GetEventHandlerForRect(const gfx::Rect& rect) OVERRIDE {
365 if (!View::UsePointBasedTargeting(rect))
366 return View::GetEventHandlerForRect(rect);
367
361 // Ignore the padding set on the button. 368 // Ignore the padding set on the button.
362 gfx::Rect rect = GetContentsBounds(); 369 gfx::Rect contents_bounds = GetContentsBounds();
363 rect.set_x(GetMirroredXForRect(rect)); 370 contents_bounds.set_x(GetMirroredXForRect(contents_bounds));
364 371
365 #if defined(USE_ASH) 372 #if defined(USE_ASH)
366 // Include the padding in hit-test for touch events. 373 // Include the padding in hit-test for touch events.
367 if (aura::Env::GetInstance()->is_touch_down()) 374 if (aura::Env::GetInstance()->is_touch_down())
368 rect = GetLocalBounds(); 375 contents_bounds = GetLocalBounds();
369 #elif defined(OS_WIN) 376 #elif defined(OS_WIN)
370 // TODO(sky): Use local-bounds if a touch-point is active. 377 // TODO(sky): Use local-bounds if a touch-point is active.
371 // http://crbug.com/145258 378 // http://crbug.com/145258
372 #endif 379 #endif
373 380
374 return rect.Contains(point) ? this : parent(); 381 return contents_bounds.Intersects(rect) ? this : parent();
375 } 382 }
376 383
377 // Overridden from views::View. 384 // Overridden from views::View.
378 virtual View* GetTooltipHandlerForPoint(const gfx::Point& point) OVERRIDE { 385 virtual View* GetTooltipHandlerForPoint(const gfx::Point& point) OVERRIDE {
379 // Tab close button has no children, so tooltip handler should be the same 386 // Tab close button has no children, so tooltip handler should be the same
380 // as the event handler. 387 // as the event handler.
381 // In addition, a hit test has to be performed for the point (as 388 // In addition, a hit test has to be performed for the point (as
382 // GetTooltipHandlerForPoint() is responsible for it). 389 // GetTooltipHandlerForPoint() is responsible for it).
383 if (!HitTestPoint(point)) 390 if (!HitTestPoint(point))
384 return NULL; 391 return NULL;
(...skipping 22 matching lines...) Expand all
407 CustomButton::OnMouseReleased(event); 414 CustomButton::OnMouseReleased(event);
408 } 415 }
409 416
410 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 417 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
411 // Consume all gesture events here so that the parent (Tab) does not 418 // Consume all gesture events here so that the parent (Tab) does not
412 // start consuming gestures. 419 // start consuming gestures.
413 ImageButton::OnGestureEvent(event); 420 ImageButton::OnGestureEvent(event);
414 event->SetHandled(); 421 event->SetHandled();
415 } 422 }
416 423
424 virtual bool HasHitTestMask() const OVERRIDE {
425 return true;
426 }
427
428 virtual void GetHitTestMask(gfx::Path* path) const OVERRIDE {
429 // Use the button's contents bounds (which does not include padding)
430 // and the hit test mask of our parent |tab_| to determine if the
431 // button is completely hidden behind another tab.
432 gfx::Path tab_mask;
433 tab_->GetHitTestMask(&tab_mask);
434
435 gfx::Rect button_bounds(GetContentsBounds());
436 gfx::Rect tab_bounds(
437 gfx::ToEnclosingRect(gfx::SkRectToRectF(tab_mask.getBounds())));
438 views::View::ConvertRectToTarget(tab_, this, &tab_bounds);
439
440 // If the button is completely hidden behind another tab, the hit test
441 // mask is empty. Otherwise set the hit test mask to be the contents bounds.
442 path->reset();
443 if (tab_bounds.Contains(button_bounds)) {
444 #if defined(USE_ASH)
tdanderson 2013/10/03 23:17:42 If this code stays, I think the #if defined(USE_AS
sky 2013/10/04 17:05:14 I don't like this ifdef. It implies the API should
tdanderson 2013/10/07 21:35:21 I'm also not a fan of having this ifdef where it i
sky 2013/10/08 15:39:07 My point is that if a view needs to know if touch
445 // Include the padding in the hit test mask for touch events.
446 if (aura::Env::GetInstance()->is_touch_down())
447 button_bounds = GetLocalBounds();
448 #endif
449 path->addRect(RectToSkRect(button_bounds));
450 }
451 }
452
453 virtual const char* GetClassName() const OVERRIDE {
454 return kTabCloseButtonName;
455 }
456
417 private: 457 private:
418 Tab* tab_; 458 Tab* tab_;
419 459
420 DISALLOW_COPY_AND_ASSIGN(TabCloseButton); 460 DISALLOW_COPY_AND_ASSIGN(TabCloseButton);
421 }; 461 };
422 462
423 //////////////////////////////////////////////////////////////////////////////// 463 ////////////////////////////////////////////////////////////////////////////////
424 // ImageCacheEntry 464 // ImageCacheEntry
425 465
426 Tab::ImageCacheEntry::ImageCacheEntry() 466 Tab::ImageCacheEntry::ImageCacheEntry()
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 } 915 }
876 916
877 void Tab::GetHitTestMask(gfx::Path* path) const { 917 void Tab::GetHitTestMask(gfx::Path* path) const {
878 // When the window is maximized we don't want to shave off the edges or top 918 // When the window is maximized we don't want to shave off the edges or top
879 // shadow of the tab, such that the user can click anywhere along the top 919 // shadow of the tab, such that the user can click anywhere along the top
880 // edge of the screen to select a tab. Ditto for immersive fullscreen. 920 // edge of the screen to select a tab. Ditto for immersive fullscreen.
881 const views::Widget* widget = GetWidget(); 921 const views::Widget* widget = GetWidget();
882 bool include_top_shadow = 922 bool include_top_shadow =
883 widget && (widget->IsMaximized() || widget->IsFullscreen()); 923 widget && (widget->IsMaximized() || widget->IsFullscreen());
884 TabResources::GetHitTestMask(width(), height(), include_top_shadow, path); 924 TabResources::GetHitTestMask(width(), height(), include_top_shadow, path);
925
926 // It is possible for a portion of the tab to be occluded if tabs are
927 // stacked, so modify the hit test mask to only include the visible
928 // region of the tab.
929 if (controller()) {
930 gfx::Rect clip;
931 controller()->ShouldPaintTab(this, &clip);
932 if (clip.size().GetArea()) {
933 SkRect intersection(path->getBounds());
934 intersection.intersect(RectToSkRect(clip));
935 path->reset();
936 path->addRect(intersection);
937 }
938 }
885 } 939 }
886 940
887 bool Tab::GetTooltipText(const gfx::Point& p, string16* tooltip) const { 941 bool Tab::GetTooltipText(const gfx::Point& p, string16* tooltip) const {
888 if (data_.title.empty()) 942 if (data_.title.empty())
889 return false; 943 return false;
890 944
891 // Only show the tooltip if the title is truncated. 945 // Only show the tooltip if the title is truncated.
892 if (font_->GetStringWidth(data_.title) > GetTitleBounds().width()) { 946 if (font_->GetStringWidth(data_.title) > GetTitleBounds().width()) {
893 *tooltip = data_.title; 947 *tooltip = data_.title;
894 return true; 948 return true;
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 const gfx::ImageSkia& image) { 1928 const gfx::ImageSkia& image) {
1875 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); 1929 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE);
1876 ImageCacheEntry entry; 1930 ImageCacheEntry entry;
1877 entry.resource_id = resource_id; 1931 entry.resource_id = resource_id;
1878 entry.scale_factor = scale_factor; 1932 entry.scale_factor = scale_factor;
1879 entry.image = image; 1933 entry.image = image;
1880 image_cache_->push_front(entry); 1934 image_cache_->push_front(entry);
1881 if (image_cache_->size() > kMaxImageCacheSize) 1935 if (image_cache_->size() > kMaxImageCacheSize)
1882 image_cache_->pop_back(); 1936 image_cache_->pop_back();
1883 } 1937 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698