Home | History | Annotate | Download | only in status
      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