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/ime/tray_ime.h"
9 #include "ash/metrics/user_metrics_recorder.h"
10 #include "ash/root_window_controller.h"
11 #include "ash/shelf/shelf_widget.h"
12 #include "ash/shell.h"
13 #include "ash/system/tray/hover_highlight_view.h"
14 #include "ash/system/tray/system_tray.h"
15 #include "ash/system/tray/system_tray_delegate.h"
16 #include "ash/system/tray/system_tray_notifier.h"
17 #include "ash/system/tray/tray_constants.h"
18 #include "ash/system/tray/tray_details_view.h"
19 #include "ash/system/tray/tray_item_more.h"
20 #include "ash/system/tray/tray_item_view.h"
21 #include "ash/system/tray/tray_utils.h"
22 #include "base/logging.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "grit/ash_resources.h"
25 #include "grit/ash_strings.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/font.h"
29 #include "ui/gfx/image/image.h"
30 #include "ui/views/controls/label.h"
31 #include "ui/views/layout/box_layout.h"
32 #include "ui/views/widget/widget.h"
38 class IMEDefaultView : public TrayItemMore {
40 explicit IMEDefaultView(SystemTrayItem* owner)
41 : TrayItemMore(owner, true) {
42 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
44 SetImage(bundle.GetImageNamed(
45 IDR_AURA_UBER_TRAY_IME).ToImageSkia());
48 Shell::GetInstance()->system_tray_delegate()->GetCurrentIME(&info);
52 virtual ~IMEDefaultView() {}
54 void UpdateLabel(const IMEInfo& info) {
56 SetAccessibleName(info.name);
60 DISALLOW_COPY_AND_ASSIGN(IMEDefaultView);
63 class IMEDetailedView : public TrayDetailsView,
64 public ViewClickListener {
66 IMEDetailedView(SystemTrayItem* owner, user::LoginStatus login)
67 : TrayDetailsView(owner),
69 SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
71 delegate->GetAvailableIMEList(&list);
72 IMEPropertyInfoList property_list;
73 delegate->GetCurrentIMEProperties(&property_list);
74 Update(list, property_list);
77 virtual ~IMEDetailedView() {}
79 void Update(const IMEInfoList& list,
80 const IMEPropertyInfoList& property_list) {
84 if (!property_list.empty())
85 AppendIMEProperties(property_list);
86 if (login_ != user::LOGGED_IN_NONE && login_ != user::LOGGED_IN_LOCKED)
95 void AppendHeaderEntry() {
96 CreateSpecialRow(IDS_ASH_STATUS_TRAY_IME, this);
99 void AppendIMEList(const IMEInfoList& list) {
101 CreateScrollableList();
102 for (size_t i = 0; i < list.size(); i++) {
103 HoverHighlightView* container = new HoverHighlightView(this);
104 container->AddLabel(list[i].name,
105 list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
106 scroll_content()->AddChildView(container);
107 ime_map_[container] = list[i].id;
111 void AppendIMEProperties(const IMEPropertyInfoList& property_list) {
112 property_map_.clear();
113 for (size_t i = 0; i < property_list.size(); i++) {
114 HoverHighlightView* container = new HoverHighlightView(this);
116 property_list[i].name,
117 property_list[i].selected ? gfx::Font::BOLD : gfx::Font::NORMAL);
119 container->SetBorder(views::Border::CreateSolidSidedBorder(
120 1, 0, 0, 0, kBorderLightColor));
121 scroll_content()->AddChildView(container);
122 property_map_[container] = property_list[i].key;
126 void AppendSettings() {
127 HoverHighlightView* container = new HoverHighlightView(this);
128 container->AddLabel(ui::ResourceBundle::GetSharedInstance().
129 GetLocalizedString(IDS_ASH_STATUS_TRAY_IME_SETTINGS),
131 AddChildView(container);
132 settings_ = container;
135 // Overridden from ViewClickListener.
136 virtual void OnViewClicked(views::View* sender) OVERRIDE {
137 SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
138 if (sender == footer()->content()) {
139 TransitionToDefaultView();
140 } else if (sender == settings_) {
141 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
142 ash::UMA_STATUS_AREA_IME_SHOW_DETAILED);
143 delegate->ShowIMESettings();
145 std::map<views::View*, std::string>::const_iterator ime_find;
146 ime_find = ime_map_.find(sender);
147 if (ime_find != ime_map_.end()) {
148 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
149 ash::UMA_STATUS_AREA_IME_SWITCH_MODE);
150 std::string ime_id = ime_find->second;
151 delegate->SwitchIME(ime_id);
152 GetWidget()->Close();
154 std::map<views::View*, std::string>::const_iterator prop_find;
155 prop_find = property_map_.find(sender);
156 if (prop_find != property_map_.end()) {
157 const std::string key = prop_find->second;
158 delegate->ActivateIMEProperty(key);
159 GetWidget()->Close();
165 user::LoginStatus login_;
167 std::map<views::View*, std::string> ime_map_;
168 std::map<views::View*, std::string> property_map_;
169 views::View* settings_;
171 DISALLOW_COPY_AND_ASSIGN(IMEDetailedView);
176 TrayIME::TrayIME(SystemTray* system_tray)
177 : SystemTrayItem(system_tray),
181 Shell::GetInstance()->system_tray_notifier()->AddIMEObserver(this);
184 TrayIME::~TrayIME() {
185 Shell::GetInstance()->system_tray_notifier()->RemoveIMEObserver(this);
188 void TrayIME::UpdateTrayLabel(const IMEInfo& current, size_t count) {
190 bool visible = count > 1;
191 tray_label_->SetVisible(visible);
192 // Do not change label before hiding because this change is noticeable.
195 if (current.third_party) {
196 tray_label_->label()->SetText(
197 current.short_name + base::UTF8ToUTF16("*"));
199 tray_label_->label()->SetText(current.short_name);
201 SetTrayLabelItemBorder(tray_label_, system_tray()->shelf_alignment());
202 tray_label_->Layout();
206 views::View* TrayIME::CreateTrayView(user::LoginStatus status) {
207 CHECK(tray_label_ == NULL);
208 tray_label_ = new TrayItemView(this);
209 tray_label_->CreateLabel();
210 SetupLabelForTray(tray_label_->label());
211 // Hide IME tray when it is created, it will be updated when it is notified
212 // for IME refresh event.
213 tray_label_->SetVisible(false);
217 views::View* TrayIME::CreateDefaultView(user::LoginStatus status) {
218 SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
220 IMEPropertyInfoList property_list;
221 delegate->GetAvailableIMEList(&list);
222 delegate->GetCurrentIMEProperties(&property_list);
223 if (list.size() <= 1 && property_list.size() <= 1)
225 CHECK(default_ == NULL);
226 default_ = new tray::IMEDefaultView(this);
230 views::View* TrayIME::CreateDetailedView(user::LoginStatus status) {
231 CHECK(detailed_ == NULL);
232 detailed_ = new tray::IMEDetailedView(this, status);
236 void TrayIME::DestroyTrayView() {
240 void TrayIME::DestroyDefaultView() {
244 void TrayIME::DestroyDetailedView() {
248 void TrayIME::UpdateAfterLoginStatusChange(user::LoginStatus status) {
251 void TrayIME::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
252 SetTrayLabelItemBorder(tray_label_, alignment);
253 tray_label_->Layout();
256 void TrayIME::OnIMERefresh() {
257 SystemTrayDelegate* delegate = Shell::GetInstance()->system_tray_delegate();
260 IMEPropertyInfoList property_list;
261 delegate->GetCurrentIME(¤t);
262 delegate->GetAvailableIMEList(&list);
263 delegate->GetCurrentIMEProperties(&property_list);
265 UpdateTrayLabel(current, list.size());
268 default_->UpdateLabel(current);
270 detailed_->Update(list, property_list);
273 } // namespace internal