azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 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 | |
James Cook | a35a1e2 | 2017-04-08 02:33:08 | [diff] [blame] | 5 | #include "ash/system/ime_menu/ime_menu_tray.h" |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 6 | |
Mike Wasserman | d13e95a | 2019-06-28 23:29:48 | [diff] [blame] | 7 | #include "ash/accessibility/accessibility_controller_impl.h" |
Darren Shen | 7b13278 | 2019-12-10 04:36:06 | [diff] [blame] | 8 | #include "ash/ime/ime_controller_impl.h" |
Darren Shen | 7daf3e1 | 2019-07-02 07:25:49 | [diff] [blame] | 9 | #include "ash/keyboard/keyboard_controller_impl.h" |
Darren Shen | cb250844 | 2019-07-03 21:48:23 | [diff] [blame] | 10 | #include "ash/keyboard/ui/keyboard_ui_controller.h" |
James Cook | 8d91252 | 2018-06-19 02:18:47 | [diff] [blame] | 11 | #include "ash/keyboard/virtual_keyboard_controller.h" |
Steven Bennetts | 93d3e5b1 | 2018-05-05 01:14:50 | [diff] [blame] | 12 | #include "ash/public/cpp/ash_constants.h" |
James Cook | a354b3b | 2019-05-22 23:15:38 | [diff] [blame] | 13 | #include "ash/public/cpp/system_tray_client.h" |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 14 | #include "ash/resources/vector_icons/vector_icons.h" |
sky | b664383 | 2017-01-11 22:08:45 | [diff] [blame] | 15 | #include "ash/root_window_controller.h" |
Xiyuan Xia | e7b1954 | 2019-05-06 23:05:18 | [diff] [blame] | 16 | #include "ash/session/session_controller_impl.h" |
James Cook | 840177e | 2017-05-25 02:20:01 | [diff] [blame] | 17 | #include "ash/shelf/shelf.h" |
sky | 07a24d4 | 2017-03-09 23:57:30 | [diff] [blame] | 18 | #include "ash/shell.h" |
jamescook | e45f811 | 2017-03-02 16:45:42 | [diff] [blame] | 19 | #include "ash/strings/grit/ash_strings.h" |
minch | 8675df5 | 2019-08-09 17:46:46 | [diff] [blame] | 20 | #include "ash/style/ash_color_provider.h" |
James Cook | a35a1e2 | 2017-04-08 02:33:08 | [diff] [blame] | 21 | #include "ash/system/ime_menu/ime_list_view.h" |
Tetsui Ohkubo | 3679446 | 2018-06-29 07:26:02 | [diff] [blame] | 22 | #include "ash/system/model/system_tray_model.h" |
Tetsui Ohkubo | cd22261 | 2018-05-28 06:47:54 | [diff] [blame] | 23 | #include "ash/system/tray/detailed_view_delegate.h" |
James Cook | b0bf8e8 | 2017-04-09 17:01:44 | [diff] [blame] | 24 | #include "ash/system/tray/system_menu_button.h" |
James Cook | b0bf8e8 | 2017-04-09 17:01:44 | [diff] [blame] | 25 | #include "ash/system/tray/system_tray_notifier.h" |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 26 | #include "ash/system/tray/tray_background_view.h" |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 27 | #include "ash/system/tray/tray_constants.h" |
mohsen | e6704a0 | 2017-04-20 06:30:20 | [diff] [blame] | 28 | #include "ash/system/tray/tray_container.h" |
James Cook | b0bf8e8 | 2017-04-09 17:01:44 | [diff] [blame] | 29 | #include "ash/system/tray/tray_popup_utils.h" |
| 30 | #include "ash/system/tray/tray_utils.h" |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 31 | #include "ash/system/unified/top_shortcut_button.h" |
azurewei | 19203f950 | 2017-01-11 03:45:43 | [diff] [blame] | 32 | #include "base/metrics/histogram_macros.h" |
James Cook | 465370c7 | 2017-06-28 22:55:08 | [diff] [blame] | 33 | #include "base/metrics/user_metrics.h" |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 34 | #include "base/strings/utf_string_conversions.h" |
jamescook | 85312ee | 2017-04-18 22:47:20 | [diff] [blame] | 35 | #include "components/session_manager/session_manager_types.h" |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 36 | #include "ui/base/ime/chromeos/extension_ime_util.h" |
Darren Shen | 377ad2d5 | 2020-05-29 00:25:05 | [diff] [blame] | 37 | #include "ui/base/ime/chromeos/ime_bridge.h" |
azurewei | 1c4c4e8 | 2017-01-10 04:47:18 | [diff] [blame] | 38 | #include "ui/base/ime/text_input_client.h" |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 39 | #include "ui/base/l10n/l10n_util.h" |
azurewei | 6bc89eb | 2016-08-26 22:56:56 | [diff] [blame] | 40 | #include "ui/base/resource/resource_bundle.h" |
Allen Bauer | 99a9379 | 2017-06-05 20:59:07 | [diff] [blame] | 41 | #include "ui/gfx/geometry/insets.h" |
azurewei | 6a18628 | 2016-09-20 15:46:30 | [diff] [blame] | 42 | #include "ui/gfx/paint_vector_icon.h" |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 43 | #include "ui/gfx/range/range.h" |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 44 | #include "ui/views/controls/image_view.h" |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 45 | #include "ui/views/controls/label.h" |
estade | 252bd536 | 2017-02-07 23:40:01 | [diff] [blame] | 46 | #include "ui/views/controls/scroll_view.h" |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 47 | #include "ui/views/controls/separator.h" |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 48 | #include "ui/views/layout/box_layout.h" |
Shengsong Tan | f215377 | 2020-12-28 08:45:07 | [diff] [blame] | 49 | #include "ui/views/layout/box_layout_view.h" |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 50 | #include "ui/views/metadata/metadata_impl_macros.h" |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 51 | |
| 52 | namespace ash { |
| 53 | |
| 54 | namespace { |
James Cook | ced4693e | 2017-07-12 02:04:28 | [diff] [blame] | 55 | |
| 56 | // Used for testing. |
| 57 | const int kEmojiButtonId = 1; |
| 58 | |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 59 | // Insets for the title view (dp). |
| 60 | constexpr gfx::Insets kTitleViewPadding(0, 0, 0, 16); |
| 61 | |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 62 | // Returns the height range of ImeListView. |
| 63 | gfx::Range GetImeListViewRange() { |
| 64 | const int max_items = 5; |
azurewei | 9786d46 | 2016-12-22 23:34:27 | [diff] [blame] | 65 | const int min_items = 1; |
estade | da123cac | 2017-03-01 05:02:55 | [diff] [blame] | 66 | const int tray_item_height = kTrayPopupItemMinHeight; |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 67 | return gfx::Range(tray_item_height * min_items, tray_item_height * max_items); |
azurewei | 5ee4621 | 2016-08-24 00:49:36 | [diff] [blame] | 68 | } |
| 69 | |
azurewei | 23b7cdb0 | 2016-11-08 04:16:57 | [diff] [blame] | 70 | // Returns true if the current screen is login or lock screen. |
| 71 | bool IsInLoginOrLockScreen() { |
jamescook | 85312ee | 2017-04-18 22:47:20 | [diff] [blame] | 72 | using session_manager::SessionState; |
| 73 | SessionState state = Shell::Get()->session_controller()->GetSessionState(); |
| 74 | return state == SessionState::LOGIN_PRIMARY || |
| 75 | state == SessionState::LOCKED || |
| 76 | state == SessionState::LOGIN_SECONDARY; |
azurewei | 23b7cdb0 | 2016-11-08 04:16:57 | [diff] [blame] | 77 | } |
| 78 | |
azurewei | 1c4c4e8 | 2017-01-10 04:47:18 | [diff] [blame] | 79 | // Returns true if the current input context type is password. |
| 80 | bool IsInPasswordInputContext() { |
Scott Violet | 7618db6a | 2019-06-20 01:22:07 | [diff] [blame] | 81 | return ui::IMEBridge::Get()->GetCurrentInputContext().type == |
| 82 | ui::TEXT_INPUT_TYPE_PASSWORD; |
azurewei | 1c4c4e8 | 2017-01-10 04:47:18 | [diff] [blame] | 83 | } |
| 84 | |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 85 | class ImeMenuLabel : public views::Label { |
| 86 | public: |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 87 | METADATA_HEADER(ImeMenuLabel); |
| 88 | |
estade | b0aaaea | 2017-04-17 22:55:25 | [diff] [blame] | 89 | ImeMenuLabel() { |
| 90 | // Sometimes the label will be more than 2 characters, e.g. INTL and EXTD. |
| 91 | // This border makes sure we only leave room for ~2 and the others are |
| 92 | // truncated. |
| 93 | SetBorder(views::CreateEmptyBorder(gfx::Insets(0, 6))); |
| 94 | } |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 95 | ImeMenuLabel(const ImeMenuLabel&) = delete; |
| 96 | ImeMenuLabel& operator=(const ImeMenuLabel&) = delete; |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 97 | ~ImeMenuLabel() override = default; |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 98 | |
| 99 | // views:Label: |
estade | f285a78 | 2017-05-22 21:52:24 | [diff] [blame] | 100 | gfx::Size CalculatePreferredSize() const override { |
estade | da123cac | 2017-03-01 05:02:55 | [diff] [blame] | 101 | return gfx::Size(kTrayItemSize, kTrayItemSize); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 102 | } |
estade | da123cac | 2017-03-01 05:02:55 | [diff] [blame] | 103 | int GetHeightForWidth(int width) const override { return kTrayItemSize; } |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 104 | }; |
| 105 | |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 106 | BEGIN_METADATA(ImeMenuLabel, views::Label) |
| 107 | END_METADATA |
| 108 | |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 109 | class ImeMenuImageView : public views::ImageView { |
| 110 | public: |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 111 | METADATA_HEADER(ImeMenuImageView); |
| 112 | |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 113 | ImeMenuImageView() { SetBorder(views::CreateEmptyBorder(gfx::Insets(0, 6))); } |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 114 | ImeMenuImageView(const ImeMenuImageView&) = delete; |
| 115 | ImeMenuImageView& operator=(const ImeMenuImageView&) = delete; |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 116 | ~ImeMenuImageView() override = default; |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 117 | }; |
| 118 | |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 119 | BEGIN_METADATA(ImeMenuImageView, views::ImageView) |
| 120 | END_METADATA |
| 121 | |
estade | a553b86b | 2017-03-29 19:04:55 | [diff] [blame] | 122 | // The view that contains IME menu title. |
Shengsong Tan | f215377 | 2020-12-28 08:45:07 | [diff] [blame] | 123 | class ImeTitleView : public views::BoxLayoutView { |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 124 | public: |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 125 | METADATA_HEADER(ImeTitleView); |
minch | ae1caf0 | 2020-11-06 18:29:03 | [diff] [blame] | 126 | ImeTitleView() { |
| 127 | auto* color_provider = AshColorProvider::Get(); |
estade | 55bb189 | 2016-11-09 22:39:21 | [diff] [blame] | 128 | SetBorder(views::CreatePaddedBorder( |
minch | 8675df5 | 2019-08-09 17:46:46 | [diff] [blame] | 129 | views::CreateSolidSidedBorder( |
| 130 | 0, 0, kMenuSeparatorWidth, 0, |
minch | ae1caf0 | 2020-11-06 18:29:03 | [diff] [blame] | 131 | color_provider->GetContentLayerColor( |
minch | 5847c6f | 2020-09-08 01:13:17 | [diff] [blame] | 132 | AshColorProvider::ContentLayerType::kSeparatorColor)), |
Manu Cornet | 88510ca | 2019-01-30 03:31:42 | [diff] [blame] | 133 | gfx::Insets(kMenuSeparatorVerticalPadding - kMenuSeparatorWidth, 0))); |
Shengsong Tan | f215377 | 2020-12-28 08:45:07 | [diff] [blame] | 134 | SetOrientation(views::BoxLayout::Orientation::kHorizontal); |
| 135 | SetInsideBorderInsets(kTitleViewPadding); |
| 136 | SetMinimumCrossAxisSize(kTrayPopupItemMinHeight); |
| 137 | |
minch | ae1caf0 | 2020-11-06 18:29:03 | [diff] [blame] | 138 | auto* title_label = AddChildView(std::make_unique<views::Label>( |
| 139 | l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME))); |
azurewei | d0cea0b | 2017-02-07 02:15:48 | [diff] [blame] | 140 | title_label->SetBorder( |
| 141 | views::CreateEmptyBorder(0, kMenuEdgeEffectivePadding, 1, 0)); |
estade | 99ef2a3 | 2017-02-03 03:57:40 | [diff] [blame] | 142 | title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
minch | ae1caf0 | 2020-11-06 18:29:03 | [diff] [blame] | 143 | title_label->SetEnabledColor(color_provider->GetContentLayerColor( |
| 144 | AshColorProvider::ContentLayerType::kTextColorPrimary)); |
| 145 | TrayPopupUtils::SetLabelFontList(title_label, |
Ahmed Mehfooz | fcf2742 | 2020-11-21 05:18:51 | [diff] [blame] | 146 | TrayPopupUtils::FontStyle::kPodMenuHeader); |
Shengsong Tan | f215377 | 2020-12-28 08:45:07 | [diff] [blame] | 147 | SetFlexForView(title_label, 1); |
azurewei | 23b7cdb0 | 2016-11-08 04:16:57 | [diff] [blame] | 148 | |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 149 | settings_button_ = AddChildView(std::make_unique<TopShortcutButton>( |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 150 | base::BindRepeating([]() { |
| 151 | base::RecordAction( |
| 152 | base::UserMetricsAction("StatusArea_IME_Detailed")); |
| 153 | Shell::Get()->system_tray_model()->client()->ShowIMESettings(); |
| 154 | }), |
| 155 | kSystemMenuSettingsIcon, IDS_ASH_STATUS_TRAY_IME_SETTINGS)); |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 156 | settings_button_->SetEnabled(TrayPopupUtils::CanOpenWebUISettings()); |
azurewei | 23b7cdb0 | 2016-11-08 04:16:57 | [diff] [blame] | 157 | } |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 158 | ImeTitleView(const ImeTitleView&) = delete; |
| 159 | ImeTitleView& operator=(const ImeTitleView&) = delete; |
azurewei | 23b7cdb0 | 2016-11-08 04:16:57 | [diff] [blame] | 160 | |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 161 | ~ImeTitleView() override = default; |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 162 | |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 163 | private: |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 164 | TopShortcutButton* settings_button_ = nullptr; |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 165 | }; |
| 166 | |
Shengsong Tan | f215377 | 2020-12-28 08:45:07 | [diff] [blame] | 167 | BEGIN_METADATA(ImeTitleView, views::BoxLayoutView) |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 168 | END_METADATA |
| 169 | |
azurewei | acbd0c3 | 2016-08-30 05:45:38 | [diff] [blame] | 170 | // The view that contains buttons shown on the bottom of IME menu. |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 171 | class ImeButtonsView : public views::View { |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 172 | public: |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 173 | METADATA_HEADER(ImeButtonsView); |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 174 | ImeButtonsView(ImeMenuTray* ime_menu_tray, |
| 175 | bool show_emoji, |
| 176 | bool show_handwriting, |
James Cook | ced4693e | 2017-07-12 02:04:28 | [diff] [blame] | 177 | bool show_voice) |
| 178 | : ime_menu_tray_(ime_menu_tray) { |
azurewei | 649030a2 | 2016-09-20 13:11:43 | [diff] [blame] | 179 | DCHECK(ime_menu_tray_); |
| 180 | |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 181 | Init(show_emoji, show_handwriting, show_voice); |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 182 | } |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 183 | ImeButtonsView(const ImeButtonsView&) = delete; |
| 184 | ImeButtonsView& operator=(const ImeButtonsView&) = delete; |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 185 | |
Chris Watkins | c24daf6 | 2017-11-28 03:43:09 | [diff] [blame] | 186 | ~ImeButtonsView() override = default; |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 187 | |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 188 | void KeysetButtonPressed(chromeos::input_method::ImeKeyset keyset) { |
Darren Shen | a4bf749 | 2018-03-16 04:25:52 | [diff] [blame] | 189 | // TODO(dcheng): When https://crbug.com/742517 is fixed, Mojo will generate |
| 190 | // a constant for the number of values in the enum. For now, we just define |
| 191 | // it here and keep it in sync with the enum. |
| 192 | const int kImeKeysetUmaBoundary = 4; |
| 193 | UMA_HISTOGRAM_ENUMERATION("InputMethod.ImeMenu.EmojiHandwritingVoiceButton", |
| 194 | keyset, kImeKeysetUmaBoundary); |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 195 | // The |keyset| will be used for drawing input view keyset in IME |
| 196 | // extensions. ImeMenuTray::ShowKeyboardWithKeyset() will deal with |
| 197 | // the |keyset| string to generate the right input view url. |
azurewei | 649030a2 | 2016-09-20 13:11:43 | [diff] [blame] | 198 | ime_menu_tray_->ShowKeyboardWithKeyset(keyset); |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | private: |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 202 | void Init(bool show_emoji, bool show_handwriting, bool show_voice) { |
Hwanseung Lee | 5b9e43d | 2019-06-25 01:55:32 | [diff] [blame] | 203 | auto box_layout = std::make_unique<views::BoxLayout>( |
| 204 | views::BoxLayout::Orientation::kHorizontal); |
estade | a553b86b | 2017-03-29 19:04:55 | [diff] [blame] | 205 | box_layout->set_minimum_cross_axis_size(kTrayPopupItemMinHeight); |
Brett Wilson | 501d664 | 2017-12-14 17:58:18 | [diff] [blame] | 206 | SetLayoutManager(std::move(box_layout)); |
estade | a553b86b | 2017-03-29 19:04:55 | [diff] [blame] | 207 | SetBorder(views::CreatePaddedBorder( |
minch | 8675df5 | 2019-08-09 17:46:46 | [diff] [blame] | 208 | views::CreateSolidSidedBorder( |
| 209 | kMenuSeparatorWidth, 0, 0, 0, |
minch | 6a718bb | 2019-08-20 20:45:28 | [diff] [blame] | 210 | AshColorProvider::Get()->GetContentLayerColor( |
minch | 5847c6f | 2020-09-08 01:13:17 | [diff] [blame] | 211 | AshColorProvider::ContentLayerType::kSeparatorColor)), |
Manu Cornet | 88510ca | 2019-01-30 03:31:42 | [diff] [blame] | 212 | gfx::Insets(kMenuSeparatorVerticalPadding - kMenuSeparatorWidth, |
estade | a553b86b | 2017-03-29 19:04:55 | [diff] [blame] | 213 | kMenuExtraMarginFromLeftEdge))); |
azurewei | acbd0c3 | 2016-08-30 05:45:38 | [diff] [blame] | 214 | |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 215 | if (show_emoji) { |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 216 | emoji_button_ = new SystemMenuButton( |
| 217 | base::BindRepeating(&ImeButtonsView::KeysetButtonPressed, |
| 218 | base::Unretained(this), |
| 219 | chromeos::input_method::ImeKeyset::kEmoji), |
| 220 | kImeMenuEmoticonIcon, IDS_ASH_STATUS_TRAY_IME_EMOJI); |
Allen Bauer | 942cd54 | 2019-05-08 13:06:13 | [diff] [blame] | 221 | emoji_button_->SetID(kEmojiButtonId); |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 222 | AddChildView(emoji_button_); |
| 223 | } |
azurewei | acbd0c3 | 2016-08-30 05:45:38 | [diff] [blame] | 224 | |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 225 | if (show_handwriting) { |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 226 | handwriting_button_ = new SystemMenuButton( |
| 227 | base::BindRepeating(&ImeButtonsView::KeysetButtonPressed, |
| 228 | base::Unretained(this), |
| 229 | chromeos::input_method::ImeKeyset::kHandwriting), |
| 230 | kImeMenuWriteIcon, IDS_ASH_STATUS_TRAY_IME_HANDWRITING); |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 231 | AddChildView(handwriting_button_); |
| 232 | } |
azurewei | acbd0c3 | 2016-08-30 05:45:38 | [diff] [blame] | 233 | |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 234 | if (show_voice) { |
Peter Kasting | 1056ad8f | 2020-11-04 17:26:24 | [diff] [blame] | 235 | voice_button_ = new SystemMenuButton( |
| 236 | base::BindRepeating(&ImeButtonsView::KeysetButtonPressed, |
| 237 | base::Unretained(this), |
| 238 | chromeos::input_method::ImeKeyset::kVoice), |
| 239 | kImeMenuMicrophoneIcon, IDS_ASH_STATUS_TRAY_IME_VOICE); |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 240 | AddChildView(voice_button_); |
| 241 | } |
azurewei | acbd0c3 | 2016-08-30 05:45:38 | [diff] [blame] | 242 | } |
| 243 | |
azurewei | 649030a2 | 2016-09-20 13:11:43 | [diff] [blame] | 244 | ImeMenuTray* ime_menu_tray_; |
azurewei | a3cd530 | 2016-11-04 01:58:00 | [diff] [blame] | 245 | SystemMenuButton* emoji_button_; |
| 246 | SystemMenuButton* handwriting_button_; |
| 247 | SystemMenuButton* voice_button_; |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 248 | }; |
| 249 | |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 250 | BEGIN_METADATA(ImeButtonsView, views::View) |
| 251 | END_METADATA |
| 252 | |
tdanderson | 9e3fb28 | 2017-04-05 21:43:33 | [diff] [blame] | 253 | // A list of available IMEs shown in the opt-in IME menu, which has a different |
| 254 | // height depending on the number of IMEs in the list. |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 255 | class ImeMenuListView : public ImeListView { |
azurewei | 29b403d | 2016-12-08 03:40:00 | [diff] [blame] | 256 | public: |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 257 | METADATA_HEADER(ImeMenuListView); |
azurewei | 29b403d | 2016-12-08 03:40:00 | [diff] [blame] | 258 | |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 259 | ImeMenuListView() : ImeMenuListView(std::make_unique<Delegate>()) {} |
| 260 | ImeMenuListView(const ImeMenuListView&) = delete; |
| 261 | ImeMenuListView& operator=(const ImeMenuListView&) = delete; |
| 262 | |
| 263 | ~ImeMenuListView() override = default; |
Andrew Lee | c99ea55 | 2019-05-21 20:42:16 | [diff] [blame] | 264 | |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 265 | private: |
| 266 | class Delegate : public DetailedViewDelegate { |
| 267 | public: |
| 268 | Delegate() : DetailedViewDelegate(nullptr /* tray_controller */) {} |
| 269 | |
| 270 | // DetailedViewDelegate: |
| 271 | void TransitionToMainView(bool restore_focus) override {} |
| 272 | void CloseBubble() override {} |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 273 | |
Jiaming Cheng | 4e74168 | 2021-02-18 22:57:55 | [diff] [blame] | 274 | gfx::Insets GetInsetsForDetailedView() const override { |
| 275 | return gfx::Insets(); |
| 276 | } |
| 277 | |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 278 | private: |
| 279 | DISALLOW_COPY_AND_ASSIGN(Delegate); |
| 280 | }; |
| 281 | |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 282 | explicit ImeMenuListView(std::unique_ptr<Delegate> delegate) |
minch | ae720619 | 2020-11-03 20:51:41 | [diff] [blame] | 283 | : ImeListView(delegate.get()) { |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 284 | set_should_focus_ime_after_selection_with_keyboard(true); |
| 285 | delegate_ = std::move(delegate); |
Tetsui Ohkubo | b879459d | 2018-06-11 02:41:16 | [diff] [blame] | 286 | } |
Tetsui Ohkubo | cd22261 | 2018-05-28 06:47:54 | [diff] [blame] | 287 | |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 288 | // ImeListView: |
azurewei | 29b403d | 2016-12-08 03:40:00 | [diff] [blame] | 289 | void Layout() override { |
| 290 | gfx::Range height_range = GetImeListViewRange(); |
estade | 252bd536 | 2017-02-07 23:40:01 | [diff] [blame] | 291 | scroller()->ClipHeightTo(height_range.start(), height_range.end()); |
azurewei | 29b403d | 2016-12-08 03:40:00 | [diff] [blame] | 292 | ImeListView::Layout(); |
| 293 | } |
| 294 | |
Tetsui Ohkubo | bd07ddd | 2019-01-17 03:35:58 | [diff] [blame] | 295 | std::unique_ptr<Delegate> delegate_; |
azurewei | 29b403d | 2016-12-08 03:40:00 | [diff] [blame] | 296 | }; |
| 297 | |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 298 | BEGIN_METADATA(ImeMenuListView, ImeListView) |
| 299 | END_METADATA |
| 300 | |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 301 | } // namespace |
| 302 | |
James Cook | 840177e | 2017-05-25 02:20:01 | [diff] [blame] | 303 | ImeMenuTray::ImeMenuTray(Shelf* shelf) |
| 304 | : TrayBackgroundView(shelf), |
James Cook | bb02673 | 2017-06-09 23:01:55 | [diff] [blame] | 305 | ime_controller_(Shell::Get()->ime_controller()), |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 306 | label_(nullptr), |
| 307 | image_view_(nullptr), |
azurewei | e266449 | 2016-12-29 00:30:42 | [diff] [blame] | 308 | keyboard_suppressed_(false), |
azurewei | e876159 | 2017-05-17 03:16:46 | [diff] [blame] | 309 | show_bubble_after_keyboard_hidden_(false), |
Blake O'Hare | f61c66e | 2017-10-05 01:55:49 | [diff] [blame] | 310 | is_emoji_enabled_(false), |
| 311 | is_handwriting_enabled_(false), |
Jeremy Roman | 47d432e | 2019-08-20 14:24:00 | [diff] [blame] | 312 | is_voice_enabled_(false) { |
James Cook | bb02673 | 2017-06-09 23:01:55 | [diff] [blame] | 313 | DCHECK(ime_controller_); |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 314 | CreateLabel(); |
sky | 5b45ed8 | 2017-03-27 02:54:23 | [diff] [blame] | 315 | SystemTrayNotifier* tray_notifier = Shell::Get()->system_tray_notifier(); |
azurewei | 1fb9e77 | 2016-11-23 06:29:11 | [diff] [blame] | 316 | tray_notifier->AddIMEObserver(this); |
| 317 | tray_notifier->AddVirtualKeyboardObserver(this); |
Tetsui Ohkubo | 852abe6 | 2018-10-03 02:52:27 | [diff] [blame] | 318 | |
| 319 | // Show the tray even if virtual keyboard is shown. (Other tray buttons will |
| 320 | // be hidden). |
| 321 | set_show_with_virtual_keyboard(true); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | ImeMenuTray::~ImeMenuTray() { |
azurewei | c6200ab | 2016-08-26 21:42:30 | [diff] [blame] | 325 | if (bubble_) |
yawano | 66c305b | 2017-06-27 00:37:14 | [diff] [blame] | 326 | bubble_->bubble_view()->ResetDelegate(); |
sky | 5b45ed8 | 2017-03-27 02:54:23 | [diff] [blame] | 327 | SystemTrayNotifier* tray_notifier = Shell::Get()->system_tray_notifier(); |
azurewei | 1fb9e77 | 2016-11-23 06:29:11 | [diff] [blame] | 328 | tray_notifier->RemoveIMEObserver(this); |
| 329 | tray_notifier->RemoveVirtualKeyboardObserver(this); |
Darren Shen | cb250844 | 2019-07-03 21:48:23 | [diff] [blame] | 330 | auto* keyboard_controller = keyboard::KeyboardUIController::Get(); |
Steven Bennetts | 137a18e | 2018-10-10 19:13:45 | [diff] [blame] | 331 | if (keyboard_controller->HasObserver(this)) |
azurewei | 886f648 | 2017-01-07 08:38:44 | [diff] [blame] | 332 | keyboard_controller->RemoveObserver(this); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 333 | } |
| 334 | |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 335 | void ImeMenuTray::ShowImeMenuBubbleInternal() { |
James Cook | 76e9205 | 2018-09-21 23:10:30 | [diff] [blame] | 336 | TrayBubbleView::InitParams init_params; |
jamescook | c330160 | 2017-05-30 21:49:28 | [diff] [blame] | 337 | init_params.delegate = this; |
| 338 | init_params.parent_window = GetBubbleWindowContainer(); |
| 339 | init_params.anchor_view = GetBubbleAnchor(); |
Manu Cornet | 588b54a | 2019-04-11 07:36:15 | [diff] [blame] | 340 | init_params.shelf_alignment = shelf()->alignment(); |
Anastasia Helfinstein | 94cd64a | 2020-04-09 18:31:42 | [diff] [blame] | 341 | init_params.preferred_width = kTrayMenuWidth; |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 342 | init_params.close_on_deactivate = true; |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 343 | init_params.has_shadow = false; |
| 344 | init_params.translucent = true; |
| 345 | init_params.corner_radius = kTrayItemCornerRadius; |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 346 | init_params.reroute_event_handler = true; |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 347 | |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 348 | auto setup_layered_view = [](views::View* view) { |
| 349 | view->SetPaintToLayer(); |
| 350 | view->layer()->SetFillsBoundsOpaquely(false); |
| 351 | }; |
| 352 | |
James Cook | 76e9205 | 2018-09-21 23:10:30 | [diff] [blame] | 353 | TrayBubbleView* bubble_view = new TrayBubbleView(init_params); |
estade | 3acb088db | 2016-11-16 18:31:30 | [diff] [blame] | 354 | bubble_view->set_anchor_view_insets(GetBubbleAnchorInsets()); |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 355 | bubble_view->set_margins(GetSecondaryBubbleInsets()); |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 356 | |
estade | a553b86b | 2017-03-29 19:04:55 | [diff] [blame] | 357 | // Add a title item with a separator on the top of the IME menu. |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 358 | setup_layered_view( |
| 359 | bubble_view->AddChildView(std::make_unique<ImeTitleView>())); |
azurewei | 92ccc5c | 2016-09-21 16:14:25 | [diff] [blame] | 360 | |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 361 | // Adds IME list to the bubble. |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 362 | ime_list_view_ = |
| 363 | bubble_view->AddChildView(std::make_unique<ImeMenuListView>()); |
azurewei | d0cea0b | 2017-02-07 02:15:48 | [diff] [blame] | 364 | ime_list_view_->Init(ShouldShowKeyboardToggle(), |
| 365 | ImeListView::SHOW_SINGLE_IME); |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 366 | setup_layered_view(ime_list_view_); |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 367 | |
Andre Le | bacf0ac1 | 2020-08-25 19:24:44 | [diff] [blame] | 368 | if (ShouldShowBottomButtons()) { |
Ahmed Mehfooz | 3a2573c | 2020-07-22 23:06:37 | [diff] [blame] | 369 | setup_layered_view( |
| 370 | bubble_view->AddChildView(std::make_unique<ImeButtonsView>( |
| 371 | this, is_emoji_enabled_, is_handwriting_enabled_, |
| 372 | is_voice_enabled_))); |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 373 | } |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 374 | |
Tetsui Ohkubo | 4c8f4342 | 2017-10-18 04:41:16 | [diff] [blame] | 375 | bubble_ = std::make_unique<TrayBubbleWrapper>(this, bubble_view, |
| 376 | false /* is_persistent */); |
mohsen | 4614a8c | 2016-11-14 19:08:20 | [diff] [blame] | 377 | SetIsActive(true); |
azurewei | e853e62 | 2016-08-27 10:52:09 | [diff] [blame] | 378 | } |
| 379 | |
Yuichiro Hanada | 2b66e9c | 2018-03-27 03:08:02 | [diff] [blame] | 380 | void ImeMenuTray::ShowKeyboardWithKeyset( |
Darren Shen | 7b13278 | 2019-12-10 04:36:06 | [diff] [blame] | 381 | chromeos::input_method::ImeKeyset keyset) { |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 382 | CloseBubble(); |
azurewei | 649030a2 | 2016-09-20 13:11:43 | [diff] [blame] | 383 | |
Steven Bennetts | edb5fa39 | 2018-10-18 17:47:52 | [diff] [blame] | 384 | Shell::Get() |
Darren Shen | 7daf3e1 | 2019-07-02 07:25:49 | [diff] [blame] | 385 | ->keyboard_controller() |
Steven Bennetts | edb5fa39 | 2018-10-18 17:47:52 | [diff] [blame] | 386 | ->virtual_keyboard_controller() |
| 387 | ->ForceShowKeyboardWithKeyset(keyset); |
azurewei | 649030a2 | 2016-09-20 13:11:43 | [diff] [blame] | 388 | } |
| 389 | |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 390 | bool ImeMenuTray::ShouldShowBottomButtons() { |
azurewei | 1c4c4e8 | 2017-01-10 04:47:18 | [diff] [blame] | 391 | // Emoji, handwriting and voice input is not supported for these cases: |
Elly Fong-Jones | c00b17c | 2019-02-20 14:32:22 | [diff] [blame] | 392 | // 1) third party IME extensions. |
| 393 | // 2) login/lock screen. |
| 394 | // 3) password input client. |
Blake O'Hare | f61c66e | 2017-10-05 01:55:49 | [diff] [blame] | 395 | |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 396 | bool should_show_buttom_buttoms = |
Blake O'Hare | f61c66e | 2017-10-05 01:55:49 | [diff] [blame] | 397 | ime_controller_->is_extra_input_options_enabled() && |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 398 | !ime_controller_->current_ime().third_party && !IsInLoginOrLockScreen() && |
| 399 | !IsInPasswordInputContext(); |
| 400 | |
| 401 | if (!should_show_buttom_buttoms) { |
Blake O'Hare | f61c66e | 2017-10-05 01:55:49 | [diff] [blame] | 402 | is_emoji_enabled_ = is_handwriting_enabled_ = is_voice_enabled_ = false; |
azurewei | 079691f | 2017-06-30 15:04:18 | [diff] [blame] | 403 | return false; |
| 404 | } |
| 405 | |
Blake O'Hare | f61c66e | 2017-10-05 01:55:49 | [diff] [blame] | 406 | is_emoji_enabled_ = ime_controller_->is_emoji_enabled(); |
| 407 | is_handwriting_enabled_ = ime_controller_->is_handwriting_enabled(); |
| 408 | is_voice_enabled_ = ime_controller_->is_voice_enabled(); |
| 409 | |
| 410 | return is_emoji_enabled_ || is_handwriting_enabled_ || is_voice_enabled_; |
azurewei | 23b7cdb0 | 2016-11-08 04:16:57 | [diff] [blame] | 411 | } |
| 412 | |
azurewei | 1fb9e77 | 2016-11-23 06:29:11 | [diff] [blame] | 413 | bool ImeMenuTray::ShouldShowKeyboardToggle() const { |
Anatoliy Potapchuk | e368758 | 2020-09-08 22:50:32 | [diff] [blame] | 414 | return keyboard_suppressed_ && !Shell::Get() |
| 415 | ->accessibility_controller() |
| 416 | ->virtual_keyboard() |
| 417 | .enabled(); |
azurewei | 1fb9e77 | 2016-11-23 06:29:11 | [diff] [blame] | 418 | } |
| 419 | |
Ahmed Mehfooz | 9f4dc13 | 2020-11-12 03:10:49 | [diff] [blame] | 420 | void ImeMenuTray::OnThemeChanged() { |
| 421 | TrayBackgroundView::OnThemeChanged(); |
| 422 | UpdateTrayLabel(); |
| 423 | } |
| 424 | |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame^] | 425 | std::u16string ImeMenuTray::GetAccessibleNameForTray() { |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 426 | return l10n_util::GetStringUTF16(IDS_ASH_IME_MENU_ACCESSIBLE_NAME); |
| 427 | } |
| 428 | |
Toni Barzic | e4627b85 | 2020-06-04 02:22:49 | [diff] [blame] | 429 | void ImeMenuTray::HandleLocaleChange() { |
| 430 | if (image_view_) { |
Allen Bauer | d9daac11 | 2020-09-15 21:54:04 | [diff] [blame] | 431 | image_view_->SetTooltipText( |
Toni Barzic | e4627b85 | 2020-06-04 02:22:49 | [diff] [blame] | 432 | l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME)); |
| 433 | } |
| 434 | |
| 435 | if (label_) |
| 436 | label_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME)); |
| 437 | } |
| 438 | |
James Cook | 76e9205 | 2018-09-21 23:10:30 | [diff] [blame] | 439 | void ImeMenuTray::HideBubbleWithView(const TrayBubbleView* bubble_view) { |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 440 | if (bubble_->bubble_view() == bubble_view) |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 441 | CloseBubble(); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 442 | } |
| 443 | |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 444 | void ImeMenuTray::ClickedOutsideBubble() { |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 445 | CloseBubble(); |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 446 | } |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 447 | |
| 448 | bool ImeMenuTray::PerformAction(const ui::Event& event) { |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 449 | if (event.IsMouseEvent() || event.IsGestureEvent()) { |
| 450 | UserMetricsRecorder::RecordUserClickOnTray( |
| 451 | LoginMetricsRecorder::TrayClickTarget::kImeTray); |
| 452 | } |
| 453 | return TrayBackgroundView::PerformAction(event); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 454 | } |
| 455 | |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 456 | void ImeMenuTray::CloseBubble() { |
| 457 | bubble_.reset(); |
| 458 | ime_list_view_ = nullptr; |
| 459 | SetIsActive(false); |
| 460 | shelf()->UpdateAutoHideState(); |
| 461 | } |
| 462 | |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 463 | void ImeMenuTray::ShowBubble() { |
Darren Shen | cb250844 | 2019-07-03 21:48:23 | [diff] [blame] | 464 | auto* keyboard_controller = keyboard::KeyboardUIController::Get(); |
Steven Bennetts | 137a18e | 2018-10-10 19:13:45 | [diff] [blame] | 465 | if (keyboard_controller->IsKeyboardVisible()) { |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 466 | show_bubble_after_keyboard_hidden_ = true; |
| 467 | keyboard_controller->AddObserver(this); |
Blake O'Hare | f768600e0 | 2018-06-13 10:01:01 | [diff] [blame] | 468 | keyboard_controller->HideKeyboardExplicitlyBySystem(); |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 469 | } else { |
MinChen | da04127 | 2017-07-27 17:20:10 | [diff] [blame] | 470 | base::RecordAction(base::UserMetricsAction("Tray_ImeMenu_Opened")); |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 471 | ShowImeMenuBubbleInternal(); |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 472 | } |
| 473 | } |
| 474 | |
James Cook | 76e9205 | 2018-09-21 23:10:30 | [diff] [blame] | 475 | TrayBubbleView* ImeMenuTray::GetBubbleView() { |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 476 | return bubble_ ? bubble_->GetBubbleView() : nullptr; |
| 477 | } |
| 478 | |
| 479 | views::Widget* ImeMenuTray::GetBubbleWidget() const { |
| 480 | return bubble_ ? bubble_->GetBubbleWidget() : nullptr; |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 481 | } |
| 482 | |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 483 | void ImeMenuTray::OnIMERefresh() { |
| 484 | UpdateTrayLabel(); |
azurewei | c6200ab | 2016-08-26 21:42:30 | [diff] [blame] | 485 | if (bubble_ && ime_list_view_) { |
James Cook | 23f56b7 | 2017-06-21 00:38:28 | [diff] [blame] | 486 | ime_list_view_->Update(ime_controller_->current_ime().id, |
| 487 | ime_controller_->available_imes(), |
James Cook | f0c78fc | 2017-06-15 14:42:55 | [diff] [blame] | 488 | ime_controller_->current_ime_menu_items(), false, |
azurewei | c6200ab | 2016-08-26 21:42:30 | [diff] [blame] | 489 | ImeListView::SHOW_SINGLE_IME); |
| 490 | } |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 491 | } |
| 492 | |
| 493 | void ImeMenuTray::OnIMEMenuActivationChanged(bool is_activated) { |
Tim Song | 21921b98 | 2019-11-08 00:57:14 | [diff] [blame] | 494 | SetVisiblePreferred(is_activated); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 495 | if (is_activated) |
| 496 | UpdateTrayLabel(); |
| 497 | else |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 498 | CloseBubble(); |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 499 | } |
| 500 | |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame^] | 501 | std::u16string ImeMenuTray::GetAccessibleNameForBubble() { |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 502 | return l10n_util::GetStringUTF16(IDS_ASH_IME_MENU_ACCESSIBLE_NAME); |
| 503 | } |
| 504 | |
yawano | 66c305b | 2017-06-27 00:37:14 | [diff] [blame] | 505 | bool ImeMenuTray::ShouldEnableExtraKeyboardAccessibility() { |
Anatoliy Potapchuk | e368758 | 2020-09-08 22:50:32 | [diff] [blame] | 506 | return Shell::Get()->accessibility_controller()->spoken_feedback().enabled(); |
yawano | 66c305b | 2017-06-27 00:37:14 | [diff] [blame] | 507 | } |
| 508 | |
James Cook | 76e9205 | 2018-09-21 23:10:30 | [diff] [blame] | 509 | void ImeMenuTray::HideBubble(const TrayBubbleView* bubble_view) { |
azurewei | 4ecb844 | 2016-07-28 06:06:09 | [diff] [blame] | 510 | HideBubbleWithView(bubble_view); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 511 | } |
| 512 | |
Darren Shen | bb5851b | 2018-07-19 07:04:06 | [diff] [blame] | 513 | void ImeMenuTray::OnKeyboardHidden(bool is_temporary_hide) { |
azurewei | e266449 | 2016-12-29 00:30:42 | [diff] [blame] | 514 | if (show_bubble_after_keyboard_hidden_) { |
| 515 | show_bubble_after_keyboard_hidden_ = false; |
Darren Shen | cb250844 | 2019-07-03 21:48:23 | [diff] [blame] | 516 | auto* keyboard_controller = keyboard::KeyboardUIController::Get(); |
Darren Shen | 96c91253 | 2018-05-22 01:20:38 | [diff] [blame] | 517 | keyboard_controller->RemoveObserver(this); |
azurewei | e266449 | 2016-12-29 00:30:42 | [diff] [blame] | 518 | |
Ahmed Mehfooz | 15cebdd | 2021-03-03 01:07:07 | [diff] [blame] | 519 | ShowImeMenuBubbleInternal(); |
azurewei | e266449 | 2016-12-29 00:30:42 | [diff] [blame] | 520 | return; |
| 521 | } |
Darren Shen | a4bf749 | 2018-03-16 04:25:52 | [diff] [blame] | 522 | } |
| 523 | |
azurewei | 1fb9e77 | 2016-11-23 06:29:11 | [diff] [blame] | 524 | void ImeMenuTray::OnKeyboardSuppressionChanged(bool suppressed) { |
| 525 | if (suppressed != keyboard_suppressed_ && bubble_) |
minch | d8633937 | 2017-07-18 20:07:50 | [diff] [blame] | 526 | CloseBubble(); |
azurewei | 1fb9e77 | 2016-11-23 06:29:11 | [diff] [blame] | 527 | keyboard_suppressed_ = suppressed; |
| 528 | } |
| 529 | |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 530 | void ImeMenuTray::UpdateTrayLabel() { |
Darren Shen | 7b13278 | 2019-12-10 04:36:06 | [diff] [blame] | 531 | const ImeInfo& current_ime = ime_controller_->current_ime(); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 532 | |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 533 | // For ARC IMEs, we use the globe icon instead of the short name of the active |
| 534 | // IME. |
| 535 | if (chromeos::extension_ime_util::IsArcIME(current_ime.id)) { |
| 536 | CreateImageView(); |
minch | bee2e31 | 2019-08-15 21:52:40 | [diff] [blame] | 537 | image_view_->SetImage(gfx::CreateVectorIcon( |
Xiaoqian Dai | f125208 | 2020-06-16 23:13:36 | [diff] [blame] | 538 | kShelfGlobeIcon, |
| 539 | AshColorProvider::Get()->GetContentLayerColor( |
minch | 5847c6f | 2020-09-08 01:13:17 | [diff] [blame] | 540 | AshColorProvider::ContentLayerType::kIconColorPrimary))); |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 541 | return; |
| 542 | } |
| 543 | |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 544 | // Updates the tray label based on the current input method. |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 545 | CreateLabel(); |
Ahmed Mehfooz | 9f4dc13 | 2020-11-12 03:10:49 | [diff] [blame] | 546 | |
| 547 | label_->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( |
| 548 | AshColorProvider::ContentLayerType::kIconColorPrimary)); |
| 549 | |
James Cook | f0c78fc | 2017-06-15 14:42:55 | [diff] [blame] | 550 | if (current_ime.third_party) |
| 551 | label_->SetText(current_ime.short_name + base::UTF8ToUTF16("*")); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 552 | else |
James Cook | f0c78fc | 2017-06-15 14:42:55 | [diff] [blame] | 553 | label_->SetText(current_ime.short_name); |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 554 | } |
| 555 | |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 556 | void ImeMenuTray::CreateLabel() { |
| 557 | // Do nothing if label_ is already created. |
| 558 | if (label_) |
| 559 | return; |
| 560 | // Remove image_view_ at first if it's created. |
| 561 | if (image_view_) { |
| 562 | tray_container()->RemoveChildView(image_view_); |
| 563 | image_view_ = nullptr; |
| 564 | } |
| 565 | label_ = new ImeMenuLabel(); |
| 566 | SetupLabelForTray(label_); |
| 567 | label_->SetElideBehavior(gfx::TRUNCATE); |
| 568 | label_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME)); |
| 569 | tray_container()->AddChildView(label_); |
| 570 | } |
| 571 | |
| 572 | void ImeMenuTray::CreateImageView() { |
| 573 | // Do nothing if image_view_ is already created. |
| 574 | if (image_view_) |
| 575 | return; |
| 576 | // Remove label_ at first if it's created. |
| 577 | if (label_) { |
| 578 | tray_container()->RemoveChildView(label_); |
| 579 | label_ = nullptr; |
| 580 | } |
| 581 | image_view_ = new ImeMenuImageView(); |
Allen Bauer | d9daac11 | 2020-09-15 21:54:04 | [diff] [blame] | 582 | image_view_->SetTooltipText( |
Yuichiro Hanada | 81b1342 | 2018-07-10 05:49:41 | [diff] [blame] | 583 | l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_IME)); |
| 584 | tray_container()->AddChildView(image_view_); |
| 585 | } |
| 586 | |
Shengsong Tan | 64ce634 | 2020-12-23 03:44:33 | [diff] [blame] | 587 | BEGIN_METADATA(ImeMenuTray, TrayBackgroundView) |
| 588 | END_METADATA |
| 589 | |
azurewei | c0b0a4f | 2016-07-15 08:56:12 | [diff] [blame] | 590 | } // namespace ash |