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_strip.h" | 5 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windowsx.h> | 8 #include <windowsx.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "chrome/common/chrome_switches.h" | 31 #include "chrome/common/chrome_switches.h" |
32 #include "chrome/grit/generated_resources.h" | 32 #include "chrome/grit/generated_resources.h" |
33 #include "content/public/browser/user_metrics.h" | 33 #include "content/public/browser/user_metrics.h" |
34 #include "grit/theme_resources.h" | 34 #include "grit/theme_resources.h" |
35 #include "ui/accessibility/ax_view_state.h" | 35 #include "ui/accessibility/ax_view_state.h" |
36 #include "ui/base/default_theme_provider.h" | 36 #include "ui/base/default_theme_provider.h" |
37 #include "ui/base/dragdrop/drag_drop_types.h" | 37 #include "ui/base/dragdrop/drag_drop_types.h" |
38 #include "ui/base/l10n/l10n_util.h" | 38 #include "ui/base/l10n/l10n_util.h" |
39 #include "ui/base/models/list_selection_model.h" | 39 #include "ui/base/models/list_selection_model.h" |
40 #include "ui/base/resource/resource_bundle.h" | 40 #include "ui/base/resource/resource_bundle.h" |
41 #include "ui/compositor/paint_context.h" | 41 #include "ui/compositor/compositing_recorder.h" |
| 42 #include "ui/compositor/paint_recorder.h" |
42 #include "ui/gfx/animation/animation_container.h" | 43 #include "ui/gfx/animation/animation_container.h" |
43 #include "ui/gfx/animation/throb_animation.h" | 44 #include "ui/gfx/animation/throb_animation.h" |
44 #include "ui/gfx/canvas.h" | 45 #include "ui/gfx/canvas.h" |
45 #include "ui/gfx/display.h" | 46 #include "ui/gfx/display.h" |
46 #include "ui/gfx/geometry/rect_conversions.h" | 47 #include "ui/gfx/geometry/rect_conversions.h" |
47 #include "ui/gfx/geometry/size.h" | 48 #include "ui/gfx/geometry/size.h" |
48 #include "ui/gfx/image/image_skia.h" | 49 #include "ui/gfx/image/image_skia.h" |
49 #include "ui/gfx/image/image_skia_operations.h" | 50 #include "ui/gfx/image/image_skia_operations.h" |
50 #include "ui/gfx/path.h" | 51 #include "ui/gfx/path.h" |
51 #include "ui/gfx/screen.h" | 52 #include "ui/gfx/screen.h" |
(...skipping 15 matching lines...) Expand all Loading... |
67 #include "ui/views/win/hwnd_util.h" | 68 #include "ui/views/win/hwnd_util.h" |
68 #endif | 69 #endif |
69 | 70 |
70 using base::UserMetricsAction; | 71 using base::UserMetricsAction; |
71 using ui::DropTargetEvent; | 72 using ui::DropTargetEvent; |
72 | 73 |
73 namespace { | 74 namespace { |
74 | 75 |
75 static const int kTabStripAnimationVSlop = 40; | 76 static const int kTabStripAnimationVSlop = 40; |
76 // Inactive tabs in a native frame are slightly transparent. | 77 // Inactive tabs in a native frame are slightly transparent. |
77 static const int kGlassFrameInactiveTabAlpha = 200; | 78 static const uint8_t kGlassFrameInactiveTabAlpha = 200; |
78 // If there are multiple tabs selected then make non-selected inactive tabs | 79 // If there are multiple tabs selected then make non-selected inactive tabs |
79 // even more transparent. | 80 // even more transparent. |
80 static const int kGlassFrameInactiveTabAlphaMultiSelection = 150; | 81 static const int kGlassFrameInactiveTabAlphaMultiSelection = 150; |
81 | 82 |
82 // Alpha applied to all elements save the selected tabs. | 83 // Alpha applied to all elements save the selected tabs. |
83 static const int kInactiveTabAndNewTabButtonAlphaAsh = 230; | 84 static const uint8_t kInactiveTabAndNewTabButtonAlphaAsh = 230; |
84 static const int kInactiveTabAndNewTabButtonAlpha = 255; | 85 static const uint8_t kInactiveTabAndNewTabButtonAlpha = 255; |
85 | 86 |
86 // Inverse ratio of the width of a tab edge to the width of the tab. When | 87 // Inverse ratio of the width of a tab edge to the width of the tab. When |
87 // hovering over the left or right edge of a tab, the drop indicator will | 88 // hovering over the left or right edge of a tab, the drop indicator will |
88 // point between tabs. | 89 // point between tabs. |
89 static const int kTabEdgeRatioInverse = 4; | 90 static const int kTabEdgeRatioInverse = 4; |
90 | 91 |
91 // Size of the drop indicator. | 92 // Size of the drop indicator. |
92 static int drop_indicator_width; | 93 static int drop_indicator_width; |
93 static int drop_indicator_height; | 94 static int drop_indicator_height; |
94 | 95 |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 IDR_NEWTAB_BUTTON_P : IDR_NEWTAB_BUTTON; | 452 IDR_NEWTAB_BUTTON_P : IDR_NEWTAB_BUTTON; |
452 gfx::ImageSkia* overlay = GetThemeProvider()->GetImageSkiaNamed(overlay_id); | 453 gfx::ImageSkia* overlay = GetThemeProvider()->GetImageSkiaNamed(overlay_id); |
453 | 454 |
454 gfx::Canvas canvas( | 455 gfx::Canvas canvas( |
455 gfx::Size(overlay->width(), overlay->height()), | 456 gfx::Size(overlay->width(), overlay->height()), |
456 scale, | 457 scale, |
457 false); | 458 false); |
458 canvas.DrawImageInt(GetBackgroundImage(state, scale), 0, 0); | 459 canvas.DrawImageInt(GetBackgroundImage(state, scale), 0, 0); |
459 | 460 |
460 // Draw the button border with a slight alpha. | 461 // Draw the button border with a slight alpha. |
461 const int kGlassFrameOverlayAlpha = 178; | 462 const uint8_t kGlassFrameOverlayAlpha = 178; |
462 const int kOpaqueFrameOverlayAlpha = 230; | 463 const uint8_t kOpaqueFrameOverlayAlpha = 230; |
463 uint8 alpha = ShouldWindowContentsBeTransparent() ? | 464 uint8_t alpha = ShouldWindowContentsBeTransparent() |
464 kGlassFrameOverlayAlpha : kOpaqueFrameOverlayAlpha; | 465 ? kGlassFrameOverlayAlpha |
| 466 : kOpaqueFrameOverlayAlpha; |
465 canvas.DrawImageInt(*overlay, 0, 0, alpha); | 467 canvas.DrawImageInt(*overlay, 0, 0, alpha); |
466 | 468 |
467 return gfx::ImageSkia(canvas.ExtractImageRep()); | 469 return gfx::ImageSkia(canvas.ExtractImageRep()); |
468 } | 470 } |
469 | 471 |
470 gfx::ImageSkia NewTabButton::GetImageForScale(float scale) const { | 472 gfx::ImageSkia NewTabButton::GetImageForScale(float scale) const { |
471 if (!hover_animation_->is_animating()) | 473 if (!hover_animation_->is_animating()) |
472 return GetImageForState(state(), scale); | 474 return GetImageForState(state(), scale); |
473 return gfx::ImageSkiaOperations::CreateBlendedImage( | 475 return gfx::ImageSkiaOperations::CreateBlendedImage( |
474 GetImageForState(views::CustomButton::STATE_NORMAL, scale), | 476 GetImageForState(views::CustomButton::STATE_NORMAL, scale), |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 void TabStrip::Layout() { | 1237 void TabStrip::Layout() { |
1236 // Only do a layout if our size changed. | 1238 // Only do a layout if our size changed. |
1237 if (last_layout_size_ == size()) | 1239 if (last_layout_size_ == size()) |
1238 return; | 1240 return; |
1239 if (IsDragSessionActive()) | 1241 if (IsDragSessionActive()) |
1240 return; | 1242 return; |
1241 DoLayout(); | 1243 DoLayout(); |
1242 } | 1244 } |
1243 | 1245 |
1244 void TabStrip::PaintChildren(const ui::PaintContext& context) { | 1246 void TabStrip::PaintChildren(const ui::PaintContext& context) { |
1245 gfx::Canvas* canvas = context.canvas(); | |
1246 // The view order doesn't match the paint order (tabs_ contains the tab | 1247 // The view order doesn't match the paint order (tabs_ contains the tab |
1247 // ordering). Additionally we need to paint the tabs that are closing in | 1248 // ordering). Additionally we need to paint the tabs that are closing in |
1248 // |tabs_closing_map_|. | 1249 // |tabs_closing_map_|. |
1249 Tab* active_tab = NULL; | 1250 Tab* active_tab = NULL; |
1250 Tabs tabs_dragging; | 1251 Tabs tabs_dragging; |
1251 Tabs selected_tabs; | 1252 Tabs selected_tabs; |
1252 int selected_tab_count = 0; | 1253 int selected_tab_count = 0; |
1253 bool is_dragging = false; | 1254 bool is_dragging = false; |
1254 int active_tab_index = -1; | 1255 int active_tab_index = -1; |
1255 | 1256 |
1256 const chrome::HostDesktopType host_desktop_type = | 1257 const chrome::HostDesktopType host_desktop_type = |
1257 chrome::GetHostDesktopTypeForNativeView(GetWidget()->GetNativeView()); | 1258 chrome::GetHostDesktopTypeForNativeView(GetWidget()->GetNativeView()); |
1258 const int inactive_tab_alpha = | 1259 const uint8_t inactive_tab_alpha = |
1259 (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH) ? | 1260 (host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH) |
1260 kInactiveTabAndNewTabButtonAlphaAsh : kInactiveTabAndNewTabButtonAlpha; | 1261 ? kInactiveTabAndNewTabButtonAlphaAsh |
| 1262 : kInactiveTabAndNewTabButtonAlpha; |
1261 | 1263 |
1262 if (inactive_tab_alpha < 255) | 1264 { |
1263 canvas->SaveLayerAlpha(inactive_tab_alpha); | 1265 ui::CompositingRecorder opacity_recorder(context, inactive_tab_alpha); |
1264 | 1266 |
1265 PaintClosingTabs(tab_count(), context); | 1267 PaintClosingTabs(tab_count(), context); |
1266 | 1268 |
1267 for (int i = tab_count() - 1; i >= 0; --i) { | 1269 for (int i = tab_count() - 1; i >= 0; --i) { |
1268 Tab* tab = tab_at(i); | 1270 Tab* tab = tab_at(i); |
1269 if (tab->IsSelected()) | 1271 if (tab->IsSelected()) |
1270 selected_tab_count++; | 1272 selected_tab_count++; |
1271 if (tab->dragging() && !stacked_layout_) { | 1273 if (tab->dragging() && !stacked_layout_) { |
1272 is_dragging = true; | 1274 is_dragging = true; |
1273 if (tab->IsActive()) { | 1275 if (tab->IsActive()) { |
| 1276 active_tab = tab; |
| 1277 active_tab_index = i; |
| 1278 } else { |
| 1279 tabs_dragging.push_back(tab); |
| 1280 } |
| 1281 } else if (!tab->IsActive()) { |
| 1282 if (!tab->IsSelected()) { |
| 1283 if (!stacked_layout_) |
| 1284 tab->Paint(context); |
| 1285 } else { |
| 1286 selected_tabs.push_back(tab); |
| 1287 } |
| 1288 } else { |
1274 active_tab = tab; | 1289 active_tab = tab; |
1275 active_tab_index = i; | 1290 active_tab_index = i; |
1276 } else { | |
1277 tabs_dragging.push_back(tab); | |
1278 } | 1291 } |
1279 } else if (!tab->IsActive()) { | 1292 PaintClosingTabs(i, context); |
1280 if (!tab->IsSelected()) { | 1293 } |
1281 if (!stacked_layout_) | 1294 |
1282 tab->Paint(context); | 1295 // Draw from the left and then the right if we're in touch mode. |
1283 } else { | 1296 if (stacked_layout_ && active_tab_index >= 0) { |
1284 selected_tabs.push_back(tab); | 1297 for (int i = 0; i < active_tab_index; ++i) { |
| 1298 Tab* tab = tab_at(i); |
| 1299 tab->Paint(context); |
1285 } | 1300 } |
1286 } else { | 1301 |
1287 active_tab = tab; | 1302 for (int i = tab_count() - 1; i > active_tab_index; --i) { |
1288 active_tab_index = i; | 1303 Tab* tab = tab_at(i); |
| 1304 tab->Paint(context); |
| 1305 } |
1289 } | 1306 } |
1290 PaintClosingTabs(i, context); | |
1291 } | 1307 } |
1292 | 1308 |
1293 // Draw from the left and then the right if we're in touch mode. | |
1294 if (stacked_layout_ && active_tab_index >= 0) { | |
1295 for (int i = 0; i < active_tab_index; ++i) { | |
1296 Tab* tab = tab_at(i); | |
1297 tab->Paint(context); | |
1298 } | |
1299 | |
1300 for (int i = tab_count() - 1; i > active_tab_index; --i) { | |
1301 Tab* tab = tab_at(i); | |
1302 tab->Paint(context); | |
1303 } | |
1304 } | |
1305 if (inactive_tab_alpha < 255) | |
1306 canvas->Restore(); | |
1307 | |
1308 if (GetWidget()->ShouldWindowContentsBeTransparent()) { | 1309 if (GetWidget()->ShouldWindowContentsBeTransparent()) { |
| 1310 ui::PaintRecorder recorder(context); |
1309 // Make sure non-active tabs are somewhat transparent. | 1311 // Make sure non-active tabs are somewhat transparent. |
1310 SkPaint paint; | 1312 SkPaint paint; |
1311 // If there are multiple tabs selected, fade non-selected tabs more to make | 1313 // If there are multiple tabs selected, fade non-selected tabs more to make |
1312 // the selected tabs more noticable. | 1314 // the selected tabs more noticable. |
1313 int alpha = selected_tab_count > 1 ? | 1315 uint8_t alpha = selected_tab_count > 1 |
1314 kGlassFrameInactiveTabAlphaMultiSelection : | 1316 ? kGlassFrameInactiveTabAlphaMultiSelection |
1315 kGlassFrameInactiveTabAlpha; | 1317 : kGlassFrameInactiveTabAlpha; |
1316 paint.setColor(SkColorSetARGB(alpha, 255, 255, 255)); | 1318 paint.setColor(SkColorSetARGB(alpha, 255, 255, 255)); |
1317 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | 1319 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
1318 paint.setStyle(SkPaint::kFill_Style); | 1320 paint.setStyle(SkPaint::kFill_Style); |
1319 | 1321 |
1320 // The tab graphics include some shadows at the top, so the actual | 1322 // The tab graphics include some shadows at the top, so the actual |
1321 // tabstrip top is 4 px. above the apparent top of the tab, to provide room | 1323 // tabstrip top is 4 px. above the apparent top of the tab, to provide room |
1322 // to draw these. Exclude this region when trying to make tabs transparent | 1324 // to draw these. Exclude this region when trying to make tabs transparent |
1323 // as it's transparent enough already, and drawing in this region can | 1325 // as it's transparent enough already, and drawing in this region can |
1324 // overlap the avatar button, leading to visual artifacts. | 1326 // overlap the avatar button, leading to visual artifacts. |
1325 const int kTopOffset = 4; | 1327 const int kTopOffset = 4; |
1326 // The tabstrip area overlaps the toolbar area by 2 px. | 1328 // The tabstrip area overlaps the toolbar area by 2 px. |
1327 canvas->DrawRect( | 1329 recorder.canvas()->DrawRect( |
1328 gfx::Rect(0, kTopOffset, width(), height() - kTopOffset - 2), paint); | 1330 gfx::Rect(0, kTopOffset, width(), height() - kTopOffset - 2), paint); |
1329 } | 1331 } |
1330 | 1332 |
1331 // Now selected but not active. We don't want these dimmed if using native | 1333 // Now selected but not active. We don't want these dimmed if using native |
1332 // frame, so they're painted after initial pass. | 1334 // frame, so they're painted after initial pass. |
1333 for (size_t i = 0; i < selected_tabs.size(); ++i) | 1335 for (size_t i = 0; i < selected_tabs.size(); ++i) |
1334 selected_tabs[i]->Paint(context); | 1336 selected_tabs[i]->Paint(context); |
1335 | 1337 |
1336 // Next comes the active tab. | 1338 // Next comes the active tab. |
1337 if (active_tab && !is_dragging) | 1339 if (active_tab && !is_dragging) |
1338 active_tab->Paint(context); | 1340 active_tab->Paint(context); |
1339 | 1341 |
1340 // Paint the New Tab button. | 1342 // Paint the New Tab button. |
1341 if (inactive_tab_alpha < 255) | 1343 { |
1342 canvas->SaveLayerAlpha(inactive_tab_alpha); | 1344 ui::CompositingRecorder opacity_recorder(context, inactive_tab_alpha); |
1343 newtab_button_->Paint(context); | 1345 newtab_button_->Paint(context); |
1344 if (inactive_tab_alpha < 255) | 1346 } |
1345 canvas->Restore(); | |
1346 | 1347 |
1347 // And the dragged tabs. | 1348 // And the dragged tabs. |
1348 for (size_t i = 0; i < tabs_dragging.size(); ++i) | 1349 for (size_t i = 0; i < tabs_dragging.size(); ++i) |
1349 tabs_dragging[i]->Paint(context); | 1350 tabs_dragging[i]->Paint(context); |
1350 | 1351 |
1351 // If the active tab is being dragged, it goes last. | 1352 // If the active tab is being dragged, it goes last. |
1352 if (active_tab && is_dragging) | 1353 if (active_tab && is_dragging) |
1353 active_tab->Paint(context); | 1354 active_tab->Paint(context); |
1354 } | 1355 } |
1355 | 1356 |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 ConvertPointToViewAndGetEventHandler(this, newtab_button_, point); | 2759 ConvertPointToViewAndGetEventHandler(this, newtab_button_, point); |
2759 if (view) | 2760 if (view) |
2760 return view; | 2761 return view; |
2761 } | 2762 } |
2762 Tab* tab = FindTabForEvent(point); | 2763 Tab* tab = FindTabForEvent(point); |
2763 if (tab) | 2764 if (tab) |
2764 return ConvertPointToViewAndGetEventHandler(this, tab, point); | 2765 return ConvertPointToViewAndGetEventHandler(this, tab, point); |
2765 } | 2766 } |
2766 return this; | 2767 return this; |
2767 } | 2768 } |
OLD | NEW |