1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_CHROMEOS_STATUS_INPUT_METHOD_MENU_H_ 6 #define CHROME_BROWSER_CHROMEOS_STATUS_INPUT_METHOD_MENU_H_ 7 #pragma once 8 9 #include <string> 10 11 #include "chrome/browser/chromeos/cros/input_method_library.h" 12 #include "chrome/browser/chromeos/status/status_area_host.h" 13 #include "chrome/browser/prefs/pref_member.h" 14 #include "content/common/notification_observer.h" 15 #include "content/common/notification_registrar.h" 16 #include "content/common/notification_type.h" 17 #include "ui/base/models/simple_menu_model.h" 18 #include "views/controls/menu/menu_2.h" 19 #include "views/controls/menu/view_menu_delegate.h" 20 21 class PrefService; 22 class SkBitmap; 23 24 namespace chromeos { 25 26 // A class for the dropdown menu for switching input method and keyboard layout. 27 // Since the class provides the views::ViewMenuDelegate interface, it's easy to 28 // create a button widget (e.g. views::MenuButton, chromeos::StatusAreaButton) 29 // which shows the dropdown menu on click. 30 class InputMethodMenu : public views::ViewMenuDelegate, 31 public ui::MenuModel, 32 public InputMethodLibrary::Observer, 33 public NotificationObserver { 34 public: 35 InputMethodMenu(PrefService* pref_service, 36 StatusAreaHost::ScreenMode screen_mode, 37 bool for_out_of_box_experience_dialog); 38 virtual ~InputMethodMenu(); 39 40 // ui::MenuModel implementation. 41 virtual bool HasIcons() const; 42 virtual int GetItemCount() const; 43 virtual ui::MenuModel::ItemType GetTypeAt(int index) const; 44 virtual int GetCommandIdAt(int index) const; 45 virtual string16 GetLabelAt(int index) const; 46 virtual bool IsItemDynamicAt(int index) const; 47 virtual bool GetAcceleratorAt(int index, 48 ui::Accelerator* accelerator) const; 49 virtual bool IsItemCheckedAt(int index) const; 50 virtual int GetGroupIdAt(int index) const; 51 virtual bool GetIconAt(int index, SkBitmap* icon); 52 virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const; 53 virtual bool IsEnabledAt(int index) const; 54 virtual ui::MenuModel* GetSubmenuModelAt(int index) const; 55 virtual void HighlightChangedTo(int index); 56 virtual void ActivatedAt(int index); 57 virtual void MenuWillShow(); 58 virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate); 59 60 // views::ViewMenuDelegate implementation. Sub classes can override the method 61 // to adjust the position of the menu. 62 virtual void RunMenu(views::View* unused_source, 63 const gfx::Point& pt); 64 65 // InputMethodLibrary::Observer implementation. 66 virtual void InputMethodChanged( 67 InputMethodLibrary* obj, 68 const InputMethodDescriptor& current_input_method, 69 size_t num_active_input_methods); 70 virtual void ActiveInputMethodsChanged( 71 InputMethodLibrary* obj, 72 const InputMethodDescriptor& current_input_method, 73 size_t num_active_input_methods); 74 virtual void PreferenceUpdateNeeded( 75 InputMethodLibrary* obj, 76 const InputMethodDescriptor& previous_input_method, 77 const InputMethodDescriptor& current_input_method); 78 virtual void PropertyListChanged( 79 InputMethodLibrary* obj, 80 const ImePropertyList& current_ime_properties); 81 virtual void FirstObserverIsAdded(InputMethodLibrary* obj); 82 83 // NotificationObserver implementation. 84 virtual void Observe(NotificationType type, 85 const NotificationSource& source, 86 const NotificationDetails& details); 87 88 // Sets the minimum width of the dropdown menu. 89 void SetMinimumWidth(int width); 90 91 // Rebuilds model and menu2 objects. 92 void PrepareMenu(); 93 94 // Registers input method preferences for the login screen. 95 static void RegisterPrefs(PrefService* local_state); 96 97 // Returns a string for the indicator on top right corner of the Chrome 98 // window. The method is public for unit tests. 99 static std::wstring GetTextForIndicator( 100 const InputMethodDescriptor& input_method); 101 102 // Returns a string for the drop-down menu and the tooltip for the indicator. 103 // The method is public for unit tests. 104 static std::wstring GetTextForMenu(const InputMethodDescriptor& input_method); 105 106 protected: 107 // Prepares menu: saves user metrics and rebuilds. 108 void PrepareForMenuOpen(); 109 110 // Returns menu2 object for language menu. 111 views::Menu2& input_method_menu() { 112 return input_method_menu_; 113 } 114 115 private: 116 // Updates UI of a container of the menu (e.g. the "US" menu button in the 117 // status area). Sub classes have to implement the interface for their own UI. 118 virtual void UpdateUI(const std::string& input_method_id, // e.g. "mozc" 119 const std::wstring& name, // e.g. "US", "INTL" 120 const std::wstring& tooltip, 121 size_t num_active_input_methods) = 0; 122 123 // Sub classes have to implement the interface. This interface should return 124 // true if the dropdown menu should show an item like "Customize languages 125 // and input..." WebUI. 126 virtual bool ShouldSupportConfigUI() = 0; 127 128 // Sub classes have to implement the interface which opens an UI for 129 // customizing languages and input. 130 virtual void OpenConfigUI() = 0; 131 132 // Parses |input_method| and then calls UpdateUI(). 133 void UpdateUIFromInputMethod(const InputMethodDescriptor& input_method, 134 size_t num_active_input_methods); 135 136 // Rebuilds |model_|. This function should be called whenever 137 // |input_method_descriptors_| is updated, or ImePropertiesChanged() is 138 // called. 139 void RebuildModel(); 140 141 // Returns true if the zero-origin |index| points to one of the input methods. 142 bool IndexIsInInputMethodList(int index) const; 143 144 // Returns true if the zero-origin |index| points to one of the IME 145 // properties. When returning true, |property_index| is updated so that 146 // property_list.at(property_index) points to the menu item. 147 bool GetPropertyIndex(int index, int* property_index) const; 148 149 // Returns true if the zero-origin |index| points to the "Configure IME" menu 150 // item. 151 bool IndexPointsToConfigureImeMenuItem(int index) const; 152 153 // The current input method list. 154 scoped_ptr<InputMethodDescriptors> input_method_descriptors_; 155 156 // Objects for reading/writing the Chrome prefs. 157 StringPrefMember previous_input_method_pref_; 158 StringPrefMember current_input_method_pref_; 159 160 // We borrow ui::SimpleMenuModel implementation to maintain the current 161 // content of the pop-up menu. The ui::MenuModel is implemented using this 162 // |model_|. 163 scoped_ptr<ui::SimpleMenuModel> model_; 164 165 // The language menu which pops up when the button in status area is clicked. 166 views::Menu2 input_method_menu_; 167 int minimum_input_method_menu_width_; 168 169 PrefService* pref_service_; 170 NotificationRegistrar registrar_; 171 172 // The mode of the host screen (e.g. browser, screen locker, login screen.) 173 const StatusAreaHost::ScreenMode screen_mode_; 174 // true if the menu is for a dialog in OOBE screen. In the dialog, we don't 175 // use radio buttons. 176 const bool for_out_of_box_experience_dialog_; 177 178 DISALLOW_COPY_AND_ASSIGN(InputMethodMenu); 179 }; 180 181 } // namespace chromeos 182 183 #endif // CHROME_BROWSER_CHROMEOS_STATUS_INPUT_METHOD_MENU_H_ 184