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/tray_caps_lock.h"
7 #include "ash/caps_lock_delegate.h"
8 #include "ash/metrics/user_metrics_recorder.h"
10 #include "ash/system/tray/actionable_view.h"
11 #include "ash/system/tray/fixed_sized_image_view.h"
12 #include "ash/system/tray/system_tray_notifier.h"
13 #include "ash/system/tray/tray_constants.h"
14 #include "grit/ash_resources.h"
15 #include "grit/ash_strings.h"
16 #include "ui/base/accessibility/accessible_view_state.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/image/image.h"
19 #include "ui/views/controls/image_view.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/box_layout.h"
22 #include "ui/views/widget/widget.h"
27 class CapsLockDefaultView
: public ActionableView
{
30 : text_label_(new views::Label
),
31 shortcut_label_(new views::Label
) {
32 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal
,
33 kTrayPopupPaddingHorizontal
,
35 kTrayPopupPaddingBetweenItems
));
37 ui::ResourceBundle
& bundle
= ui::ResourceBundle::GetSharedInstance();
38 FixedSizedImageView
* image
=
39 new FixedSizedImageView(0, kTrayPopupItemHeight
);
40 image
->SetImage(bundle
.GetImageNamed(IDR_AURA_UBER_TRAY_CAPS_LOCK_DARK
).
44 text_label_
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
45 AddChildView(text_label_
);
47 shortcut_label_
->SetEnabled(false);
48 AddChildView(shortcut_label_
);
51 virtual ~CapsLockDefaultView() {}
53 // Updates the label text and the shortcut text.
54 void Update(bool caps_lock_enabled
, bool search_mapped_to_caps_lock
) {
55 ui::ResourceBundle
& bundle
= ui::ResourceBundle::GetSharedInstance();
56 const int text_string_id
= caps_lock_enabled
?
57 IDS_ASH_STATUS_TRAY_CAPS_LOCK_ENABLED
:
58 IDS_ASH_STATUS_TRAY_CAPS_LOCK_DISABLED
;
59 text_label_
->SetText(bundle
.GetLocalizedString(text_string_id
));
61 int shortcut_string_id
= 0;
62 if (caps_lock_enabled
) {
63 shortcut_string_id
= search_mapped_to_caps_lock
?
64 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH_OR_SHIFT
:
65 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH_OR_SHIFT
;
67 shortcut_string_id
= search_mapped_to_caps_lock
?
68 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH
:
69 IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH
;
71 shortcut_label_
->SetText(bundle
.GetLocalizedString(shortcut_string_id
));
77 // Overridden from views::View:
78 virtual void Layout() OVERRIDE
{
79 views::View::Layout();
81 // Align the shortcut text with the right end
82 const int old_x
= shortcut_label_
->x();
84 width() - shortcut_label_
->width() - kTrayPopupPaddingHorizontal
;
85 shortcut_label_
->SetX(new_x
);
86 const gfx::Size text_size
= text_label_
->size();
87 text_label_
->SetSize(gfx::Size(text_size
.width() + new_x
- old_x
,
91 virtual void GetAccessibleState(ui::AccessibleViewState
* state
) OVERRIDE
{
92 state
->role
= ui::AccessibilityTypes::ROLE_PUSHBUTTON
;
93 state
->name
= text_label_
->text();
96 // Overridden from ActionableView:
97 virtual bool PerformAction(const ui::Event
& event
) OVERRIDE
{
98 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
99 Shell::GetInstance()->caps_lock_delegate()->IsCapsLockEnabled() ?
100 ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK
:
101 ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK
);
102 Shell::GetInstance()->caps_lock_delegate()->ToggleCapsLock();
106 views::Label
* text_label_
;
107 views::Label
* shortcut_label_
;
109 DISALLOW_COPY_AND_ASSIGN(CapsLockDefaultView
);
112 TrayCapsLock::TrayCapsLock(SystemTray
* system_tray
)
113 : TrayImageItem(system_tray
, IDR_AURA_UBER_TRAY_CAPS_LOCK
),
116 search_mapped_to_caps_lock_(false),
118 Shell::GetInstance()->caps_lock_delegate()->IsCapsLockEnabled()),
119 message_shown_(false) {
120 Shell::GetInstance()->system_tray_notifier()->AddCapsLockObserver(this);
123 TrayCapsLock::~TrayCapsLock() {
124 Shell::GetInstance()->system_tray_notifier()->RemoveCapsLockObserver(this);
127 bool TrayCapsLock::GetInitialVisibility() {
128 return Shell::GetInstance()->caps_lock_delegate()->IsCapsLockEnabled();
131 views::View
* TrayCapsLock::CreateDefaultView(user::LoginStatus status
) {
132 if (!caps_lock_enabled_
)
134 DCHECK(default_
== NULL
);
135 default_
= new CapsLockDefaultView
;
136 default_
->Update(caps_lock_enabled_
, search_mapped_to_caps_lock_
);
140 views::View
* TrayCapsLock::CreateDetailedView(user::LoginStatus status
) {
141 DCHECK(detailed_
== NULL
);
142 detailed_
= new views::View
;
144 detailed_
->SetLayoutManager(new
145 views::BoxLayout(views::BoxLayout::kHorizontal
,
146 kTrayPopupPaddingHorizontal
, 10, kTrayPopupPaddingBetweenItems
));
148 ui::ResourceBundle
& bundle
= ui::ResourceBundle::GetSharedInstance();
149 views::ImageView
* image
= new views::ImageView
;
150 image
->SetImage(bundle
.GetImageNamed(IDR_AURA_UBER_TRAY_CAPS_LOCK_DARK
).
153 detailed_
->AddChildView(image
);
155 const int string_id
= search_mapped_to_caps_lock_
?
156 IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_SEARCH
:
157 IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_ALT_SEARCH
;
158 views::Label
* label
= new views::Label(bundle
.GetLocalizedString(string_id
));
159 label
->SetMultiLine(true);
160 label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
161 detailed_
->AddChildView(label
);
162 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
163 ash::UMA_STATUS_AREA_CAPS_LOCK_DETAILED
);
168 void TrayCapsLock::DestroyDefaultView() {
172 void TrayCapsLock::DestroyDetailedView() {
176 void TrayCapsLock::OnCapsLockChanged(bool enabled
,
177 bool search_mapped_to_caps_lock
) {
179 tray_view()->SetVisible(enabled
);
181 caps_lock_enabled_
= enabled
;
182 search_mapped_to_caps_lock_
= search_mapped_to_caps_lock
;
185 default_
->Update(enabled
, search_mapped_to_caps_lock
);
188 if (!message_shown_
) {
189 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
190 ash::UMA_STATUS_AREA_CAPS_LOCK_POPUP
);
191 PopupDetailedView(kTrayPopupAutoCloseDelayForTextInSeconds
, false);
192 message_shown_
= true;
194 } else if (detailed_
) {
195 detailed_
->GetWidget()->Close();
200 } // namespace internal