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

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

Issue 2368653002: Remove pre-MD code from browser/ui/views/tabs/tab.cc (Closed)
Patch Set: fix compile Created 4 years, 3 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
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 <stddef.h> 7 #include <stddef.h>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 16 matching lines...) Expand all
27 #include "chrome/grit/generated_resources.h" 27 #include "chrome/grit/generated_resources.h"
28 #include "chrome/grit/theme_resources.h" 28 #include "chrome/grit/theme_resources.h"
29 #include "components/grit/components_scaled_resources.h" 29 #include "components/grit/components_scaled_resources.h"
30 #include "components/strings/grit/components_strings.h" 30 #include "components/strings/grit/components_strings.h"
31 #include "content/public/browser/user_metrics.h" 31 #include "content/public/browser/user_metrics.h"
32 #include "content/public/common/url_constants.h" 32 #include "content/public/common/url_constants.h"
33 #include "third_party/skia/include/effects/SkGradientShader.h" 33 #include "third_party/skia/include/effects/SkGradientShader.h"
34 #include "third_party/skia/include/pathops/SkPathOps.h" 34 #include "third_party/skia/include/pathops/SkPathOps.h"
35 #include "ui/accessibility/ax_view_state.h" 35 #include "ui/accessibility/ax_view_state.h"
36 #include "ui/base/l10n/l10n_util.h" 36 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/base/material_design/material_design_controller.h"
38 #include "ui/base/models/list_selection_model.h" 37 #include "ui/base/models/list_selection_model.h"
39 #include "ui/base/resource/resource_bundle.h" 38 #include "ui/base/resource/resource_bundle.h"
40 #include "ui/base/theme_provider.h" 39 #include "ui/base/theme_provider.h"
41 #include "ui/gfx/animation/animation_container.h" 40 #include "ui/gfx/animation/animation_container.h"
42 #include "ui/gfx/animation/throb_animation.h" 41 #include "ui/gfx/animation/throb_animation.h"
43 #include "ui/gfx/canvas.h" 42 #include "ui/gfx/canvas.h"
44 #include "ui/gfx/color_analysis.h" 43 #include "ui/gfx/color_analysis.h"
45 #include "ui/gfx/favicon_size.h" 44 #include "ui/gfx/favicon_size.h"
46 #include "ui/gfx/geometry/rect_conversions.h" 45 #include "ui/gfx/geometry/rect_conversions.h"
47 #include "ui/gfx/image/image_skia_operations.h" 46 #include "ui/gfx/image/image_skia_operations.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 const double kSelectedTabOpacity = 0.3; 87 const double kSelectedTabOpacity = 0.3;
89 88
90 // Inactive selected tabs have their throb value scaled by this. 89 // Inactive selected tabs have their throb value scaled by this.
91 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity; 90 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity;
92 91
93 // Max number of images to cache. This has to be at least two since rounding 92 // Max number of images to cache. This has to be at least two since rounding
94 // errors may lead to tabs in the same tabstrip having different sizes. 93 // errors may lead to tabs in the same tabstrip having different sizes.
95 // 8 = normal/incognito, active/inactive, 2 sizes within tabstrip. 94 // 8 = normal/incognito, active/inactive, 2 sizes within tabstrip.
96 const size_t kMaxImageCacheSize = 8; 95 const size_t kMaxImageCacheSize = 8;
97 96
98 // Height of the miniature tab strip in immersive mode.
99 const int kImmersiveTabHeight = 3;
100
101 // Height of the small tab indicator rectangles in immersive mode.
102 const int kImmersiveBarHeight = 2;
103
104 // Color for active and inactive tabs in the immersive mode light strip. These
105 // should be a little brighter than the color of the normal art assets for tabs,
106 // which for active tabs is 230, 230, 230 and for inactive is 184, 184, 184.
107 const SkColor kImmersiveActiveTabColor = SkColorSetRGB(235, 235, 235);
108 const SkColor kImmersiveInactiveTabColor = SkColorSetRGB(190, 190, 190);
109
110 // The minimum opacity (out of 1) when a tab (either active or inactive) is
111 // throbbing in the immersive mode light strip.
112 const double kImmersiveTabMinThrobOpacity = 0.66;
113
114 // Number of steps in the immersive mode loading animation.
115 const int kImmersiveLoadingStepCount = 32;
116
117 const char kTabCloseButtonName[] = "TabCloseButton"; 97 const char kTabCloseButtonName[] = "TabCloseButton";
118 98
119 //////////////////////////////////////////////////////////////////////////////// 99 ////////////////////////////////////////////////////////////////////////////////
120 // ImageCacheEntryMetadata 100 // ImageCacheEntryMetadata
121 // 101 //
122 // All metadata necessary to uniquely identify a cached image. 102 // All metadata necessary to uniquely identify a cached image.
123 struct ImageCacheEntryMetadata { 103 struct ImageCacheEntryMetadata {
124 ImageCacheEntryMetadata(int resource_id, 104 ImageCacheEntryMetadata(SkColor fill_color,
125 SkColor fill_color,
126 SkColor stroke_color, 105 SkColor stroke_color,
127 bool use_fill_and_stroke_images, 106 bool use_fill_and_stroke_images,
128 float scale_factor, 107 float scale_factor,
129 const gfx::Size& size); 108 const gfx::Size& size);
130 109
131 ~ImageCacheEntryMetadata(); 110 ~ImageCacheEntryMetadata();
132 111
133 bool operator==(const ImageCacheEntryMetadata& rhs) const; 112 bool operator==(const ImageCacheEntryMetadata& rhs) const;
134 113
135 int resource_id; // Only needed by pre-MD 114 SkColor fill_color;
136 SkColor fill_color; // Both colors only needed by MD
137 SkColor stroke_color; 115 SkColor stroke_color;
138 bool use_fill_and_stroke_images; 116 bool use_fill_and_stroke_images;
139 float scale_factor; 117 float scale_factor;
140 gfx::Size size; 118 gfx::Size size;
141 }; 119 };
142 120
143 ImageCacheEntryMetadata::ImageCacheEntryMetadata( 121 ImageCacheEntryMetadata::ImageCacheEntryMetadata(
144 int resource_id,
145 SkColor fill_color, 122 SkColor fill_color,
146 SkColor stroke_color, 123 SkColor stroke_color,
147 bool use_fill_and_stroke_images, 124 bool use_fill_and_stroke_images,
148 float scale_factor, 125 float scale_factor,
149 const gfx::Size& size) 126 const gfx::Size& size)
150 : resource_id(resource_id), 127 : fill_color(fill_color),
151 fill_color(fill_color),
152 stroke_color(stroke_color), 128 stroke_color(stroke_color),
153 use_fill_and_stroke_images(use_fill_and_stroke_images), 129 use_fill_and_stroke_images(use_fill_and_stroke_images),
154 scale_factor(scale_factor), 130 scale_factor(scale_factor),
155 size(size) { 131 size(size) {}
156 // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones
157 // so they don't cause incorrect cache misses.
158 // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted.
159 if (ui::MaterialDesignController::IsModeMaterial())
160 resource_id = 0;
161 else
162 fill_color = stroke_color = SK_ColorTRANSPARENT;
163 }
164 132
165 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {} 133 ImageCacheEntryMetadata::~ImageCacheEntryMetadata() {}
166 134
167 bool ImageCacheEntryMetadata::operator==( 135 bool ImageCacheEntryMetadata::operator==(
168 const ImageCacheEntryMetadata& rhs) const { 136 const ImageCacheEntryMetadata& rhs) const {
169 return resource_id == rhs.resource_id && fill_color == rhs.fill_color && 137 return fill_color == rhs.fill_color && stroke_color == rhs.stroke_color &&
170 stroke_color == rhs.stroke_color &&
171 use_fill_and_stroke_images == rhs.use_fill_and_stroke_images && 138 use_fill_and_stroke_images == rhs.use_fill_and_stroke_images &&
172 scale_factor == rhs.scale_factor && size == rhs.size; 139 scale_factor == rhs.scale_factor && size == rhs.size;
173 } 140 }
174 141
175 //////////////////////////////////////////////////////////////////////////////// 142 ////////////////////////////////////////////////////////////////////////////////
176 // ImageCacheEntry and cache management 143 // ImageCacheEntry and cache management
177 // 144 //
178 // A cached image and the metadata used to generate it. 145 // A cached image and the metadata used to generate it.
179 struct ImageCacheEntry { 146 struct ImageCacheEntry {
180 ImageCacheEntry(const ImageCacheEntryMetadata& metadata, 147 ImageCacheEntry(const ImageCacheEntryMetadata& metadata,
(...skipping 12 matching lines...) Expand all
193 : metadata(metadata), fill_image(fill_image), stroke_image(stroke_image) {} 160 : metadata(metadata), fill_image(fill_image), stroke_image(stroke_image) {}
194 161
195 ImageCacheEntry::~ImageCacheEntry() {} 162 ImageCacheEntry::~ImageCacheEntry() {}
196 163
197 typedef std::list<ImageCacheEntry> ImageCache; 164 typedef std::list<ImageCacheEntry> ImageCache;
198 165
199 // As the majority of the tabs are inactive, and painting tabs is slowish, 166 // As the majority of the tabs are inactive, and painting tabs is slowish,
200 // we cache a handful of the inactive tab backgrounds here. 167 // we cache a handful of the inactive tab backgrounds here.
201 static ImageCache* g_image_cache = nullptr; 168 static ImageCache* g_image_cache = nullptr;
202 169
203 struct TabImages {
204 gfx::ImageSkia* image_l;
205 gfx::ImageSkia* image_c;
206 gfx::ImageSkia* image_r;
207 int l_width;
208 int r_width;
209 };
210 static TabImages g_active_images = {0};
211 static TabImages g_inactive_images = {0};
212 static TabImages g_mask_images = {0};
213
214 // Loads the images to be used for the tab background.
215 void LoadTabImages() {
216 g_image_cache->clear();
217
218 // We're not letting people override tab images just yet.
219 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
220
221 g_active_images.image_l = rb.GetImageSkiaNamed(IDR_TAB_ACTIVE_LEFT);
222 g_active_images.image_c = rb.GetImageSkiaNamed(IDR_TAB_ACTIVE_CENTER);
223 g_active_images.image_r = rb.GetImageSkiaNamed(IDR_TAB_ACTIVE_RIGHT);
224 g_active_images.l_width = g_active_images.image_l->width();
225 g_active_images.r_width = g_active_images.image_r->width();
226
227 g_inactive_images.image_l = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_LEFT);
228 g_inactive_images.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER);
229 g_inactive_images.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT);
230 g_inactive_images.l_width = g_inactive_images.image_l->width();
231 g_inactive_images.r_width = g_inactive_images.image_r->width();
232
233 g_mask_images.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT);
234 g_mask_images.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT);
235 g_mask_images.l_width = g_mask_images.image_l->width();
236 g_mask_images.r_width = g_mask_images.image_r->width();
237 }
238
239 // Performs a one-time initialization of static resources such as tab images. 170 // Performs a one-time initialization of static resources such as tab images.
240 void InitTabResources() { 171 void InitTabResources() {
241 static bool initialized = false; 172 static bool initialized = false;
242 if (initialized) 173 if (initialized)
243 return; 174 return;
244 175
245 initialized = true; 176 initialized = true;
246 g_image_cache = new ImageCache(); 177 g_image_cache = new ImageCache();
247
248 // Load the tab images once now, and maybe again later if the theme changes.
249 LoadTabImages();
250 } 178 }
251 179
252 //////////////////////////////////////////////////////////////////////////////// 180 ////////////////////////////////////////////////////////////////////////////////
253 // Drawing and utility functions 181 // Drawing and utility functions
254 182
255 // Returns the width of the tab endcap at scale 1. More precisely, this is the 183 // Returns the width of the tab endcap at scale 1. More precisely, this is the
256 // width of the curve making up either the outer or inner edge of the stroke; 184 // width of the curve making up either the outer or inner edge of the stroke;
257 // since these two curves are horizontally offset by 1 px (regardless of scale), 185 // since these two curves are horizontally offset by 1 px (regardless of scale),
258 // the total width of the endcap from tab outer edge to the inside end of the 186 // the total width of the endcap from tab outer edge to the inside end of the
259 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1. 187 // stroke inner edge is (GetUnscaledEndcapWidth() * scale) + 1.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 249
322 // Returns a path corresponding to the tab's outer border for a given tab |size| 250 // Returns a path corresponding to the tab's outer border for a given tab |size|
323 // and |scale|. If |unscale_at_end| is true, this path will be normalized to a 251 // and |scale|. If |unscale_at_end| is true, this path will be normalized to a
324 // 1x scale by scaling by 1/scale before returning. If |extend_to_top| is true, 252 // 1x scale by scaling by 1/scale before returning. If |extend_to_top| is true,
325 // the path is extended vertically to the top of the tab bounds. The caller 253 // the path is extended vertically to the top of the tab bounds. The caller
326 // uses this for Fitts' Law purposes in maximized/fullscreen mode. 254 // uses this for Fitts' Law purposes in maximized/fullscreen mode.
327 gfx::Path GetBorderPath(float scale, 255 gfx::Path GetBorderPath(float scale,
328 bool unscale_at_end, 256 bool unscale_at_end,
329 bool extend_to_top, 257 bool extend_to_top,
330 const gfx::Size& size) { 258 const gfx::Size& size) {
259 const float top = scale - 1;
260 const float right = size.width() * scale;
261 const float bottom = size.height() * scale;
262 const float unscaled_endcap_width = GetUnscaledEndcapWidth();
263
331 gfx::Path path; 264 gfx::Path path;
332 if (ui::MaterialDesignController::IsModeMaterial()) { 265 path.moveTo(0, bottom);
333 const float top = scale - 1; 266 path.rLineTo(0, -1);
334 const float right = size.width() * scale; 267 path.rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale,
335 const float bottom = size.height() * scale; 268 -1.5 * scale);
336 const float unscaled_endcap_width = GetUnscaledEndcapWidth(); 269 path.lineTo((unscaled_endcap_width - 2) * scale, top + 1.5 * scale);
270 if (extend_to_top) {
271 // Create the vertical extension by extending the side diagonals until
272 // they reach the top of the bounds.
273 const float dy = 2.5 * scale - 1;
274 const float dx = Tab::GetInverseDiagonalSlope() * dy;
275 path.rLineTo(dx, -dy);
276 path.lineTo(right - (unscaled_endcap_width - 2) * scale - dx, 0);
277 path.rLineTo(dx, dy);
278 } else {
279 path.rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale, 2 * scale,
280 -1.5 * scale);
281 path.lineTo(right - unscaled_endcap_width * scale, top);
282 path.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale,
283 1.5 * scale);
284 }
285 path.lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale);
286 path.rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale,
287 1.5 * scale);
288 path.rLineTo(0, 1);
289 path.close();
337 290
338 path.moveTo(0, bottom); 291 if (unscale_at_end && (scale != 1))
339 path.rLineTo(0, -1); 292 path.transform(SkMatrix::MakeScale(1.f / scale));
340 path.rCubicTo(0.75 * scale, 0, 1.625 * scale, -0.5 * scale, 2 * scale,
341 -1.5 * scale);
342 path.lineTo((unscaled_endcap_width - 2) * scale, top + 1.5 * scale);
343 if (extend_to_top) {
344 // Create the vertical extension by extending the side diagonals until
345 // they reach the top of the bounds.
346 const float dy = 2.5 * scale - 1;
347 const float dx = Tab::GetInverseDiagonalSlope() * dy;
348 path.rLineTo(dx, -dy);
349 path.lineTo(right - (unscaled_endcap_width - 2) * scale - dx, 0);
350 path.rLineTo(dx, dy);
351 } else {
352 path.rCubicTo(0.375 * scale, -scale, 1.25 * scale, -1.5 * scale,
353 2 * scale, -1.5 * scale);
354 path.lineTo(right - unscaled_endcap_width * scale, top);
355 path.rCubicTo(0.75 * scale, 0, 1.625 * scale, 0.5 * scale, 2 * scale,
356 1.5 * scale);
357 }
358 path.lineTo(right - 2 * scale, bottom - 1 - 1.5 * scale);
359 path.rCubicTo(0.375 * scale, scale, 1.25 * scale, 1.5 * scale, 2 * scale,
360 1.5 * scale);
361 path.rLineTo(0, 1);
362 path.close();
363
364 if (unscale_at_end && (scale != 1))
365 path.transform(SkMatrix::MakeScale(1.f / scale));
366 } else {
367 // Hit mask constants.
368 const SkScalar kTabCapWidth = 15;
369 const SkScalar kTabTopCurveWidth = 4;
370 const SkScalar kTabBottomCurveWidth = 3;
371 #if defined(OS_MACOSX)
372 // Mac's Cocoa UI doesn't have shadows.
373 const SkScalar kTabInset = 0;
374 #elif defined(TOOLKIT_VIEWS)
375 // The views browser UI has shadows in the left, right and top parts of the
376 // tab.
377 const SkScalar kTabInset = 6;
378 #endif
379
380 SkScalar left = kTabInset;
381 SkScalar top = SkIntToScalar(0);
382 SkScalar right = SkIntToScalar(size.width()) - kTabInset;
383 SkScalar bottom = SkIntToScalar(size.height());
384
385 // Start in the lower-left corner.
386 path.moveTo(left, bottom);
387
388 // Left end cap.
389 path.lineTo(left + kTabBottomCurveWidth, bottom - kTabBottomCurveWidth);
390 path.lineTo(left + kTabCapWidth - kTabTopCurveWidth,
391 top + kTabTopCurveWidth);
392 path.lineTo(left + kTabCapWidth, top);
393
394 // Connect to the right cap.
395 path.lineTo(right - kTabCapWidth, top);
396
397 // Right end cap.
398 path.lineTo(right - kTabCapWidth + kTabTopCurveWidth,
399 top + kTabTopCurveWidth);
400 path.lineTo(right - kTabBottomCurveWidth, bottom - kTabBottomCurveWidth);
401 path.lineTo(right, bottom);
402
403 // Close out the path.
404 path.lineTo(left, bottom);
405 path.close();
406
407 // Unscaling is not necessary since we never scaled up to begin with.
408 }
409 293
410 return path; 294 return path;
411 } 295 }
412 296
413 void PaintTabFill(gfx::Canvas* canvas,
414 const gfx::ImageSkia& fill_image,
415 gfx::Rect rect,
416 bool is_active) {
417 const gfx::Insets tab_insets(GetLayoutInsets(TAB));
418 // If this isn't the foreground tab, don't draw over the toolbar, but do
419 // include the 1 px divider stroke at the bottom.
420 const int toolbar_overlap = is_active ? 0 : (tab_insets.bottom() - 1);
421
422 // Draw left edge.
423 gfx::ImageSkia tab_l = gfx::ImageSkiaOperations::CreateTiledImage(
424 fill_image, rect.x(), rect.y(), g_mask_images.l_width, rect.height());
425 gfx::ImageSkia theme_l = gfx::ImageSkiaOperations::CreateMaskedImage(
426 tab_l, *g_mask_images.image_l);
427 canvas->DrawImageInt(
428 theme_l, 0, 0, theme_l.width(), theme_l.height() - toolbar_overlap, 0, 0,
429 theme_l.width(), theme_l.height() - toolbar_overlap, false);
430
431 // Draw right edge.
432 gfx::ImageSkia tab_r = gfx::ImageSkiaOperations::CreateTiledImage(
433 fill_image, rect.right() - g_mask_images.r_width, rect.y(),
434 g_mask_images.r_width, rect.height());
435 gfx::ImageSkia theme_r = gfx::ImageSkiaOperations::CreateMaskedImage(
436 tab_r, *g_mask_images.image_r);
437 canvas->DrawImageInt(theme_r, 0, 0, theme_r.width(),
438 theme_r.height() - toolbar_overlap,
439 rect.width() - theme_r.width(), 0, theme_r.width(),
440 theme_r.height() - toolbar_overlap, false);
441
442 // Draw center. Instead of masking out the top portion we simply skip over it
443 // by incrementing by the top padding, since it's a simple rectangle.
444 rect.Inset(g_mask_images.l_width, tab_insets.top(), g_mask_images.r_width,
445 toolbar_overlap);
446 canvas->TileImageInt(fill_image, rect.x(), rect.y(), g_mask_images.l_width,
447 tab_insets.top(), rect.width(), rect.height());
448 }
449
450 } // namespace 297 } // namespace
451 298
452 //////////////////////////////////////////////////////////////////////////////// 299 ////////////////////////////////////////////////////////////////////////////////
453 // FaviconCrashAnimation 300 // FaviconCrashAnimation
454 // 301 //
455 // A custom animation subclass to manage the favicon crash animation. 302 // A custom animation subclass to manage the favicon crash animation.
456 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation, 303 class Tab::FaviconCrashAnimation : public gfx::LinearAnimation,
457 public gfx::AnimationDelegate { 304 public gfx::AnimationDelegate {
458 public: 305 public:
459 explicit FaviconCrashAnimation(Tab* target) 306 explicit FaviconCrashAnimation(Tab* target)
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 507
661 // static 508 // static
662 const char Tab::kViewClassName[] = "Tab"; 509 const char Tab::kViewClassName[] = "Tab";
663 510
664 Tab::Tab(TabController* controller, gfx::AnimationContainer* container) 511 Tab::Tab(TabController* controller, gfx::AnimationContainer* container)
665 : controller_(controller), 512 : controller_(controller),
666 closing_(false), 513 closing_(false),
667 dragging_(false), 514 dragging_(false),
668 detached_(false), 515 detached_(false),
669 favicon_hiding_offset_(0), 516 favicon_hiding_offset_(0),
670 immersive_loading_step_(0),
671 should_display_crashed_favicon_(false), 517 should_display_crashed_favicon_(false),
672 pulse_animation_(new gfx::ThrobAnimation(this)), 518 pulse_animation_(new gfx::ThrobAnimation(this)),
673 crash_icon_animation_(new FaviconCrashAnimation(this)), 519 crash_icon_animation_(new FaviconCrashAnimation(this)),
674 animation_container_(container), 520 animation_container_(container),
675 throbber_(nullptr), 521 throbber_(nullptr),
676 alert_indicator_button_(nullptr), 522 alert_indicator_button_(nullptr),
677 close_button_(nullptr), 523 close_button_(nullptr),
678 title_(new views::Label()), 524 title_(new views::Label()),
679 tab_activated_with_last_tap_down_(false), 525 tab_activated_with_last_tap_down_(false),
680 hover_controller_(this), 526 hover_controller_(this),
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 return kTouchWidth; 717 return kTouchWidth;
872 } 718 }
873 719
874 // static 720 // static
875 int Tab::GetPinnedWidth() { 721 int Tab::GetPinnedWidth() {
876 return GetMinimumInactiveSize().width() + 722 return GetMinimumInactiveSize().width() +
877 GetLayoutConstant(TAB_PINNED_CONTENT_WIDTH); 723 GetLayoutConstant(TAB_PINNED_CONTENT_WIDTH);
878 } 724 }
879 725
880 // static 726 // static
881 int Tab::GetImmersiveHeight() {
882 return kImmersiveTabHeight;
883 }
884
885 // static
886 float Tab::GetInverseDiagonalSlope() { 727 float Tab::GetInverseDiagonalSlope() {
887 // This is computed from the border path as follows: 728 // This is computed from the border path as follows:
888 // * The unscaled endcap width is enough for the whole stroke outer curve, 729 // * The unscaled endcap width is enough for the whole stroke outer curve,
889 // i.e. the side diagonal plus the curves on both its ends. 730 // i.e. the side diagonal plus the curves on both its ends.
890 // * The bottom and top curve are each (2 * scale) px wide, so the diagonal is 731 // * The bottom and top curve are each (2 * scale) px wide, so the diagonal is
891 // (unscaled endcap width - 2 - 2) * scale px wide. 732 // (unscaled endcap width - 2 - 2) * scale px wide.
892 // * The bottom and top curve are each 1.5 px high. Additionally, there is an 733 // * The bottom and top curve are each 1.5 px high. Additionally, there is an
893 // extra 1 px below the bottom curve and (scale - 1) px above the top curve, 734 // extra 1 px below the bottom curve and (scale - 1) px above the top curve,
894 // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px 735 // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px
895 // high. 736 // high.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 if (!closing()) 789 if (!closing())
949 controller_->ShowContextMenuForTab(this, point, source_type); 790 controller_->ShowContextMenuForTab(this, point, source_type);
950 } 791 }
951 792
952 //////////////////////////////////////////////////////////////////////////////// 793 ////////////////////////////////////////////////////////////////////////////////
953 // Tab, views::MaskedTargeterDelegate overrides: 794 // Tab, views::MaskedTargeterDelegate overrides:
954 795
955 bool Tab::GetHitTestMask(gfx::Path* mask) const { 796 bool Tab::GetHitTestMask(gfx::Path* mask) const {
956 // When the window is maximized we don't want to shave off the edges or top 797 // When the window is maximized we don't want to shave off the edges or top
957 // shadow of the tab, such that the user can click anywhere along the top 798 // shadow of the tab, such that the user can click anywhere along the top
958 // edge of the screen to select a tab. Ditto for immersive fullscreen. 799 // edge of the screen to select a tab.
959 const views::Widget* widget = GetWidget(); 800 const views::Widget* widget = GetWidget();
960 *mask = GetBorderPath( 801 *mask = GetBorderPath(
961 GetWidget()->GetCompositor()->device_scale_factor(), true, 802 GetWidget()->GetCompositor()->device_scale_factor(), true,
962 widget && (widget->IsMaximized() || widget->IsFullscreen()), size()); 803 widget && (widget->IsMaximized() || widget->IsFullscreen()), size());
963 return true; 804 return true;
964 } 805 }
965 806
966 //////////////////////////////////////////////////////////////////////////////// 807 ////////////////////////////////////////////////////////////////////////////////
967 // Tab, views::View overrides: 808 // Tab, views::View overrides:
968 809
(...skipping 10 matching lines...) Expand all
979 // only happen during animations). 820 // only happen during animations).
980 if (width() < GetMinimumInactiveSize().width() && !data().pinned) 821 if (width() < GetMinimumInactiveSize().width() && !data().pinned)
981 return; 822 return;
982 823
983 gfx::Path clip; 824 gfx::Path clip;
984 if (!controller_->ShouldPaintTab( 825 if (!controller_->ShouldPaintTab(
985 this, base::Bind(&GetBorderPath, canvas->image_scale(), true, false), 826 this, base::Bind(&GetBorderPath, canvas->image_scale(), true, false),
986 &clip)) 827 &clip))
987 return; 828 return;
988 829
989 if (controller_->IsImmersiveStyle()) 830 PaintTab(canvas, clip);
990 PaintImmersiveTab(canvas);
991 else
992 PaintTab(canvas, clip);
993 } 831 }
994 832
995 void Tab::Layout() { 833 void Tab::Layout() {
996 const gfx::Rect lb = GetContentsBounds(); 834 const gfx::Rect lb = GetContentsBounds();
997 showing_icon_ = ShouldShowIcon(); 835 showing_icon_ = ShouldShowIcon();
998 // See comments in IconCapacity(). 836 // See comments in IconCapacity().
999 const int extra_padding = 837 const int extra_padding =
1000 (controller_->ShouldHideCloseButtonForInactiveTabs() || 838 (controller_->ShouldHideCloseButtonForInactiveTabs() ||
1001 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding; 839 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding;
1002 const int start = lb.x() + extra_padding; 840 const int start = lb.x() + extra_padding;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 } 905 }
1068 // The Label will automatically center the font's cap height within the 906 // The Label will automatically center the font's cap height within the
1069 // provided vertical space. 907 // provided vertical space.
1070 title_->SetBoundsRect( 908 title_->SetBoundsRect(
1071 gfx::Rect(title_left, lb.y(), std::max(title_width, 0), lb.height())); 909 gfx::Rect(title_left, lb.y(), std::max(title_width, 0), lb.height()));
1072 } 910 }
1073 title_->SetVisible(show_title); 911 title_->SetVisible(show_title);
1074 } 912 }
1075 913
1076 void Tab::OnThemeChanged() { 914 void Tab::OnThemeChanged() {
1077 LoadTabImages();
1078 OnButtonColorMaybeChanged(); 915 OnButtonColorMaybeChanged();
1079 favicon_ = gfx::ImageSkia(); 916 favicon_ = gfx::ImageSkia();
1080 } 917 }
1081 918
1082 const char* Tab::GetClassName() const { 919 const char* Tab::GetClassName() const {
1083 return kViewClassName; 920 return kViewClassName;
1084 } 921 }
1085 922
1086 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { 923 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
1087 // Note: Anything that affects the tooltip text should be accounted for when 924 // Note: Anything that affects the tooltip text should be accounted for when
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId, 1132 PaintTabBackgroundUsingFillId(canvas, canvas, true, kActiveTabFillId,
1296 has_custom_image, y_offset); 1133 has_custom_image, y_offset);
1297 canvas->Restore(); 1134 canvas->Restore();
1298 } 1135 }
1299 } 1136 }
1300 1137
1301 if (showing_icon_) 1138 if (showing_icon_)
1302 PaintIcon(canvas); 1139 PaintIcon(canvas);
1303 } 1140 }
1304 1141
1305 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) {
1306 // Use transparency for the draw-attention animation.
1307 int alpha = 255;
1308 if (pulse_animation_->is_animating() && !data().pinned) {
1309 alpha = pulse_animation_->CurrentValueBetween(
1310 255, gfx::ToRoundedInt(255 * kImmersiveTabMinThrobOpacity));
1311 }
1312
1313 // Draw a gray rectangle to represent the tab. This works for pinned tabs as
1314 // well as regular ones. The active tab has a brigher bar.
1315 SkColor color =
1316 IsActive() ? kImmersiveActiveTabColor : kImmersiveInactiveTabColor;
1317 gfx::Rect bar_rect = GetImmersiveBarRect();
1318 canvas->FillRect(bar_rect, SkColorSetA(color, alpha));
1319
1320 // Paint network activity indicator.
1321 // TODO(jamescook): Replace this placeholder animation with a real one.
1322 // For now, let's go with a Cylon eye effect, but in blue.
1323 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
1324 const SkColor kEyeColor = SkColorSetARGB(alpha, 71, 138, 217);
1325 int eye_width = bar_rect.width() / 3;
1326 int eye_offset = bar_rect.width() * immersive_loading_step_ /
1327 kImmersiveLoadingStepCount;
1328 if (eye_offset + eye_width < bar_rect.width()) {
1329 // Draw a single indicator strip because it fits inside |bar_rect|.
1330 gfx::Rect eye_rect(
1331 bar_rect.x() + eye_offset, 0, eye_width, kImmersiveBarHeight);
1332 canvas->FillRect(eye_rect, kEyeColor);
1333 } else {
1334 // Draw two indicators to simulate the eye "wrapping around" to the left
1335 // side. The first part fills the remainder of the bar.
1336 int right_eye_width = bar_rect.width() - eye_offset;
1337 gfx::Rect right_eye_rect(
1338 bar_rect.x() + eye_offset, 0, right_eye_width, kImmersiveBarHeight);
1339 canvas->FillRect(right_eye_rect, kEyeColor);
1340 // The second part parts the remaining |eye_width| on the left.
1341 int left_eye_width = eye_offset + eye_width - bar_rect.width();
1342 gfx::Rect left_eye_rect(
1343 bar_rect.x(), 0, left_eye_width, kImmersiveBarHeight);
1344 canvas->FillRect(left_eye_rect, kEyeColor);
1345 }
1346 }
1347 }
1348
1349 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas, 1142 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas,
1350 const gfx::Path& clip) { 1143 const gfx::Path& clip) {
1351 bool has_custom_image; 1144 bool has_custom_image;
1352 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); 1145 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image);
1353 1146
1354 // If the theme is providing a custom background image, then its top edge 1147 // If the theme is providing a custom background image, then its top edge
1355 // should be at the top of the tab. Otherwise, we assume that the background 1148 // should be at the top of the tab. Otherwise, we assume that the background
1356 // image is a composited foreground + frame image. Note that if the theme is 1149 // image is a composited foreground + frame image. Note that if the theme is
1357 // only providing a custom frame image, |has_custom_image| will be true, but 1150 // only providing a custom frame image, |has_custom_image| will be true, but
1358 // we should use the |background_offset_| here. 1151 // we should use the |background_offset_| here.
1359 const ui::ThemeProvider* tp = GetThemeProvider(); 1152 const ui::ThemeProvider* tp = GetThemeProvider();
1360 const int y_offset = tp->HasCustomImage(fill_id) ? 0 : background_offset_.y(); 1153 const int y_offset = tp->HasCustomImage(fill_id) ? 0 : background_offset_.y();
1361 1154
1362 // We only cache the image when it's the default image and we're not hovered, 1155 // We only cache the image when it's the default image and we're not hovered,
1363 // to avoid caching a background image that isn't the same for all tabs. 1156 // to avoid caching a background image that isn't the same for all tabs.
1364 if (has_custom_image || hover_controller_.ShouldDraw()) { 1157 if (has_custom_image || hover_controller_.ShouldDraw()) {
1365 PaintTabBackgroundUsingFillId(canvas, canvas, false, fill_id, 1158 PaintTabBackgroundUsingFillId(canvas, canvas, false, fill_id,
1366 has_custom_image, y_offset); 1159 has_custom_image, y_offset);
1367 return; 1160 return;
1368 } 1161 }
1369 1162
1370 // For efficiency, we don't use separate fill and stroke images unless we 1163 // For efficiency, we don't use separate fill and stroke images unless we
1371 // really need to clip the stroke and not the fill (for stacked tabs). This 1164 // really need to clip the stroke and not the fill (for stacked tabs). This
1372 // saves memory and avoids an extra image draw at the cost of recalculating 1165 // saves memory and avoids an extra image draw at the cost of recalculating
1373 // the images when MaySetClip() toggles. 1166 // the images when MaySetClip() toggles.
1374 const bool use_fill_and_stroke_images = 1167 const bool use_fill_and_stroke_images = controller_->MaySetClip();
1375 controller_->MaySetClip() &&
1376 ui::MaterialDesignController::IsModeMaterial();
1377 1168
1378 const ImageCacheEntryMetadata metadata( 1169 const ImageCacheEntryMetadata metadata(
1379 fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), 1170 tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB),
1380 controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images, 1171 controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images,
1381 canvas->image_scale(), size()); 1172 canvas->image_scale(), size());
1382 auto it = std::find_if( 1173 auto it = std::find_if(
1383 g_image_cache->begin(), g_image_cache->end(), 1174 g_image_cache->begin(), g_image_cache->end(),
1384 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); 1175 [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; });
1385 if (it == g_image_cache->end()) { 1176 if (it == g_image_cache->end()) {
1386 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false); 1177 gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false);
1387 if (use_fill_and_stroke_images) { 1178 if (use_fill_and_stroke_images) {
1388 gfx::Canvas tmp_fill_canvas(size(), canvas->image_scale(), false); 1179 gfx::Canvas tmp_fill_canvas(size(), canvas->image_scale(), false);
1389 PaintTabBackgroundUsingFillId(&tmp_fill_canvas, &tmp_canvas, false, 1180 PaintTabBackgroundUsingFillId(&tmp_fill_canvas, &tmp_canvas, false,
(...skipping 21 matching lines...) Expand all
1411 } 1202 }
1412 canvas->DrawImageInt(it->stroke_image, 0, 0); 1203 canvas->DrawImageInt(it->stroke_image, 0, 0);
1413 } 1204 }
1414 1205
1415 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, 1206 void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas,
1416 gfx::Canvas* stroke_canvas, 1207 gfx::Canvas* stroke_canvas,
1417 bool is_active, 1208 bool is_active,
1418 int fill_id, 1209 int fill_id,
1419 bool has_custom_image, 1210 bool has_custom_image,
1420 int y_offset) { 1211 int y_offset) {
1421 const ui::ThemeProvider* tp = GetThemeProvider(); 1212 gfx::Path fill;
1422 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); 1213 SkPaint paint;
1423 gfx::ImageSkia* fill_image = tp->GetImageSkiaNamed(fill_id); 1214 paint.setAntiAlias(true);
1424 // The tab image needs to be lined up with the background image
1425 // so that it feels partially transparent. These offsets represent the tab
1426 // position within the frame background image.
1427 const int x_offset = GetMirroredX() + background_offset_.x();
1428 1215
1429 const SkScalar kMinHoverRadius = 16; 1216 // Draw the fill.
1430 const SkScalar radius = 1217 {
1431 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius); 1218 gfx::ScopedCanvas scoped_canvas(fill_canvas);
1432 const bool draw_hover = !is_active && hover_controller_.ShouldDraw(); 1219 const float scale = fill_canvas->UndoDeviceScaleFactor();
1433 SkPoint hover_location(gfx::PointToSkPoint(hover_controller_.location())); 1220 const ui::ThemeProvider* tp = GetThemeProvider();
1434 const SkColor hover_color = 1221 const SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
1435 SkColorSetA(toolbar_color, hover_controller_.GetAlpha());
1436 1222
1437 if (ui::MaterialDesignController::IsModeMaterial()) { 1223 fill = GetFillPath(scale, size());
1438 gfx::Path fill; 1224 {
1439 SkPaint paint; 1225 gfx::ScopedCanvas clip_scoper(fill_canvas);
1440 paint.setAntiAlias(true); 1226 fill_canvas->ClipPath(fill, true);
1227 if (has_custom_image) {
1228 gfx::ScopedCanvas scale_scoper(fill_canvas);
1229 fill_canvas->sk_canvas()->scale(scale, scale);
1230 fill_canvas->TileImageInt(*tp->GetImageSkiaNamed(fill_id),
1231 GetMirroredX() + background_offset_.x(),
1232 y_offset, 0, 0, width(), height());
1233 } else {
1234 paint.setColor(
1235 is_active ? toolbar_color
1236 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB));
1237 fill_canvas->DrawRect(
1238 gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), paint);
1239 }
1441 1240
1442 // Draw the fill. 1241 if (!is_active && hover_controller_.ShouldDraw()) {
1443 { 1242 SkPoint hover_location(
1444 gfx::ScopedCanvas scoped_canvas(fill_canvas); 1243 gfx::PointToSkPoint(hover_controller_.location()));
1445 const float scale = fill_canvas->UndoDeviceScaleFactor(); 1244 hover_location.scale(SkFloatToScalar(scale));
1446 1245 const SkScalar kMinHoverRadius = 16;
1447 fill = GetFillPath(scale, size()); 1246 const SkScalar radius =
1448 { 1247 std::max(SkFloatToScalar(width() / 4.f), kMinHoverRadius);
1449 gfx::ScopedCanvas clip_scoper(fill_canvas); 1248 DrawHighlight(fill_canvas, hover_location, radius * scale,
1450 fill_canvas->ClipPath(fill, true); 1249 SkColorSetA(toolbar_color, hover_controller_.GetAlpha()));
1451 if (has_custom_image) {
1452 gfx::ScopedCanvas scale_scoper(fill_canvas);
1453 fill_canvas->sk_canvas()->scale(scale, scale);
1454 fill_canvas->TileImageInt(*fill_image, x_offset, y_offset, 0, 0,
1455 width(), height());
1456 } else {
1457 paint.setColor(
1458 is_active ? toolbar_color
1459 : tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB));
1460 fill_canvas->DrawRect(
1461 gfx::ScaleToEnclosingRect(GetLocalBounds(), scale), paint);
1462 }
1463 if (draw_hover) {
1464 hover_location.scale(SkFloatToScalar(scale));
1465 DrawHighlight(fill_canvas, hover_location, radius * scale,
1466 hover_color);
1467 }
1468 } 1250 }
1469 } 1251 }
1252 }
1470 1253
1471 // Draw the stroke. 1254 // Draw the stroke.
1472 { 1255 {
1473 gfx::ScopedCanvas scoped_canvas(stroke_canvas); 1256 gfx::ScopedCanvas scoped_canvas(stroke_canvas);
1474 const float scale = stroke_canvas->UndoDeviceScaleFactor(); 1257 const float scale = stroke_canvas->UndoDeviceScaleFactor();
1475 1258
1476 gfx::Path stroke = GetBorderPath(scale, false, false, size()); 1259 gfx::Path stroke = GetBorderPath(scale, false, false, size());
1477 Op(stroke, fill, kDifference_SkPathOp, &stroke); 1260 Op(stroke, fill, kDifference_SkPathOp, &stroke);
1478 if (!is_active) { 1261 if (!is_active) {
1479 // Clip out the bottom line; this will be drawn for us by 1262 // Clip out the bottom line; this will be drawn for us by
1480 // TabStrip::PaintChildren(). 1263 // TabStrip::PaintChildren().
1481 stroke_canvas->ClipRect( 1264 stroke_canvas->ClipRect(
1482 gfx::RectF(width() * scale, height() * scale - 1)); 1265 gfx::RectF(width() * scale, height() * scale - 1));
1483 }
1484 paint.setColor(controller_->GetToolbarTopSeparatorColor());
1485 stroke_canvas->DrawPath(stroke, paint);
1486 } 1266 }
1487 } else { 1267 paint.setColor(controller_->GetToolbarTopSeparatorColor());
1488 gfx::Canvas* canvas = stroke_canvas; 1268 stroke_canvas->DrawPath(stroke, paint);
1489 gfx::Rect rect(gfx::Point(x_offset, y_offset), size());
1490 if (draw_hover) {
1491 // Draw everything to a temporary canvas so we can extract an image for
1492 // use in masking the hover glow.
1493 gfx::Canvas background_canvas(size(), canvas->image_scale(), false);
1494 PaintTabFill(&background_canvas, *fill_image, rect, is_active);
1495 gfx::ImageSkia background_image(background_canvas.ExtractImageRep());
1496 canvas->DrawImageInt(background_image, 0, 0);
1497
1498 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false);
1499 DrawHighlight(&hover_canvas, hover_location, radius, hover_color);
1500 gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage(
1501 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image);
1502 canvas->DrawImageInt(result, 0, 0);
1503 } else {
1504 PaintTabFill(canvas, *fill_image, rect, is_active);
1505 }
1506
1507 // Now draw the stroke, highlights, and shadows around the tab edge.
1508 TabImages* stroke_images =
1509 is_active ? &g_active_images : &g_inactive_images;
1510 canvas->DrawImageInt(*stroke_images->image_l, 0, 0);
1511 canvas->TileImageInt(
1512 *stroke_images->image_c, stroke_images->l_width, 0,
1513 width() - stroke_images->l_width - stroke_images->r_width, height());
1514 canvas->DrawImageInt(*stroke_images->image_r,
1515 width() - stroke_images->r_width, 0);
1516 } 1269 }
1517 } 1270 }
1518 1271
1519 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( 1272 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon(
1520 gfx::Canvas* canvas, 1273 gfx::Canvas* canvas,
1521 const gfx::Rect& favicon_draw_bounds) { 1274 const gfx::Rect& favicon_draw_bounds) {
1522 // The pinned tab title changed indicator consists of two parts: 1275 // The pinned tab title changed indicator consists of two parts:
1523 // . a clear (totally transparent) part over the bottom right (or left in rtl) 1276 // . a clear (totally transparent) part over the bottom right (or left in rtl)
1524 // of the favicon. This is done by drawing the favicon to a canvas, then 1277 // of the favicon. This is done by drawing the favicon to a canvas, then
1525 // drawing the clear part on top of the favicon. 1278 // drawing the clear part on top of the favicon.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 !should_display_crashed_favicon_) { 1344 !should_display_crashed_favicon_) {
1592 PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, bounds); 1345 PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, bounds);
1593 } else if (!favicon_.isNull()) { 1346 } else if (!favicon_.isNull()) {
1594 canvas->DrawImageInt(favicon_, 0, 0, bounds.width(), bounds.height(), 1347 canvas->DrawImageInt(favicon_, 0, 0, bounds.width(), bounds.height(),
1595 bounds.x(), bounds.y(), bounds.width(), 1348 bounds.x(), bounds.y(), bounds.width(),
1596 bounds.height(), false); 1349 bounds.height(), false);
1597 } 1350 }
1598 } 1351 }
1599 1352
1600 void Tab::AdvanceLoadingAnimation() { 1353 void Tab::AdvanceLoadingAnimation() {
1601 const TabRendererData::NetworkState state = data().network_state; 1354 if (data().network_state == TabRendererData::NETWORK_STATE_NONE) {
1602 if (controller_->IsImmersiveStyle()) {
1603 throbber_->SetVisible(false);
1604 if (state == TabRendererData::NETWORK_STATE_WAITING) {
1605 // Waiting steps backwards.
1606 immersive_loading_step_ =
1607 (immersive_loading_step_ - 1 + kImmersiveLoadingStepCount) %
1608 kImmersiveLoadingStepCount;
1609 } else if (state == TabRendererData::NETWORK_STATE_LOADING) {
1610 immersive_loading_step_ =
1611 (immersive_loading_step_ + 1) % kImmersiveLoadingStepCount;
1612 } else {
1613 immersive_loading_step_ = 0;
1614 }
1615
1616 SchedulePaintInRect(GetImmersiveBarRect());
1617 return;
1618 }
1619
1620 if (state == TabRendererData::NETWORK_STATE_NONE) {
1621 throbber_->ResetStartTimes(); 1355 throbber_->ResetStartTimes();
1622 throbber_->SetVisible(false); 1356 throbber_->SetVisible(false);
1623 ScheduleIconPaint(); 1357 ScheduleIconPaint();
1624 return; 1358 return;
1625 } 1359 }
1626 1360
1627 // Since the throbber can animate for a long time, paint to a separate layer 1361 // Since the throbber can animate for a long time, paint to a separate layer
1628 // when possible to reduce repaint overhead. 1362 // when possible to reduce repaint overhead.
1629 const bool paint_to_layer = controller_->CanPaintThrobberToLayer(); 1363 const bool paint_to_layer = controller_->CanPaintThrobberToLayer();
1630 if (paint_to_layer != !!throbber_->layer()) { 1364 if (paint_to_layer != !!throbber_->layer()) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 gfx::Rect bounds = favicon_bounds_; 1478 gfx::Rect bounds = favicon_bounds_;
1745 if (bounds.IsEmpty()) 1479 if (bounds.IsEmpty())
1746 return; 1480 return;
1747 1481
1748 // Extends the area to the bottom when the crash animation is in progress. 1482 // Extends the area to the bottom when the crash animation is in progress.
1749 if (crash_icon_animation_->is_animating()) 1483 if (crash_icon_animation_->is_animating())
1750 bounds.set_height(height() - bounds.y()); 1484 bounds.set_height(height() - bounds.y());
1751 bounds.set_x(GetMirroredXForRect(bounds)); 1485 bounds.set_x(GetMirroredXForRect(bounds));
1752 SchedulePaintInRect(bounds); 1486 SchedulePaintInRect(bounds);
1753 } 1487 }
1754
1755 gfx::Rect Tab::GetImmersiveBarRect() const {
1756 // The main bar is as wide as the normal tab's horizontal top line.
1757 // This top line of the tab extends a few pixels left and right of the
1758 // center image due to pixels in the rounded corner images.
1759 const int kBarPadding = 1;
1760 int main_bar_left = g_active_images.l_width - kBarPadding;
1761 int main_bar_right = width() - g_active_images.r_width + kBarPadding;
1762 return gfx::Rect(
1763 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight);
1764 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698