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

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

Issue 2497373003: Add tab status to accessibility labels (Closed)
Patch Set: Formatting and style Created 4 years 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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 loading_start_time_ = base::TimeTicks(); 487 loading_start_time_ = base::TimeTicks();
488 waiting_state_ = gfx::ThrobberWaitingState(); 488 waiting_state_ = gfx::ThrobberWaitingState();
489 } 489 }
490 490
491 bool Tab::ThrobberView::CanProcessEventsWithinSubtree() const { 491 bool Tab::ThrobberView::CanProcessEventsWithinSubtree() const {
492 return false; 492 return false;
493 } 493 }
494 494
495 void Tab::ThrobberView::OnPaint(gfx::Canvas* canvas) { 495 void Tab::ThrobberView::OnPaint(gfx::Canvas* canvas) {
496 const TabRendererData::NetworkState state = owner_->data().network_state; 496 const TabRendererData::NetworkState state = owner_->data().network_state;
497 if (state == TabRendererData::NETWORK_STATE_NONE) 497 if (state == TabRendererData::NETWORK_STATE_NONE ||
498 state == TabRendererData::NETWORK_STATE_ERROR)
498 return; 499 return;
499 500
500 const ui::ThemeProvider* tp = GetThemeProvider(); 501 const ui::ThemeProvider* tp = GetThemeProvider();
501 const gfx::Rect bounds = GetLocalBounds(); 502 const gfx::Rect bounds = GetLocalBounds();
502 if (state == TabRendererData::NETWORK_STATE_WAITING) { 503 if (state == TabRendererData::NETWORK_STATE_WAITING) {
503 if (waiting_start_time_ == base::TimeTicks()) 504 if (waiting_start_time_ == base::TimeTicks())
504 waiting_start_time_ = base::TimeTicks::Now(); 505 waiting_start_time_ = base::TimeTicks::Now();
505 506
506 waiting_state_.elapsed_time = base::TimeTicks::Now() - waiting_start_time_; 507 waiting_state_.elapsed_time = base::TimeTicks::Now() - waiting_start_time_;
507 gfx::PaintThrobberWaiting( 508 gfx::PaintThrobberWaiting(
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 showing_pinned_tab_title_changed_indicator_ = false; 668 showing_pinned_tab_title_changed_indicator_ = false;
668 669
669 DataChanged(old); 670 DataChanged(old);
670 671
671 Layout(); 672 Layout();
672 SchedulePaint(); 673 SchedulePaint();
673 } 674 }
674 675
675 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { 676 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
676 if (state == data_.network_state && 677 if (state == data_.network_state &&
677 state == TabRendererData::NETWORK_STATE_NONE) { 678 (state == TabRendererData::NETWORK_STATE_NONE ||
678 // If the network state is none and hasn't changed, do nothing. Otherwise we 679 state == TabRendererData::NETWORK_STATE_ERROR)) {
679 // need to advance the animation frame. 680 // If the network state is none or is a network error and hasn't changed,
681 // do nothing. Otherwise we need to advance the animation frame.
680 return; 682 return;
681 } 683 }
682 684
683 data_.network_state = state; 685 data_.network_state = state;
684 AdvanceLoadingAnimation(); 686 AdvanceLoadingAnimation();
685 } 687 }
686 688
687 void Tab::StartPulse() { 689 void Tab::StartPulse() {
688 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); 690 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max());
689 } 691 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 // (unscaled endcap width - 2 - 2) * scale px wide. 759 // (unscaled endcap width - 2 - 2) * scale px wide.
758 // * The bottom and top curve are each 1.5 px high. Additionally, there is an 760 // * The bottom and top curve are each 1.5 px high. Additionally, there is an
759 // extra 1 px below the bottom curve and (scale - 1) px above the top curve, 761 // extra 1 px below the bottom curve and (scale - 1) px above the top curve,
760 // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px 762 // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px
761 // high. 763 // high.
762 // Simplifying these gives the expression below. 764 // Simplifying these gives the expression below.
763 return (GetUnscaledEndcapWidth() - 4) / 765 return (GetUnscaledEndcapWidth() - 4) /
764 (GetMinimumInactiveSize().height() - 4); 766 (GetMinimumInactiveSize().height() - 4);
765 } 767 }
766 768
769 base::string16 Tab::GetAccessibleTabLabel() {
770 base::string16 tab_label;
771
772 if (data_.IsCrashed()) {
773 // Tab has crashed.
774 tab_label = l10n_util::GetStringFUTF16(IDS_TAB_AX_LABEL_CRASHED_FORMAT,
775 data_.title);
776 } else if (data_.network_state == TabRendererData::NETWORK_STATE_ERROR) {
777 // Network error interstitial.
778 tab_label = l10n_util::GetStringFUTF16(
779 IDS_TAB_AX_LABEL_NETWORK_ERROR_FORMAT, data_.title);
780 } else {
781 // Alert tab states.
782 switch (data_.alert_state) {
783 case TabAlertState::AUDIO_PLAYING:
784 tab_label = l10n_util::GetStringFUTF16(
785 IDS_TAB_AX_LABEL_AUDIO_PLAYING_FORMAT, data_.title);
786 break;
787 case TabAlertState::USB_CONNECTED:
788 tab_label = l10n_util::GetStringFUTF16(
789 IDS_TAB_AX_LABEL_USB_CONNECTED_FORMAT, data_.title);
790 break;
791 case TabAlertState::BLUETOOTH_CONNECTED:
792 tab_label = l10n_util::GetStringFUTF16(
793 IDS_TAB_AX_LABEL_BLUETOOTH_CONNECTED_FORMAT, data_.title);
794 break;
795 case TabAlertState::MEDIA_RECORDING:
796 tab_label = l10n_util::GetStringFUTF16(
797 IDS_TAB_AX_LABEL_MEDIA_RECORDING_FORMAT, data_.title);
798 break;
799 case TabAlertState::AUDIO_MUTING:
800 tab_label = l10n_util::GetStringFUTF16(
801 IDS_TAB_AX_LABEL_AUDIO_MUTING_FORMAT, data_.title);
802 break;
803 case TabAlertState::TAB_CAPTURING:
804 tab_label = l10n_util::GetStringFUTF16(
805 IDS_TAB_AX_LABEL_TAB_CAPTURING_FORMAT, data_.title);
806 break;
807 case TabAlertState::NONE:
808 default:
809 tab_label = data_.title;
810 break;
811 }
812 }
813 // Indicate tab is incognito in addition to other tab status.
814 if (data_.incognito) {
815 tab_label = l10n_util::GetStringFUTF16(
816 IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT, tab_label);
817 }
818 return tab_label;
819 }
820
767 //////////////////////////////////////////////////////////////////////////////// 821 ////////////////////////////////////////////////////////////////////////////////
768 // Tab, AnimationDelegate overrides: 822 // Tab, AnimationDelegate overrides:
769 823
770 void Tab::AnimationProgressed(const gfx::Animation* animation) { 824 void Tab::AnimationProgressed(const gfx::Animation* animation) {
771 // Ignore if the pulse animation is being performed on active tab because 825 // Ignore if the pulse animation is being performed on active tab because
772 // it repaints the same image. See PaintTab(). 826 // it repaints the same image. See PaintTab().
773 if ((animation != pulse_animation_.get()) || !IsActive()) 827 if ((animation != pulse_animation_.get()) || !IsActive())
774 SchedulePaint(); 828 SchedulePaint();
775 } 829 }
776 830
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 break; 1147 break;
1094 1148
1095 default: 1149 default:
1096 break; 1150 break;
1097 } 1151 }
1098 event->SetHandled(); 1152 event->SetHandled();
1099 } 1153 }
1100 1154
1101 void Tab::GetAccessibleNodeData(ui::AXNodeData* node_data) { 1155 void Tab::GetAccessibleNodeData(ui::AXNodeData* node_data) {
1102 node_data->role = ui::AX_ROLE_TAB; 1156 node_data->role = ui::AX_ROLE_TAB;
1103 node_data->SetName(data_.title); 1157 node_data->SetName(GetAccessibleTabLabel());
1104 node_data->AddStateFlag(ui::AX_STATE_MULTISELECTABLE); 1158 node_data->AddStateFlag(ui::AX_STATE_MULTISELECTABLE);
1105 node_data->AddStateFlag(ui::AX_STATE_SELECTABLE); 1159 node_data->AddStateFlag(ui::AX_STATE_SELECTABLE);
1106 controller_->UpdateTabAccessibilityState(this, node_data); 1160 controller_->UpdateTabAccessibilityState(this, node_data);
1107 if (IsSelected()) 1161 if (IsSelected())
1108 node_data->AddStateFlag(ui::AX_STATE_SELECTED); 1162 node_data->AddStateFlag(ui::AX_STATE_SELECTED);
1109 } 1163 }
1110 1164
1111 //////////////////////////////////////////////////////////////////////////////// 1165 ////////////////////////////////////////////////////////////////////////////////
1112 // Tab, private 1166 // Tab, private
1113 1167
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 // Draw a gray rectangle to represent the tab. This works for pinned tabs as 1232 // Draw a gray rectangle to represent the tab. This works for pinned tabs as
1179 // well as regular ones. The active tab has a brigher bar. 1233 // well as regular ones. The active tab has a brigher bar.
1180 SkColor color = 1234 SkColor color =
1181 IsActive() ? kImmersiveActiveTabColor : kImmersiveInactiveTabColor; 1235 IsActive() ? kImmersiveActiveTabColor : kImmersiveInactiveTabColor;
1182 gfx::Rect bar_rect = GetImmersiveBarRect(); 1236 gfx::Rect bar_rect = GetImmersiveBarRect();
1183 canvas->FillRect(bar_rect, SkColorSetA(color, alpha)); 1237 canvas->FillRect(bar_rect, SkColorSetA(color, alpha));
1184 1238
1185 // Paint network activity indicator. 1239 // Paint network activity indicator.
1186 // TODO(jamescook): Replace this placeholder animation with a real one. 1240 // TODO(jamescook): Replace this placeholder animation with a real one.
1187 // For now, let's go with a Cylon eye effect, but in blue. 1241 // For now, let's go with a Cylon eye effect, but in blue.
1188 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { 1242 if (data().network_state != TabRendererData::NETWORK_STATE_NONE &&
1243 data().network_state != TabRendererData::NETWORK_STATE_ERROR) {
1189 const SkColor kEyeColor = SkColorSetARGB(alpha, 71, 138, 217); 1244 const SkColor kEyeColor = SkColorSetARGB(alpha, 71, 138, 217);
1190 int eye_width = bar_rect.width() / 3; 1245 int eye_width = bar_rect.width() / 3;
1191 int eye_offset = bar_rect.width() * immersive_loading_step_ / 1246 int eye_offset = bar_rect.width() * immersive_loading_step_ /
1192 kImmersiveLoadingStepCount; 1247 kImmersiveLoadingStepCount;
1193 if (eye_offset + eye_width < bar_rect.width()) { 1248 if (eye_offset + eye_width < bar_rect.width()) {
1194 // Draw a single indicator strip because it fits inside |bar_rect|. 1249 // Draw a single indicator strip because it fits inside |bar_rect|.
1195 gfx::Rect eye_rect( 1250 gfx::Rect eye_rect(
1196 bar_rect.x() + eye_offset, 0, eye_width, kImmersiveBarHeight); 1251 bar_rect.x() + eye_offset, 0, eye_width, kImmersiveBarHeight);
1197 canvas->FillRect(eye_rect, kEyeColor); 1252 canvas->FillRect(eye_rect, kEyeColor);
1198 } else { 1253 } else {
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 1438
1384 void Tab::PaintIcon(gfx::Canvas* canvas) { 1439 void Tab::PaintIcon(gfx::Canvas* canvas) {
1385 gfx::Rect bounds = favicon_bounds_; 1440 gfx::Rect bounds = favicon_bounds_;
1386 bounds.set_x(GetMirroredXForRect(bounds)); 1441 bounds.set_x(GetMirroredXForRect(bounds));
1387 bounds.Offset(0, favicon_hiding_offset_); 1442 bounds.Offset(0, favicon_hiding_offset_);
1388 bounds.Intersect(GetContentsBounds()); 1443 bounds.Intersect(GetContentsBounds());
1389 if (bounds.IsEmpty()) 1444 if (bounds.IsEmpty())
1390 return; 1445 return;
1391 1446
1392 // Throbber will do its own painting. 1447 // Throbber will do its own painting.
1393 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) 1448 if (data().network_state != TabRendererData::NETWORK_STATE_NONE &&
1449 data().network_state != TabRendererData::NETWORK_STATE_ERROR) {
1394 return; 1450 return;
1395 1451 }
1396 // Ensure that |favicon_| is created. 1452 // Ensure that |favicon_| is created.
1397 if (favicon_.isNull()) { 1453 if (favicon_.isNull()) {
1398 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); 1454 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
1399 favicon_ = should_display_crashed_favicon_ 1455 favicon_ = should_display_crashed_favicon_
1400 ? *rb->GetImageSkiaNamed(IDR_CRASH_SAD_FAVICON) 1456 ? *rb->GetImageSkiaNamed(IDR_CRASH_SAD_FAVICON)
1401 : data().favicon; 1457 : data().favicon;
1402 // Themify the icon if it's a chrome:// page or if it's the sadtab favicon. 1458 // Themify the icon if it's a chrome:// page or if it's the sadtab favicon.
1403 // This ensures chrome:// pages are visible over the tab background. This is 1459 // This ensures chrome:// pages are visible over the tab background. This is
1404 // similar to code in the bookmarks bar. 1460 // similar to code in the bookmarks bar.
1405 if (!favicon_.isNull() && 1461 if (!favicon_.isNull() &&
(...skipping 29 matching lines...) Expand all
1435 immersive_loading_step_ = 1491 immersive_loading_step_ =
1436 (immersive_loading_step_ + 1) % kImmersiveLoadingStepCount; 1492 (immersive_loading_step_ + 1) % kImmersiveLoadingStepCount;
1437 } else { 1493 } else {
1438 immersive_loading_step_ = 0; 1494 immersive_loading_step_ = 0;
1439 } 1495 }
1440 1496
1441 SchedulePaintInRect(GetImmersiveBarRect()); 1497 SchedulePaintInRect(GetImmersiveBarRect());
1442 return; 1498 return;
1443 } 1499 }
1444 1500
1445 if (state == TabRendererData::NETWORK_STATE_NONE) { 1501 if (state == TabRendererData::NETWORK_STATE_NONE ||
1502 state == TabRendererData::NETWORK_STATE_ERROR) {
1446 throbber_->ResetStartTimes(); 1503 throbber_->ResetStartTimes();
1447 throbber_->SetVisible(false); 1504 throbber_->SetVisible(false);
1448 ScheduleIconPaint(); 1505 ScheduleIconPaint();
1449 return; 1506 return;
1450 } 1507 }
1451 1508
1452 // Since the throbber can animate for a long time, paint to a separate layer 1509 // Since the throbber can animate for a long time, paint to a separate layer
1453 // when possible to reduce repaint overhead. 1510 // when possible to reduce repaint overhead.
1454 const bool paint_to_layer = controller_->CanPaintThrobberToLayer(); 1511 const bool paint_to_layer = controller_->CanPaintThrobberToLayer();
1455 if (paint_to_layer != !!throbber_->layer()) { 1512 if (paint_to_layer != !!throbber_->layer()) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 SchedulePaintInRect(bounds); 1634 SchedulePaintInRect(bounds);
1578 } 1635 }
1579 1636
1580 gfx::Rect Tab::GetImmersiveBarRect() const { 1637 gfx::Rect Tab::GetImmersiveBarRect() const {
1581 // The main bar is as wide as the normal tab's horizontal top line. 1638 // The main bar is as wide as the normal tab's horizontal top line.
1582 gfx::Rect contents = GetContentsBounds(); 1639 gfx::Rect contents = GetContentsBounds();
1583 contents.set_y(0); 1640 contents.set_y(0);
1584 contents.set_height(kImmersiveBarHeight); 1641 contents.set_height(kImmersiveBarHeight);
1585 return contents; 1642 return contents;
1586 } 1643 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698