OLD | NEW |
| (Empty) |
1 // Copyright 2016 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. | |
4 | |
5 #include "ash/common/system/chromeos/ime_menu/ime_menu_tray.h" | |
6 | |
7 #include "ash/common/accessibility_delegate.h" | |
8 #include "ash/common/ash_constants.h" | |
9 #include "ash/common/material_design/material_design_controller.h" | |
10 #include "ash/common/session/session_state_delegate.h" | |
11 #include "ash/common/shelf/wm_shelf.h" | |
12 #include "ash/common/shelf/wm_shelf_util.h" | |
13 #include "ash/common/system/chromeos/ime_menu/ime_list_view.h" | |
14 #include "ash/common/system/tray/hover_highlight_view.h" | |
15 #include "ash/common/system/tray/system_menu_button.h" | |
16 #include "ash/common/system/tray/system_tray_controller.h" | |
17 #include "ash/common/system/tray/system_tray_delegate.h" | |
18 #include "ash/common/system/tray/system_tray_notifier.h" | |
19 #include "ash/common/system/tray/tray_constants.h" | |
20 #include "ash/common/system/tray/tray_popup_item_style.h" | |
21 #include "ash/common/system/tray/tray_popup_utils.h" | |
22 #include "ash/common/system/tray/tray_utils.h" | |
23 #include "ash/common/wm_shell.h" | |
24 #include "ash/common/wm_window.h" | |
25 #include "ash/public/cpp/shell_window_ids.h" | |
26 #include "ash/resources/grit/ash_resources.h" | |
27 #include "ash/root_window_controller.h" | |
28 #include "ash/strings/grit/ash_strings.h" | |
29 #include "base/metrics/histogram_macros.h" | |
30 #include "base/strings/utf_string_conversions.h" | |
31 #include "ui/base/ime/chromeos/input_method_manager.h" | |
32 #include "ui/base/ime/ime_bridge.h" | |
33 #include "ui/base/ime/text_input_client.h" | |
34 #include "ui/base/l10n/l10n_util.h" | |
35 #include "ui/base/resource/resource_bundle.h" | |
36 #include "ui/gfx/paint_vector_icon.h" | |
37 #include "ui/gfx/range/range.h" | |
38 #include "ui/gfx/vector_icons_public.h" | |
39 #include "ui/keyboard/keyboard_controller.h" | |
40 #include "ui/keyboard/keyboard_util.h" | |
41 #include "ui/views/controls/button/button.h" | |
42 #include "ui/views/controls/label.h" | |
43 #include "ui/views/controls/scroll_view.h" | |
44 #include "ui/views/controls/separator.h" | |
45 #include "ui/views/layout/box_layout.h" | |
46 | |
47 using chromeos::input_method::InputMethodManager; | |
48 | |
49 namespace ash { | |
50 | |
51 namespace { | |
52 // Returns the height range of ImeListView. | |
53 gfx::Range GetImeListViewRange() { | |
54 const int max_items = 5; | |
55 const int min_items = 1; | |
56 const int tray_item_height = kTrayPopupItemMinHeight; | |
57 return gfx::Range(tray_item_height * min_items, tray_item_height * max_items); | |
58 } | |
59 | |
60 // Returns the minimum with of IME menu. | |
61 int GetMinimumMenuWidth() { | |
62 return MaterialDesignController::IsSystemTrayMenuMaterial() | |
63 ? kTrayMenuMinimumWidthMd | |
64 : kTrayMenuMinimumWidth; | |
65 } | |
66 | |
67 // Shows language and input settings page. | |
68 void ShowIMESettings() { | |
69 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_IME_SHOW_DETAILED); | |
70 WmShell::Get()->system_tray_controller()->ShowIMESettings(); | |
71 } | |
72 | |
73 // Records the number of times users click buttons in opt-in IME menu. | |
74 void RecordButtonsClicked(const std::string& button_name) { | |
75 enum { | |
76 UNKNOWN = 0, | |
77 EMOJI = 1, | |
78 HANDWRITING = 2, | |
79 VOICE = 3, | |
80 // SETTINGS is not used for now. | |
81 SETTINGS = 4, | |
82 BUTTON_MAX | |
83 } button = UNKNOWN; | |
84 if (button_name == "emoji") { | |
85 button = EMOJI; | |
86 } else if (button_name == "hwt") { | |
87 button = HANDWRITING; | |
88 } else if (button_name == "voice") { | |
89 button = VOICE; | |
90 } | |
91 UMA_HISTOGRAM_ENUMERATION("InputMethod.ImeMenu.EmojiHandwritingVoiceButton", | |
92 button, BUTTON_MAX); | |
93 } | |
94 | |
95 // Returns true if the current screen is login or lock screen. | |
96 bool IsInLoginOrLockScreen() { | |
97 LoginStatus login = | |
98 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus(); | |
99 return !TrayPopupUtils::CanOpenWebUISettings(login); | |
100 } | |
101 | |
102 // Returns true if the current input context type is password. | |
103 bool IsInPasswordInputContext() { | |
104 return ui::IMEBridge::Get()->GetCurrentInputContext().type == | |
105 ui::TEXT_INPUT_TYPE_PASSWORD; | |
106 } | |
107 | |
108 class ImeMenuLabel : public views::Label { | |
109 public: | |
110 ImeMenuLabel() {} | |
111 ~ImeMenuLabel() override {} | |
112 | |
113 // views:Label: | |
114 gfx::Size GetPreferredSize() const override { | |
115 return gfx::Size(kTrayItemSize, kTrayItemSize); | |
116 } | |
117 int GetHeightForWidth(int width) const override { return kTrayItemSize; } | |
118 | |
119 private: | |
120 DISALLOW_COPY_AND_ASSIGN(ImeMenuLabel); | |
121 }; | |
122 | |
123 SystemMenuButton* CreateImeMenuButton(views::ButtonListener* listener, | |
124 const gfx::VectorIcon& icon, | |
125 int accessible_name_id, | |
126 int right_border) { | |
127 SystemMenuButton* button = new SystemMenuButton( | |
128 listener, TrayPopupInkDropStyle::HOST_CENTERED, icon, accessible_name_id); | |
129 if (!MaterialDesignController::IsShelfMaterial()) { | |
130 button->SetBorder( | |
131 views::CreateSolidSidedBorder(0, 0, 0, right_border, kBorderDarkColor)); | |
132 } | |
133 return button; | |
134 } | |
135 | |
136 // The view that contains IME menu title in the material design. | |
137 class ImeTitleView : public views::View, public views::ButtonListener { | |
138 public: | |
139 explicit ImeTitleView(bool show_settings_button) : settings_button_(nullptr) { | |
140 SetBorder(views::CreatePaddedBorder( | |
141 views::CreateSolidSidedBorder(0, 0, kSeparatorWidth, 0, | |
142 kMenuSeparatorColor), | |
143 gfx::Insets(kMenuSeparatorVerticalPadding - kSeparatorWidth, 0))); | |
144 auto* box_layout = | |
145 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); | |
146 box_layout->set_minimum_cross_axis_size(kTrayPopupItemMinHeight); | |
147 SetLayoutManager(box_layout); | |
148 auto* title_label = | |
149 new views::Label(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME)); | |
150 title_label->SetBorder( | |
151 views::CreateEmptyBorder(0, kMenuEdgeEffectivePadding, 1, 0)); | |
152 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
153 TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::TITLE); | |
154 style.SetupLabel(title_label); | |
155 | |
156 AddChildView(title_label); | |
157 box_layout->SetFlexForView(title_label, 1); | |
158 | |
159 if (show_settings_button) { | |
160 settings_button_ = CreateImeMenuButton( | |
161 this, kSystemMenuSettingsIcon, IDS_ASH_STATUS_TRAY_IME_SETTINGS, 0); | |
162 if (IsInLoginOrLockScreen()) | |
163 settings_button_->SetEnabled(false); | |
164 AddChildView(settings_button_); | |
165 } | |
166 } | |
167 | |
168 // views::ButtonListener: | |
169 void ButtonPressed(views::Button* sender, const ui::Event& event) override { | |
170 DCHECK_EQ(sender, settings_button_); | |
171 ShowIMESettings(); | |
172 } | |
173 | |
174 ~ImeTitleView() override {} | |
175 | |
176 private: | |
177 // Settings button that is only used in material design, and only if the | |
178 // emoji, handwriting and voice buttons are not available. | |
179 SystemMenuButton* settings_button_; | |
180 | |
181 DISALLOW_COPY_AND_ASSIGN(ImeTitleView); | |
182 }; | |
183 | |
184 // The view that contains buttons shown on the bottom of IME menu. | |
185 class ImeButtonsView : public views::View, | |
186 public views::ButtonListener, | |
187 public ViewClickListener { | |
188 public: | |
189 ImeButtonsView(ImeMenuTray* ime_menu_tray, | |
190 bool show_emoji_button, | |
191 bool show_voice_button, | |
192 bool show_handwriting_button, | |
193 bool show_settings_button) | |
194 : ime_menu_tray_(ime_menu_tray) { | |
195 DCHECK(ime_menu_tray_); | |
196 | |
197 if (!MaterialDesignController::IsSystemTrayMenuMaterial()) | |
198 SetBorder(views::CreateSolidSidedBorder(1, 0, 0, 0, kBorderDarkColor)); | |
199 | |
200 // If there's only one settings button, the bottom should be a label with | |
201 // normal background. Otherwise, show button icons with header background. | |
202 if (show_settings_button && !show_emoji_button && | |
203 !show_handwriting_button && !show_voice_button) { | |
204 DCHECK(!MaterialDesignController::IsSystemTrayMenuMaterial()); | |
205 ShowOneSettingButton(); | |
206 } else { | |
207 ShowButtons(show_emoji_button, show_handwriting_button, show_voice_button, | |
208 show_settings_button); | |
209 } | |
210 } | |
211 | |
212 ~ImeButtonsView() override {} | |
213 | |
214 // views::ButtonListener: | |
215 void ButtonPressed(views::Button* sender, const ui::Event& event) override { | |
216 if (sender == settings_button_) { | |
217 ime_menu_tray_->HideImeMenuBubble(); | |
218 ShowIMESettings(); | |
219 return; | |
220 } | |
221 | |
222 // The |keyset| will be used for drawing input view keyset in IME | |
223 // extensions. InputMethodManager::ShowKeyboardWithKeyset() will deal with | |
224 // the |keyset| string to generate the right input view url. | |
225 std::string keyset; | |
226 if (sender == emoji_button_) { | |
227 keyset = "emoji"; | |
228 RecordButtonsClicked(keyset); | |
229 } else if (sender == voice_button_) { | |
230 keyset = "voice"; | |
231 RecordButtonsClicked(keyset); | |
232 } else if (sender == handwriting_button_) { | |
233 keyset = "hwt"; | |
234 RecordButtonsClicked(keyset); | |
235 } else { | |
236 NOTREACHED(); | |
237 } | |
238 | |
239 ime_menu_tray_->ShowKeyboardWithKeyset(keyset); | |
240 } | |
241 | |
242 // ViewClickListener: | |
243 void OnViewClicked(views::View* sender) override { | |
244 if (one_settings_button_view_ && sender == one_settings_button_view_) { | |
245 ime_menu_tray_->HideImeMenuBubble(); | |
246 ShowIMESettings(); | |
247 } | |
248 } | |
249 | |
250 private: | |
251 // Shows the UI of one settings button. | |
252 void ShowOneSettingButton() { | |
253 auto* box_layout = | |
254 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); | |
255 box_layout->SetDefaultFlex(1); | |
256 SetLayoutManager(box_layout); | |
257 one_settings_button_view_ = new HoverHighlightView(this); | |
258 one_settings_button_view_->AddLabel( | |
259 ui::ResourceBundle::GetSharedInstance().GetLocalizedString( | |
260 IDS_ASH_STATUS_TRAY_IME_SETTINGS), | |
261 gfx::ALIGN_LEFT, false /* highlight */); | |
262 if (IsInLoginOrLockScreen()) | |
263 one_settings_button_view_->SetEnabled(false); | |
264 AddChildView(one_settings_button_view_); | |
265 } | |
266 | |
267 // Shows the UI of more than one buttons. | |
268 void ShowButtons(bool show_emoji_button, | |
269 bool show_handwriting_button, | |
270 bool show_voice_button, | |
271 bool show_settings_button) { | |
272 if (MaterialDesignController::IsSystemTrayMenuMaterial()) { | |
273 auto* box_layout = | |
274 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); | |
275 box_layout->set_minimum_cross_axis_size(kTrayPopupItemMinHeight); | |
276 SetLayoutManager(box_layout); | |
277 SetBorder(views::CreatePaddedBorder( | |
278 views::CreateSolidSidedBorder(kSeparatorWidth, 0, 0, 0, | |
279 kMenuSeparatorColor), | |
280 gfx::Insets(kMenuSeparatorVerticalPadding - kSeparatorWidth, | |
281 kMenuExtraMarginFromLeftEdge))); | |
282 } else { | |
283 auto* box_layout = | |
284 new views::BoxLayout(views::BoxLayout::kHorizontal, 4, 4, 0); | |
285 set_background( | |
286 views::Background::CreateSolidBackground(kHeaderBackgroundColor)); | |
287 box_layout->SetDefaultFlex(1); | |
288 SetLayoutManager(box_layout); | |
289 } | |
290 | |
291 const int right_border = 1; | |
292 if (show_emoji_button) { | |
293 emoji_button_ = | |
294 CreateImeMenuButton(this, kImeMenuEmoticonIcon, | |
295 IDS_ASH_STATUS_TRAY_IME_EMOJI, right_border); | |
296 AddChildView(emoji_button_); | |
297 } | |
298 | |
299 if (show_handwriting_button) { | |
300 handwriting_button_ = CreateImeMenuButton( | |
301 this, kImeMenuWriteIcon, IDS_ASH_STATUS_TRAY_IME_HANDWRITING, | |
302 right_border); | |
303 AddChildView(handwriting_button_); | |
304 } | |
305 | |
306 if (show_voice_button) { | |
307 voice_button_ = | |
308 CreateImeMenuButton(this, kImeMenuMicrophoneIcon, | |
309 IDS_ASH_STATUS_TRAY_IME_VOICE, right_border); | |
310 AddChildView(voice_button_); | |
311 } | |
312 | |
313 if (show_settings_button) { | |
314 settings_button_ = CreateImeMenuButton( | |
315 this, kSystemMenuSettingsIcon, IDS_ASH_STATUS_TRAY_IME_SETTINGS, 0); | |
316 AddChildView(settings_button_); | |
317 } | |
318 } | |
319 | |
320 ImeMenuTray* ime_menu_tray_; | |
321 SystemMenuButton* emoji_button_; | |
322 SystemMenuButton* handwriting_button_; | |
323 SystemMenuButton* voice_button_; | |
324 SystemMenuButton* settings_button_; | |
325 HoverHighlightView* one_settings_button_view_; | |
326 | |
327 DISALLOW_COPY_AND_ASSIGN(ImeButtonsView); | |
328 }; | |
329 | |
330 // The list view that contains the selected IME and property items. | |
331 class ImeMenuListView : public ImeListView { | |
332 public: | |
333 ImeMenuListView(SystemTrayItem* owner) : ImeListView(owner) { | |
334 set_should_focus_ime_after_selection_with_keyboard(true); | |
335 } | |
336 | |
337 ~ImeMenuListView() override {} | |
338 | |
339 protected: | |
340 void Layout() override { | |
341 gfx::Range height_range = GetImeListViewRange(); | |
342 scroller()->ClipHeightTo(height_range.start(), height_range.end()); | |
343 ImeListView::Layout(); | |
344 } | |
345 | |
346 DISALLOW_COPY_AND_ASSIGN(ImeMenuListView); | |
347 }; | |
348 | |
349 } // namespace | |
350 | |
351 ImeMenuTray::ImeMenuTray(WmShelf* wm_shelf) | |
352 : TrayBackgroundView(wm_shelf), | |
353 label_(new ImeMenuLabel()), | |
354 show_keyboard_(false), | |
355 force_show_keyboard_(false), | |
356 should_block_shelf_auto_hide_(false), | |
357 keyboard_suppressed_(false), | |
358 show_bubble_after_keyboard_hidden_(false) { | |
359 if (MaterialDesignController::IsShelfMaterial()) { | |
360 SetInkDropMode(InkDropMode::ON); | |
361 SetContentsBackground(false); | |
362 } else { | |
363 SetContentsBackground(true); | |
364 } | |
365 SetupLabelForTray(label_); | |
366 tray_container()->AddChildView(label_); | |
367 SystemTrayNotifier* tray_notifier = WmShell::Get()->system_tray_notifier(); | |
368 tray_notifier->AddIMEObserver(this); | |
369 tray_notifier->AddVirtualKeyboardObserver(this); | |
370 } | |
371 | |
372 ImeMenuTray::~ImeMenuTray() { | |
373 if (bubble_) | |
374 bubble_->bubble_view()->reset_delegate(); | |
375 SystemTrayNotifier* tray_notifier = WmShell::Get()->system_tray_notifier(); | |
376 tray_notifier->RemoveIMEObserver(this); | |
377 tray_notifier->RemoveVirtualKeyboardObserver(this); | |
378 keyboard::KeyboardController* keyboard_controller = | |
379 keyboard::KeyboardController::GetInstance(); | |
380 if (keyboard_controller) | |
381 keyboard_controller->RemoveObserver(this); | |
382 } | |
383 | |
384 void ImeMenuTray::ShowImeMenuBubble() { | |
385 keyboard::KeyboardController* keyboard_controller = | |
386 keyboard::KeyboardController::GetInstance(); | |
387 if (keyboard_controller && keyboard_controller->keyboard_visible()) { | |
388 show_bubble_after_keyboard_hidden_ = true; | |
389 keyboard_controller->AddObserver(this); | |
390 keyboard_controller->HideKeyboard( | |
391 keyboard::KeyboardController::HIDE_REASON_AUTOMATIC); | |
392 } else { | |
393 ShowImeMenuBubbleInternal(); | |
394 } | |
395 } | |
396 | |
397 void ImeMenuTray::ShowImeMenuBubbleInternal() { | |
398 int minimum_menu_width = GetMinimumMenuWidth(); | |
399 should_block_shelf_auto_hide_ = true; | |
400 views::TrayBubbleView::InitParams init_params( | |
401 GetAnchorAlignment(), minimum_menu_width, minimum_menu_width); | |
402 init_params.can_activate = true; | |
403 init_params.close_on_deactivate = true; | |
404 | |
405 views::TrayBubbleView* bubble_view = | |
406 views::TrayBubbleView::Create(GetBubbleAnchor(), this, &init_params); | |
407 bubble_view->set_anchor_view_insets(GetBubbleAnchorInsets()); | |
408 | |
409 // In the material design, we will add a title item with a separator on the | |
410 // top of the IME menu. | |
411 if (MaterialDesignController::IsSystemTrayMenuMaterial()) { | |
412 bubble_view->AddChildView( | |
413 new ImeTitleView(!ShouldShowEmojiHandwritingVoiceButtons())); | |
414 } else { | |
415 bubble_view->set_margins(gfx::Insets(7, 0, 0, 0)); | |
416 } | |
417 | |
418 // Adds IME list to the bubble. | |
419 ime_list_view_ = new ImeMenuListView(nullptr); | |
420 ime_list_view_->Init(ShouldShowKeyboardToggle(), | |
421 ImeListView::SHOW_SINGLE_IME); | |
422 bubble_view->AddChildView(ime_list_view_); | |
423 | |
424 if (ShouldShowEmojiHandwritingVoiceButtons()) { | |
425 bubble_view->AddChildView(new ImeButtonsView(this, true, true, true, true)); | |
426 } else if (!MaterialDesignController::IsSystemTrayMenuMaterial()) { | |
427 // For MD, we don't need |ImeButtonsView| as the settings button will be | |
428 // shown in the title row. | |
429 bubble_view->AddChildView( | |
430 new ImeButtonsView(this, false, false, false, true)); | |
431 } | |
432 | |
433 bubble_.reset(new TrayBubbleWrapper(this, bubble_view)); | |
434 SetIsActive(true); | |
435 } | |
436 | |
437 void ImeMenuTray::HideImeMenuBubble() { | |
438 bubble_.reset(); | |
439 ime_list_view_ = nullptr; | |
440 SetIsActive(false); | |
441 should_block_shelf_auto_hide_ = false; | |
442 shelf()->UpdateAutoHideState(); | |
443 } | |
444 | |
445 bool ImeMenuTray::IsImeMenuBubbleShown() { | |
446 return !!bubble_; | |
447 } | |
448 | |
449 void ImeMenuTray::ShowKeyboardWithKeyset(const std::string& keyset) { | |
450 HideImeMenuBubble(); | |
451 | |
452 // Overrides the keyboard url ref to make it shown with the given keyset. | |
453 if (InputMethodManager::Get()) | |
454 InputMethodManager::Get()->OverrideKeyboardUrlRef(keyset); | |
455 | |
456 // If onscreen keyboard has been enabled, shows the keyboard directly. | |
457 keyboard::KeyboardController* keyboard_controller = | |
458 keyboard::KeyboardController::GetInstance(); | |
459 show_keyboard_ = true; | |
460 if (keyboard_controller) { | |
461 keyboard_controller->AddObserver(this); | |
462 // If the keyboard window hasn't been created yet, it means the extension | |
463 // cannot receive anything to show the keyboard. Therefore, instead of | |
464 // relying the extension to show the keyboard, forcibly show the keyboard | |
465 // window here (which will cause the keyboard window to be created). | |
466 // Otherwise, the extension will show keyboard by calling private api. The | |
467 // native side could just skip showing the keyboard. | |
468 if (!keyboard_controller->IsKeyboardWindowCreated()) | |
469 keyboard_controller->ShowKeyboard(false); | |
470 return; | |
471 } | |
472 | |
473 AccessibilityDelegate* accessibility_delegate = | |
474 WmShell::Get()->accessibility_delegate(); | |
475 // Fails to show the keyboard. | |
476 if (accessibility_delegate->IsVirtualKeyboardEnabled()) | |
477 return; | |
478 | |
479 // Onscreen keyboard has not been enabled yet, forces to bring out the | |
480 // keyboard for one time. | |
481 force_show_keyboard_ = true; | |
482 accessibility_delegate->SetVirtualKeyboardEnabled(true); | |
483 keyboard_controller = keyboard::KeyboardController::GetInstance(); | |
484 if (keyboard_controller) { | |
485 keyboard_controller->AddObserver(this); | |
486 keyboard_controller->ShowKeyboard(false); | |
487 } | |
488 } | |
489 | |
490 bool ImeMenuTray::ShouldBlockShelfAutoHide() const { | |
491 return should_block_shelf_auto_hide_; | |
492 } | |
493 | |
494 bool ImeMenuTray::ShouldShowEmojiHandwritingVoiceButtons() const { | |
495 // Emoji, handwriting and voice input is not supported for these cases: | |
496 // 1) features::kEHVInputOnImeMenu is not enabled. | |
497 // 2) third party IME extensions. | |
498 // 3) login/lock screen. | |
499 // 4) password input client. | |
500 return InputMethodManager::Get() && | |
501 InputMethodManager::Get()->IsEmojiHandwritingVoiceOnImeMenuEnabled() && | |
502 !current_ime_.third_party && !IsInLoginOrLockScreen() && | |
503 !IsInPasswordInputContext(); | |
504 } | |
505 | |
506 bool ImeMenuTray::ShouldShowKeyboardToggle() const { | |
507 return keyboard_suppressed_ && | |
508 !WmShell::Get()->accessibility_delegate()->IsVirtualKeyboardEnabled(); | |
509 } | |
510 | |
511 void ImeMenuTray::SetShelfAlignment(ShelfAlignment alignment) { | |
512 TrayBackgroundView::SetShelfAlignment(alignment); | |
513 if (!MaterialDesignController::IsShelfMaterial()) | |
514 tray_container()->SetBorder(views::NullBorder()); | |
515 } | |
516 | |
517 base::string16 ImeMenuTray::GetAccessibleNameForTray() { | |
518 return l10n_util::GetStringUTF16(IDS_ASH_IME_MENU_ACCESSIBLE_NAME); | |
519 } | |
520 | |
521 void ImeMenuTray::HideBubbleWithView(const views::TrayBubbleView* bubble_view) { | |
522 if (bubble_->bubble_view() == bubble_view) | |
523 HideImeMenuBubble(); | |
524 } | |
525 | |
526 void ImeMenuTray::ClickedOutsideBubble() { | |
527 HideImeMenuBubble(); | |
528 } | |
529 | |
530 bool ImeMenuTray::PerformAction(const ui::Event& event) { | |
531 if (bubble_) | |
532 HideImeMenuBubble(); | |
533 else | |
534 ShowImeMenuBubble(); | |
535 return true; | |
536 } | |
537 | |
538 void ImeMenuTray::OnIMERefresh() { | |
539 UpdateTrayLabel(); | |
540 if (bubble_ && ime_list_view_) { | |
541 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate(); | |
542 IMEInfoList list; | |
543 delegate->GetAvailableIMEList(&list); | |
544 IMEPropertyInfoList property_list; | |
545 delegate->GetCurrentIMEProperties(&property_list); | |
546 ime_list_view_->Update(list, property_list, false, | |
547 ImeListView::SHOW_SINGLE_IME); | |
548 } | |
549 } | |
550 | |
551 void ImeMenuTray::OnIMEMenuActivationChanged(bool is_activated) { | |
552 SetVisible(is_activated); | |
553 if (is_activated) | |
554 UpdateTrayLabel(); | |
555 else | |
556 HideImeMenuBubble(); | |
557 } | |
558 | |
559 void ImeMenuTray::BubbleViewDestroyed() { | |
560 } | |
561 | |
562 void ImeMenuTray::OnMouseEnteredView() {} | |
563 | |
564 void ImeMenuTray::OnMouseExitedView() {} | |
565 | |
566 base::string16 ImeMenuTray::GetAccessibleNameForBubble() { | |
567 return l10n_util::GetStringUTF16(IDS_ASH_IME_MENU_ACCESSIBLE_NAME); | |
568 } | |
569 | |
570 void ImeMenuTray::OnBeforeBubbleWidgetInit( | |
571 views::Widget* anchor_widget, | |
572 views::Widget* bubble_widget, | |
573 views::Widget::InitParams* params) const { | |
574 // Place the bubble in the same root window as |anchor_widget|. | |
575 WmWindow::Get(anchor_widget->GetNativeWindow()) | |
576 ->GetRootWindowController() | |
577 ->ConfigureWidgetInitParamsForContainer( | |
578 bubble_widget, kShellWindowId_SettingBubbleContainer, params); | |
579 } | |
580 | |
581 void ImeMenuTray::HideBubble(const views::TrayBubbleView* bubble_view) { | |
582 HideBubbleWithView(bubble_view); | |
583 } | |
584 | |
585 void ImeMenuTray::OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) {} | |
586 | |
587 void ImeMenuTray::OnKeyboardClosed() { | |
588 if (InputMethodManager::Get()) | |
589 InputMethodManager::Get()->OverrideKeyboardUrlRef(std::string()); | |
590 keyboard::KeyboardController* keyboard_controller = | |
591 keyboard::KeyboardController::GetInstance(); | |
592 if (keyboard_controller) | |
593 keyboard_controller->RemoveObserver(this); | |
594 | |
595 show_keyboard_ = false; | |
596 force_show_keyboard_ = false; | |
597 } | |
598 | |
599 void ImeMenuTray::OnKeyboardHidden() { | |
600 if (show_bubble_after_keyboard_hidden_) { | |
601 show_bubble_after_keyboard_hidden_ = false; | |
602 keyboard::KeyboardController* keyboard_controller = | |
603 keyboard::KeyboardController::GetInstance(); | |
604 if (keyboard_controller) | |
605 keyboard_controller->RemoveObserver(this); | |
606 | |
607 ShowImeMenuBubbleInternal(); | |
608 return; | |
609 } | |
610 | |
611 if (!show_keyboard_) | |
612 return; | |
613 | |
614 // If the the IME menu has overriding the input view url, we should write it | |
615 // back to normal keyboard when hiding the input view. | |
616 if (InputMethodManager::Get()) | |
617 InputMethodManager::Get()->OverrideKeyboardUrlRef(std::string()); | |
618 show_keyboard_ = false; | |
619 | |
620 // If the keyboard is forced to be shown by IME menu for once, we need to | |
621 // disable the keyboard when it's hidden. | |
622 keyboard::KeyboardController* keyboard_controller = | |
623 keyboard::KeyboardController::GetInstance(); | |
624 if (keyboard_controller) | |
625 keyboard_controller->RemoveObserver(this); | |
626 | |
627 if (!force_show_keyboard_) | |
628 return; | |
629 | |
630 WmShell::Get()->accessibility_delegate()->SetVirtualKeyboardEnabled(false); | |
631 force_show_keyboard_ = false; | |
632 } | |
633 | |
634 void ImeMenuTray::OnKeyboardSuppressionChanged(bool suppressed) { | |
635 if (suppressed != keyboard_suppressed_ && bubble_) | |
636 HideImeMenuBubble(); | |
637 keyboard_suppressed_ = suppressed; | |
638 } | |
639 | |
640 void ImeMenuTray::UpdateTrayLabel() { | |
641 WmShell::Get()->system_tray_delegate()->GetCurrentIME(¤t_ime_); | |
642 | |
643 // Updates the tray label based on the current input method. | |
644 if (current_ime_.third_party) | |
645 label_->SetText(current_ime_.short_name + base::UTF8ToUTF16("*")); | |
646 else | |
647 label_->SetText(current_ime_.short_name); | |
648 } | |
649 | |
650 } // namespace ash | |
OLD | NEW |