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 "ash/system/tray_accessibility.h" | 5 #include "ash/system/tray_accessibility.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/shell_delegate.h" | 8 #include "ash/shell_delegate.h" |
| 9 #include "ash/system/tray/system_tray.h" |
| 10 #include "ash/system/tray/system_tray_delegate.h" |
9 #include "ash/system/tray/tray_constants.h" | 11 #include "ash/system/tray/tray_constants.h" |
| 12 #include "ash/system/tray/tray_details_view.h" |
| 13 #include "ash/system/tray/tray_item_more.h" |
| 14 #include "ash/system/tray/tray_notification_view.h" |
10 #include "ash/system/tray/tray_views.h" | 15 #include "ash/system/tray/tray_views.h" |
11 #include "grit/ash_resources.h" | 16 #include "grit/ash_resources.h" |
12 #include "grit/ash_strings.h" | 17 #include "grit/ash_strings.h" |
| 18 #include "ui/base/l10n/l10n_util.h" |
13 #include "ui/base/resource/resource_bundle.h" | 19 #include "ui/base/resource/resource_bundle.h" |
14 #include "ui/gfx/image/image.h" | 20 #include "ui/gfx/image/image.h" |
15 #include "ui/views/controls/image_view.h" | 21 #include "ui/views/controls/image_view.h" |
16 #include "ui/views/controls/label.h" | 22 #include "ui/views/controls/label.h" |
17 #include "ui/views/layout/box_layout.h" | 23 #include "ui/views/layout/box_layout.h" |
18 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
19 | 25 |
20 namespace ash { | 26 namespace ash { |
21 namespace internal { | 27 namespace internal { |
22 | 28 |
23 class DefaultAccessibilityView : public ActionableView { | 29 namespace { |
| 30 const int kPaddingAroundBottomRow = 5; |
| 31 |
| 32 bool IsAnyAccessibilityFeatureEnabled() { |
| 33 ShellDelegate* shell_delegate = Shell::GetInstance()->delegate(); |
| 34 return shell_delegate && |
| 35 (shell_delegate->IsSpokenFeedbackEnabled() || |
| 36 shell_delegate->IsHighContrastEnabled() || |
| 37 shell_delegate->GetMagnifierType() != ash::MAGNIFIER_OFF); |
| 38 } |
| 39 |
| 40 user::LoginStatus GetCurrentLoginStatus() { |
| 41 return Shell::GetInstance()->tray_delegate()->GetUserLoginStatus(); |
| 42 } |
| 43 |
| 44 } // namespace |
| 45 |
| 46 namespace tray { |
| 47 |
| 48 class DefaultAccessibilityView : public TrayItemMore { |
24 public: | 49 public: |
25 DefaultAccessibilityView() { | 50 explicit DefaultAccessibilityView(SystemTrayItem* owner) |
26 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, | 51 : TrayItemMore(owner, true) { |
27 kTrayPopupPaddingHorizontal, | |
28 0, | |
29 kTrayPopupPaddingBetweenItems)); | |
30 | |
31 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 52 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
32 FixedSizedImageView* image = | 53 SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK). |
33 new FixedSizedImageView(0, kTrayPopupItemHeight); | |
34 image->SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK). | |
35 ToImageSkia()); | 54 ToImageSkia()); |
36 | |
37 AddChildView(image); | |
38 string16 label = bundle.GetLocalizedString( | 55 string16 label = bundle.GetLocalizedString( |
39 IDS_ASH_STATUS_TRAY_DISABLE_SPOKEN_FEEDBACK); | 56 IDS_ASH_STATUS_TRAY_ACCESSIBILITY); |
40 AddChildView(new views::Label(label)); | 57 SetLabel(label); |
41 SetAccessibleName(label); | 58 SetAccessibleName(label); |
42 } | 59 } |
43 | 60 |
44 virtual ~DefaultAccessibilityView() {} | 61 virtual ~DefaultAccessibilityView() { |
45 | |
46 protected: | |
47 // Overridden from ActionableView. | |
48 virtual bool PerformAction(const ui::Event& event) OVERRIDE { | |
49 if (Shell::GetInstance()->delegate()->IsSpokenFeedbackEnabled()) | |
50 Shell::GetInstance()->delegate()->ToggleSpokenFeedback(); | |
51 GetWidget()->Close(); | |
52 return true; | |
53 } | 62 } |
54 | 63 |
55 private: | 64 private: |
56 | |
57 DISALLOW_COPY_AND_ASSIGN(DefaultAccessibilityView); | 65 DISALLOW_COPY_AND_ASSIGN(DefaultAccessibilityView); |
58 }; | 66 }; |
59 | 67 |
| 68 class AccessibilityDetailedView : public TrayDetailsView, |
| 69 public ViewClickListener, |
| 70 public views::ButtonListener, |
| 71 public ShellObserver { |
| 72 public: |
| 73 explicit AccessibilityDetailedView(SystemTrayItem* owner, |
| 74 user::LoginStatus login) : |
| 75 TrayDetailsView(owner), |
| 76 spoken_feedback_view_(NULL), |
| 77 high_contrast_view_(NULL), |
| 78 screen_magnifier_view_(NULL), |
| 79 help_view_(NULL), |
| 80 login_(login) { |
| 81 |
| 82 Reset(); |
| 83 |
| 84 AppendAccessibilityList(); |
| 85 AppendHelpEntries(); |
| 86 CreateSpecialRow(IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TITLE, this); |
| 87 |
| 88 Layout(); |
| 89 } |
| 90 |
| 91 virtual ~AccessibilityDetailedView() { |
| 92 } |
| 93 |
| 94 private: |
| 95 // Add the accessibility feature list. |
| 96 void AppendAccessibilityList() { |
| 97 CreateScrollableList(); |
| 98 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| 99 |
| 100 ShellDelegate* shell_delegate = Shell::GetInstance()->delegate(); |
| 101 bool spoken_feedback_enabled = shell_delegate->IsSpokenFeedbackEnabled(); |
| 102 spoken_feedback_view_ = AddScrollListItem( |
| 103 bundle.GetLocalizedString( |
| 104 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SPOKEN_FEEDBACK), |
| 105 spoken_feedback_enabled ? gfx::Font::BOLD : gfx::Font::NORMAL, |
| 106 spoken_feedback_enabled); |
| 107 bool high_contrast_mode_enabled = shell_delegate->IsHighContrastEnabled(); |
| 108 high_contrast_view_ = AddScrollListItem( |
| 109 bundle.GetLocalizedString( |
| 110 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_HIGH_CONTRAST_MODE), |
| 111 high_contrast_mode_enabled ? gfx::Font::BOLD : gfx::Font::NORMAL, |
| 112 high_contrast_mode_enabled); |
| 113 bool screen_magnifier_enabled = |
| 114 shell_delegate->GetMagnifierType() == ash::MAGNIFIER_FULL; |
| 115 screen_magnifier_view_ = AddScrollListItem( |
| 116 bundle.GetLocalizedString( |
| 117 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_SCREEN_MAGNIFIER), |
| 118 screen_magnifier_enabled ? gfx::Font::BOLD : gfx::Font::NORMAL, |
| 119 screen_magnifier_enabled); |
| 120 } |
| 121 |
| 122 // Add help entries. |
| 123 void AppendHelpEntries() { |
| 124 // Currently the help page requires a browser window. |
| 125 // TODO(yoshiki): show this even on login/lock screen. crbug.com/158286 |
| 126 if (login_ == user::LOGGED_IN_NONE || |
| 127 login_ == user::LOGGED_IN_LOCKED) |
| 128 return; |
| 129 |
| 130 views::View* bottom_row = new View(); |
| 131 views::BoxLayout* layout = new |
| 132 views::BoxLayout(views::BoxLayout::kHorizontal, |
| 133 kTrayMenuBottomRowPadding, |
| 134 kTrayMenuBottomRowPadding, |
| 135 kTrayMenuBottomRowPaddingBetweenItems); |
| 136 layout->set_spread_blank_space(true); |
| 137 bottom_row->SetLayoutManager(layout); |
| 138 |
| 139 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| 140 |
| 141 TrayPopupLabelButton* help = new TrayPopupLabelButton( |
| 142 this, |
| 143 bundle.GetLocalizedString( |
| 144 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_LEARN_MORE)); |
| 145 bottom_row->AddChildView(help); |
| 146 help_view_ = help; |
| 147 |
| 148 // TODO(yoshiki): Add "Customize accessibility" button when the customize is |
| 149 // available. crbug.com/158281 |
| 150 |
| 151 AddChildView(bottom_row); |
| 152 } |
| 153 |
| 154 HoverHighlightView* AddScrollListItem(const string16& text, |
| 155 gfx::Font::FontStyle style, |
| 156 bool checked) { |
| 157 HoverHighlightView* container = new HoverHighlightView(this); |
| 158 container->set_fixed_height(kTrayPopupItemHeight); |
| 159 container->AddCheckableLabel(text, style, checked); |
| 160 scroll_content()->AddChildView(container); |
| 161 return container; |
| 162 } |
| 163 |
| 164 // Overridden from ViewClickListener. |
| 165 virtual void ClickedOn(views::View* sender) OVERRIDE { |
| 166 ShellDelegate* shell_delegate = Shell::GetInstance()->delegate(); |
| 167 if (sender == footer()->content()) { |
| 168 owner()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); |
| 169 } else if (sender == spoken_feedback_view_) { |
| 170 shell_delegate->ToggleSpokenFeedback(); |
| 171 } else if (sender == high_contrast_view_) { |
| 172 shell_delegate->ToggleHighContrast(); |
| 173 } else if (sender == screen_magnifier_view_) { |
| 174 bool screen_magnifier_enabled = |
| 175 shell_delegate->GetMagnifierType() == ash::MAGNIFIER_FULL; |
| 176 shell_delegate->SetMagnifier( |
| 177 screen_magnifier_enabled ? ash::MAGNIFIER_OFF : ash::MAGNIFIER_FULL); |
| 178 } |
| 179 } |
| 180 |
| 181 // Overridden from ButtonListener. |
| 182 virtual void ButtonPressed(views::Button* sender, |
| 183 const ui::Event& event) OVERRIDE { |
| 184 SystemTrayDelegate* tray_delegate = Shell::GetInstance()->tray_delegate(); |
| 185 if (sender == help_view_) |
| 186 tray_delegate->ShowAccessibilityHelp(); |
| 187 } |
| 188 |
| 189 views::View* spoken_feedback_view_; |
| 190 views::View* high_contrast_view_; |
| 191 views::View* screen_magnifier_view_;; |
| 192 views::View* help_view_; |
| 193 user::LoginStatus login_; |
| 194 |
| 195 DISALLOW_COPY_AND_ASSIGN(AccessibilityDetailedView); |
| 196 }; |
| 197 |
| 198 class AccessibilityPopupView : public TrayNotificationView { |
| 199 public: |
| 200 AccessibilityPopupView(SystemTrayItem* owner) |
| 201 : TrayNotificationView(owner, IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK) { |
| 202 InitView(GetLabel()); |
| 203 } |
| 204 |
| 205 private: |
| 206 views::Label* GetLabel() { |
| 207 views::Label* label = new views::Label( |
| 208 l10n_util::GetStringUTF16( |
| 209 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TURNED_ON_BUBBLE)); |
| 210 label->SetMultiLine(true); |
| 211 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 212 return label; |
| 213 } |
| 214 |
| 215 DISALLOW_COPY_AND_ASSIGN(AccessibilityPopupView); |
| 216 }; |
| 217 |
| 218 } // namespace tray |
| 219 |
| 220 |
60 TrayAccessibility::TrayAccessibility(SystemTray* system_tray) | 221 TrayAccessibility::TrayAccessibility(SystemTray* system_tray) |
61 : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_ACCESSIBILITY), | 222 : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_ACCESSIBILITY), |
62 default_(NULL), | 223 default_(NULL), |
63 detailed_(NULL) { | 224 detailed_(NULL), |
64 } | 225 request_popup_view_(false), |
65 | 226 accessibility_previously_enabled_(IsAnyAccessibilityFeatureEnabled()), |
66 TrayAccessibility::~TrayAccessibility() {} | 227 login_(GetCurrentLoginStatus()) { |
| 228 DCHECK(Shell::GetInstance()->delegate()); |
| 229 DCHECK(system_tray); |
| 230 |
| 231 Shell::GetInstance()->AddShellObserver(this); |
| 232 } |
| 233 |
| 234 TrayAccessibility::~TrayAccessibility() { |
| 235 Shell::GetInstance()->RemoveShellObserver(this); |
| 236 } |
67 | 237 |
68 bool TrayAccessibility::GetInitialVisibility() { | 238 bool TrayAccessibility::GetInitialVisibility() { |
69 return Shell::GetInstance()->delegate() && | 239 ShellDelegate* delegate = Shell::GetInstance()->delegate(); |
70 Shell::GetInstance()->delegate()->IsSpokenFeedbackEnabled(); | 240 // Always shows this on the login screen. |
| 241 if (login_ == user::LOGGED_IN_NONE) |
| 242 return true; |
| 243 |
| 244 if (delegate->ShouldAlwaysShowAccessibilityMenu() || |
| 245 IsAnyAccessibilityFeatureEnabled()) { |
| 246 return true; |
| 247 } |
| 248 |
| 249 return false; |
71 } | 250 } |
72 | 251 |
73 views::View* TrayAccessibility::CreateDefaultView(user::LoginStatus status) { | 252 views::View* TrayAccessibility::CreateDefaultView(user::LoginStatus status) { |
74 if (!Shell::GetInstance()->delegate()->IsSpokenFeedbackEnabled()) | 253 CHECK(default_ == NULL); |
| 254 |
| 255 login_ = status; |
| 256 |
| 257 if (!GetInitialVisibility()) |
75 return NULL; | 258 return NULL; |
76 | 259 |
77 CHECK(default_ == NULL); | 260 CHECK(default_ == NULL); |
78 default_ = new DefaultAccessibilityView(); | 261 default_ = new tray::DefaultAccessibilityView(this); |
79 | 262 |
80 return default_; | 263 return default_; |
81 } | 264 } |
82 | 265 |
83 views::View* TrayAccessibility::CreateDetailedView(user::LoginStatus status) { | 266 views::View* TrayAccessibility::CreateDetailedView(user::LoginStatus status) { |
84 CHECK(detailed_ == NULL); | 267 CHECK(detailed_ == NULL); |
85 detailed_ = new views::View; | 268 |
86 | 269 login_ = status; |
87 detailed_->SetLayoutManager(new | 270 |
88 views::BoxLayout(views::BoxLayout::kHorizontal, | 271 if (request_popup_view_) { |
89 kTrayPopupPaddingHorizontal, 10, kTrayPopupPaddingBetweenItems)); | 272 detailed_ = new tray::AccessibilityPopupView(this); |
90 | 273 request_popup_view_ = false; |
91 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); | 274 } else { |
92 views::ImageView* image = new views::ImageView; | 275 detailed_ = new tray::AccessibilityDetailedView(this, status); |
93 image->SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK). | 276 } |
94 ToImageSkia()); | |
95 | |
96 detailed_->AddChildView(image); | |
97 detailed_->AddChildView(new views::Label(bundle.GetLocalizedString( | |
98 IDS_ASH_STATUS_TRAY_ACCESSIBILITY_TURNED_ON_BUBBLE))); | |
99 | 277 |
100 return detailed_; | 278 return detailed_; |
101 } | 279 } |
102 | 280 |
103 void TrayAccessibility::DestroyDefaultView() { | 281 void TrayAccessibility::DestroyDefaultView() { |
104 default_ = NULL; | 282 default_ = NULL; |
105 } | 283 } |
106 | 284 |
107 void TrayAccessibility::DestroyDetailedView() { | 285 void TrayAccessibility::DestroyDetailedView() { |
108 detailed_ = NULL; | 286 detailed_ = NULL; |
109 } | 287 } |
110 | 288 |
111 void TrayAccessibility::OnAccessibilityModeChanged(bool enabled) { | 289 void TrayAccessibility::OnLoginStateChanged(user::LoginStatus status) { |
| 290 login_ = status; |
| 291 |
112 if (tray_view()) | 292 if (tray_view()) |
113 tray_view()->SetVisible(enabled); | 293 tray_view()->SetVisible(GetInitialVisibility()); |
| 294 } |
114 | 295 |
115 if (enabled) { | 296 void TrayAccessibility::OnAccessibilityModeChanged() { |
| 297 if (tray_view()) |
| 298 tray_view()->SetVisible(GetInitialVisibility()); |
| 299 |
| 300 bool accessibility_enabled = IsAnyAccessibilityFeatureEnabled(); |
| 301 if (!accessibility_previously_enabled_ && accessibility_enabled && |
| 302 login_ != user::LOGGED_IN_NONE) { |
| 303 // Shows popup if the accessibilty status is being changed to true from |
| 304 // false. |
| 305 request_popup_view_ = true; |
116 PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false); | 306 PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds, false); |
117 } else if (detailed_) { | 307 } else if (detailed_) { |
118 detailed_->GetWidget()->Close(); | 308 detailed_->GetWidget()->Close(); |
119 } | 309 } |
| 310 |
| 311 accessibility_previously_enabled_ = accessibility_enabled; |
120 } | 312 } |
121 | 313 |
122 } // namespace internal | 314 } // namespace internal |
123 } // namespace ash | 315 } // namespace ash |
OLD | NEW |