1 // Copyright 2013 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 "chrome/browser/chromeos/input_method/mode_indicator_controller.h" 6 7 #include "ash/ime/mode_indicator_view.h" 8 #include "ash/shell.h" 9 #include "ash/shell_window_ids.h" 10 #include "ash/wm/window_util.h" 11 #include "base/logging.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "chrome/browser/chromeos/input_method/input_method_util.h" 14 15 namespace chromeos { 16 namespace input_method { 17 18 namespace { 19 ModeIndicatorObserverInterface* g_mode_indicator_observer_for_testing_ = NULL; 20 } // namespace 21 22 class ModeIndicatorObserver : public ModeIndicatorObserverInterface { 23 public: 24 ModeIndicatorObserver() 25 : active_widget_(NULL) {} 26 27 virtual ~ModeIndicatorObserver() { 28 if (active_widget_) 29 active_widget_->RemoveObserver(this); 30 } 31 32 // If other active mode indicator widget is shown, close it immedicately 33 // without fading animation. Then store this widget as the active widget. 34 virtual void AddModeIndicatorWidget(views::Widget* widget) OVERRIDE { 35 DCHECK(widget); 36 if (active_widget_) 37 active_widget_->Close(); 38 active_widget_ = widget; 39 widget->AddObserver(this); 40 } 41 42 // views::WidgetObserver override: 43 virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE { 44 if (widget == active_widget_) 45 active_widget_ = NULL; 46 } 47 48 private: 49 views::Widget* active_widget_; 50 }; 51 52 53 ModeIndicatorController::ModeIndicatorController(InputMethodManager* imm) 54 : imm_(imm), 55 is_focused_(false), 56 mi_observer_(new ModeIndicatorObserver) { 57 DCHECK(imm_); 58 imm_->AddObserver(this); 59 } 60 61 ModeIndicatorController::~ModeIndicatorController() { 62 imm_->RemoveObserver(this); 63 } 64 65 void ModeIndicatorController::SetCursorBounds( 66 const gfx::Rect& cursor_bounds) { 67 cursor_bounds_ = cursor_bounds; 68 } 69 70 void ModeIndicatorController::FocusStateChanged(bool is_focused) { 71 is_focused_ = is_focused; 72 } 73 74 // static 75 void ModeIndicatorController::SetModeIndicatorObserverForTesting( 76 ModeIndicatorObserverInterface* observer) { 77 g_mode_indicator_observer_for_testing_ = observer; 78 } 79 80 // static 81 ModeIndicatorObserverInterface* 82 ModeIndicatorController::GetModeIndicatorObserverForTesting() { 83 return g_mode_indicator_observer_for_testing_; 84 } 85 86 void ModeIndicatorController::InputMethodChanged(InputMethodManager* manager, 87 bool show_message) { 88 if (!show_message) 89 return; 90 ShowModeIndicator(); 91 } 92 93 void ModeIndicatorController::ShowModeIndicator() { 94 // TODO(komatsu): Show the mode indicator in the right bottom of the 95 // display when the launch bar is hidden and the focus is out. To 96 // implement it, we should consider to use message center or system 97 // notification. Note, launch bar can be vertical and can be placed 98 // right/left side of display. 99 if (!is_focused_) 100 return; 101 102 // Get the short name of the changed input method (e.g. US, JA, etc.) 103 const InputMethodDescriptor descriptor = 104 imm_->GetActiveIMEState()->GetCurrentInputMethod(); 105 const base::string16 short_name = 106 imm_->GetInputMethodUtil()->GetInputMethodShortName(descriptor); 107 108 aura::Window* parent = 109 ash::Shell::GetContainer(ash::wm::GetActiveWindow()->GetRootWindow(), 110 ash::kShellWindowId_SettingBubbleContainer); 111 ash::ime::ModeIndicatorView* mi_view = new ash::ime::ModeIndicatorView( 112 parent, cursor_bounds_, short_name); 113 views::BubbleDelegateView::CreateBubble(mi_view); 114 115 views::Widget* mi_widget = mi_view->GetWidget(); 116 if (GetModeIndicatorObserverForTesting()) 117 GetModeIndicatorObserverForTesting()->AddModeIndicatorWidget(mi_widget); 118 119 mi_observer_->AddModeIndicatorWidget(mi_widget); 120 mi_view->ShowAndFadeOut(); 121 } 122 123 } // namespace input_method 124 } // namespace chromeos 125