Chromium Code Reviews| 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/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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |