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
3 // found in the LICENSE file.
5 #include "ash/system/chromeos/tray_caps_lock.h"
7 #include "ash/metrics/user_metrics_recorder.h"
9 #include "ash/system/tray/actionable_view.h"
10 #include "ash/system/tray/fixed_sized_image_view.h"
11 #include "ash/system/tray/system_tray_delegate.h"
12 #include "ash/system/tray/system_tray_notifier.h"
13 #include "ash/system/tray/tray_constants.h"
14 #include "base/sys_info.h"
15 #include "chromeos/ime/ime_keyboard.h"
16 #include "chromeos/ime/input_method_manager.h"
17 #include "grit/ash_resources.h"
18 #include "grit/ash_strings.h"
19 #include "ui/accessibility/ax_view_state.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/image/image.h"
22 #include "ui/views/controls/image_view.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/layout/box_layout.h"
25 #include "ui/views/widget/widget.h"
30 bool CapsLockIsEnabled() {
31 chromeos::input_method::InputMethodManager
* ime
=
32 chromeos::input_method::InputMethodManager::Get();
33 return (ime
&& ime
->GetImeKeyboard())
34 ? ime
->GetImeKeyboard()->CapsLockIsEnabled()
40 class CapsLockDefaultView
: public ActionableView
{
43 : text_label_(new views::Label
),
44 shortcut_label_(new views::Label
) {
45 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal
,
46 kTrayPopupPaddingHorizontal
,
48 kTrayPopupPaddingBetweenItems
));
50 ui::ResourceBundle
& bundle
= ui::ResourceBundle::GetSharedInstance();
51 FixedSizedImageView
* image
=
52 new FixedSizedImageView(0, kTrayPopupItemHeight
);
53 image
->SetImage(bundle
.GetImageNamed(IDR_AURA_UBER_TRAY_CAPS_LOCK_DARK
).
57 text_label_
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
58 AddChildView(text_label_
);
60 shortcut_label_
->SetEnabled(false);
61 AddChildView(shortcut_label_
);
64 virtual ~CapsLockDefaultView() {}
66 // Updates the label text and the shortcut text.
67 void Update(bool caps_lock_enabled
) {
68 ui::ResourceBundle
& bundle
= ui::ResourceBundle::GetSharedInstance();
69 const int text_string_id
= caps_lock_enabled
?
70 IDS_ASH_STATUS_TRAY_CAPS_LOCK_ENABLED
:
71 IDS_ASH_STATUS_TRAY_CAPS_LOCK_DISABLED
;
72 text_label_
->SetText(bundle
.GetLocalizedString(text_string_id
));
74 int shortcut_string_id
= 0;
75 bool search_mapped_to_caps_lock
= Shell::GetInstance()->
76 system_tray_delegate()->IsSearchKeyMappedToCapsLock();
77 if (caps_lock_enabled
) {
78 shortcut_string_id
= search_mapped_to_caps_lock
?
79 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH_OR_SHIFT
:
80 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH_OR_SHIFT
;
82 shortcut_string_id
= search_mapped_to_caps_lock
?
83 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH
:
84 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH
;
86 shortcut_label_
->SetText(bundle
.GetLocalizedString(shortcut_string_id
));
92 // Overridden from views::View:
93 virtual void Layout() override
{
94 views::View::Layout();
96 // Align the shortcut text with the right end
97 const int old_x
= shortcut_label_
->x();
99 width() - shortcut_label_
->width() - kTrayPopupPaddingHorizontal
;
100 shortcut_label_
->SetX(new_x
);
101 const gfx::Size text_size
= text_label_
->size();
102 text_label_
->SetSize(gfx::Size(text_size
.width() + new_x
- old_x
,
103 text_size
.height()));
106 virtual void GetAccessibleState(ui::AXViewState
* state
) override
{
107 state
->role
= ui::AX_ROLE_BUTTON
;
108 state
->name
= text_label_
->text();
111 // Overridden from ActionableView:
112 virtual bool PerformAction(const ui::Event
& event
) override
{
113 chromeos::input_method::ImeKeyboard
* keyboard
=
114 chromeos::input_method::InputMethodManager::Get()->GetImeKeyboard();
116 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
117 keyboard
->CapsLockIsEnabled() ?
118 ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK
:
119 ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK
);
120 keyboard
->SetCapsLockEnabled(!keyboard
->CapsLockIsEnabled());
125 views::Label
* text_label_
;
126 views::Label
* shortcut_label_
;
128 DISALLOW_COPY_AND_ASSIGN(CapsLockDefaultView
);
131 TrayCapsLock::TrayCapsLock(SystemTray
* system_tray
)
132 : TrayImageItem(system_tray
, IDR_AURA_UBER_TRAY_CAPS_LOCK
),
135 caps_lock_enabled_(CapsLockIsEnabled()),
136 message_shown_(false) {
137 chromeos::input_method::InputMethodManager
* ime
=
138 chromeos::input_method::InputMethodManager::Get();
139 if (ime
&& ime
->GetImeKeyboard())
140 ime
->GetImeKeyboard()->AddObserver(this);
143 TrayCapsLock::~TrayCapsLock() {
144 chromeos::input_method::InputMethodManager
* ime
=
145 chromeos::input_method::InputMethodManager::Get();
146 if (ime
&& ime
->GetImeKeyboard())
147 ime
->GetImeKeyboard()->RemoveObserver(this);
150 void TrayCapsLock::OnCapsLockChanged(bool enabled
) {
151 caps_lock_enabled_
= enabled
;
154 tray_view()->SetVisible(caps_lock_enabled_
);
157 default_
->Update(caps_lock_enabled_
);
159 if (caps_lock_enabled_
) {
160 if (!message_shown_
) {
161 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
162 ash::UMA_STATUS_AREA_CAPS_LOCK_POPUP
);
163 PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds
, false);
164 message_shown_
= true;
166 } else if (detailed_
) {
167 detailed_
->GetWidget()->Close();
172 bool TrayCapsLock::GetInitialVisibility() {
173 return CapsLockIsEnabled();
176 views::View
* TrayCapsLock::CreateDefaultView(user::LoginStatus status
) {
177 if (!caps_lock_enabled_
)
179 DCHECK(default_
== NULL
);
180 default_
= new CapsLockDefaultView
;
181 default_
->Update(caps_lock_enabled_
);
185 views::View
* TrayCapsLock::CreateDetailedView(user::LoginStatus status
) {
186 DCHECK(detailed_
== NULL
);
187 detailed_
= new views::View
;
189 detailed_
->SetLayoutManager(new
190 views::BoxLayout(views::BoxLayout::kHorizontal
,
191 kTrayPopupPaddingHorizontal
, 10, kTrayPopupPaddingBetweenItems
));
193 ui::ResourceBundle
& bundle
= ui::ResourceBundle::GetSharedInstance();
194 views::ImageView
* image
= new views::ImageView
;
195 image
->SetImage(bundle
.GetImageNamed(IDR_AURA_UBER_TRAY_CAPS_LOCK_DARK
).
198 detailed_
->AddChildView(image
);
200 const int string_id
= Shell::GetInstance()->system_tray_delegate()->
201 IsSearchKeyMappedToCapsLock() ?
202 IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_SEARCH
:
203 IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_ALT_SEARCH
;
204 views::Label
* label
= new views::Label(bundle
.GetLocalizedString(string_id
));
205 label
->SetMultiLine(true);
206 label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
207 detailed_
->AddChildView(label
);
208 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
209 ash::UMA_STATUS_AREA_CAPS_LOCK_DETAILED
);
214 void TrayCapsLock::DestroyDefaultView() {
218 void TrayCapsLock::DestroyDetailedView() {