Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Side by Side Diff: chrome/browser/chromeos/status/caps_lock_menu_button.cc

Issue 10056001: chromeos: Remove old status-area related code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/status/caps_lock_menu_button.h"
6
7 #include <string>
8
9 #include "base/chromeos/chromeos_version.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
12 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
13 #include "chrome/browser/chromeos/login/screen_locker.h"
14 #include "chrome/browser/chromeos/status/status_area_bubble.h"
15 #include "chrome/browser/chromeos/status/status_area_view_chromeos.h"
16 #include "chrome/browser/chromeos/view_ids.h"
17 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/pref_names.h"
21 #include "content/public/browser/notification_service.h"
22 #include "grit/generated_resources.h"
23 #include "grit/theme_resources.h"
24 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/base/resource/resource_bundle.h"
26 #include "ui/gfx/image/image.h"
27 #include "ui/views/controls/image_view.h"
28 #include "ui/views/controls/menu/menu_item_view.h"
29 #include "ui/views/controls/menu/menu_runner.h"
30 #include "ui/views/controls/menu/submenu_view.h"
31 #include "ui/views/widget/widget.h"
32
33 namespace {
34
35 const size_t kMaxBubbleCount = 3;
36
37 PrefService* GetPrefService() {
38 Profile* profile = ProfileManager::GetDefaultProfile();
39 if (profile)
40 return profile->GetPrefs();
41 return NULL;
42 }
43
44 views::ImageView* CreateImageViewWithCapsLockIcon() {
45 const gfx::Image& image =
46 ResourceBundle::GetSharedInstance().GetImageNamed(IDR_CAPS_LOCK_ICON);
47 views::ImageView* image_view = new views::ImageView;
48 image_view->SetImage(image.ToSkBitmap());
49 return image_view;
50 }
51
52 } // namespace
53
54 namespace chromeos {
55
56 ////////////////////////////////////////////////////////////////////////////////
57 // CapsLockMenuButton
58
59 CapsLockMenuButton::CapsLockMenuButton(StatusAreaButton::Delegate* delegate)
60 : StatusAreaButton(delegate, this),
61 initialized_prefs_(false),
62 status_(NULL),
63 should_show_bubble_(true),
64 bubble_count_(0) {
65 set_id(VIEW_ID_STATUS_BUTTON_CAPS_LOCK);
66
67 if (StatusAreaViewChromeos::IsBrowserMode())
68 InitializePrefMember();
69
70 SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(
71 IDR_STATUSBAR_CAPS_LOCK));
72 UpdateAccessibleName();
73
74 input_method::InputMethodManager* ime_manager =
75 input_method::InputMethodManager::GetInstance();
76 UpdateUIFromCurrentCapsLock(ime_manager->GetXKeyboard()->CapsLockIsEnabled());
77
78 // Status bar should be initialized after SystemKeyEventListener on the
79 // device. SystemKeyEventListener is never initialized on chrome for cros
80 // running on linux.
81 DCHECK(SystemKeyEventListener::GetInstance() ||
82 !base::chromeos::IsRunningOnChromeOS());
83 if (SystemKeyEventListener::GetInstance())
84 SystemKeyEventListener::GetInstance()->AddCapsLockObserver(this);
85
86 #if defined(USE_ASH)
87 if (StatusAreaViewChromeos::IsLoginMode()) {
88 // See comments in InputMethodMenu::InputMethodMenu().
89 registrar_.Add(this,
90 chrome::NOTIFICATION_SESSION_STARTED,
91 content::NotificationService::AllSources());
92 }
93 #endif
94 }
95
96 CapsLockMenuButton::~CapsLockMenuButton() {
97 if (SystemKeyEventListener::GetInstance())
98 SystemKeyEventListener::GetInstance()->RemoveCapsLockObserver(this);
99 }
100
101 ////////////////////////////////////////////////////////////////////////////////
102 // views::View implementation:
103
104 void CapsLockMenuButton::OnLocaleChanged() {
105 input_method::InputMethodManager* ime_manager =
106 input_method::InputMethodManager::GetInstance();
107 UpdateUIFromCurrentCapsLock(ime_manager->GetXKeyboard()->CapsLockIsEnabled());
108 }
109
110 ////////////////////////////////////////////////////////////////////////////////
111 // views::MenuDelegate implementation:
112
113 string16 CapsLockMenuButton::GetLabel(int id) const {
114 return string16();
115 }
116
117 ////////////////////////////////////////////////////////////////////////////////
118 // views::MenuButtonListener implementation:
119
120 void CapsLockMenuButton::OnMenuButtonClicked(views::View* source,
121 const gfx::Point& point) {
122 static const int kDummyCommandId = 1000;
123
124 if (IsBubbleShown())
125 HideBubble();
126
127 views::MenuItemView* menu = new views::MenuItemView(this);
128 // MenuRunner takes ownership of |menu|.
129 menu_runner_.reset(new views::MenuRunner(menu));
130 views::MenuItemView* submenu = menu->AppendMenuItem(
131 kDummyCommandId,
132 string16(),
133 views::MenuItemView::NORMAL);
134 status_ = new StatusAreaBubbleContentView(CreateImageViewWithCapsLockIcon(),
135 GetText());
136 submenu->AddChildView(status_);
137 menu->CreateSubmenu()->set_resize_open_menu(true);
138 menu->SetMargins(0, 0);
139 submenu->SetMargins(0, 0);
140 menu->ChildrenChanged();
141
142 gfx::Point screen_location;
143 views::View::ConvertPointToScreen(source, &screen_location);
144 gfx::Rect bounds(screen_location, source->size());
145 if (menu_runner_->RunMenuAt(
146 source->GetWidget()->GetTopLevelWidget(), this, bounds,
147 views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) ==
148 views::MenuRunner::MENU_DELETED)
149 return;
150 status_ = NULL;
151 menu_runner_.reset(NULL);
152 }
153
154 ////////////////////////////////////////////////////////////////////////////////
155 // SystemKeyEventListener::CapsLockObserver implementation
156
157 void CapsLockMenuButton::OnCapsLockChange(bool enabled) {
158 if (!enabled && !HasCapsLock() && bubble_count_ > 0) {
159 // Both shift keys are pressed. We can assume that the user now recognizes
160 // how to turn off Caps Lock.
161 should_show_bubble_ = false;
162 }
163
164 // Update the indicator.
165 UpdateUIFromCurrentCapsLock(enabled);
166
167 // Update the drop-down menu and bubble. Since the constructor also calls
168 // UpdateUIFromCurrentCapsLock, we shouldn't do this in the function.
169 if (enabled && IsMenuShown()) {
170 // Update the drop-down menu if it's already shown.
171 status_->SetMessage(GetText());
172 } else if (!enabled && IsMenuShown()) {
173 HideMenu();
174 }
175 if (enabled)
176 MaybeShowBubble();
177 else if (!enabled && IsBubbleShown())
178 HideBubble();
179 }
180
181 ////////////////////////////////////////////////////////////////////////////////
182 // content::NotificationObserver implementation
183
184 void CapsLockMenuButton::Observe(int type,
185 const content::NotificationSource& source,
186 const content::NotificationDetails& details) {
187 switch (type) {
188 case chrome::NOTIFICATION_PREF_CHANGED:
189 UpdateAccessibleName();
190 break;
191 case chrome::NOTIFICATION_SESSION_STARTED:
192 InitializePrefMember();
193 break;
194 }
195 }
196
197 void CapsLockMenuButton::UpdateAccessibleName() {
198 int id = IDS_STATUSBAR_CAPS_LOCK_ENABLED_PRESS_SHIFT_AND_SEARCH_KEYS;
199 if (HasCapsLock())
200 id = IDS_STATUSBAR_CAPS_LOCK_ENABLED_PRESS_SEARCH;
201 SetAccessibleName(l10n_util::GetStringUTF16(id));
202 }
203
204 string16 CapsLockMenuButton::GetText() const {
205 int id = IDS_STATUSBAR_CAPS_LOCK_ENABLED_PRESS_SHIFT_AND_SEARCH_KEYS;
206 if (HasCapsLock())
207 id = IDS_STATUSBAR_CAPS_LOCK_ENABLED_PRESS_SEARCH;
208 return l10n_util::GetStringUTF16(id);
209 }
210
211 void CapsLockMenuButton::UpdateUIFromCurrentCapsLock(bool enabled) {
212 SetVisible(enabled);
213 SchedulePaint();
214 }
215
216 bool CapsLockMenuButton::IsMenuShown() const {
217 return menu_runner_.get() && status_;
218 }
219
220 void CapsLockMenuButton::HideMenu() {
221 if (!IsMenuShown())
222 return;
223 menu_runner_->Cancel();
224 }
225
226 bool CapsLockMenuButton::IsBubbleShown() const {
227 return bubble_controller_.get() && bubble_controller_->IsBubbleShown();
228 }
229
230 void CapsLockMenuButton::MaybeShowBubble() {
231 if (IsBubbleShown() ||
232 // We've already shown the bubble |kMaxBubbleCount| times.
233 !should_show_bubble_ ||
234 // Don't show the bubble when Caps Lock key is available.
235 HasCapsLock() ||
236 // Don't show it when the status area is hidden.
237 (parent() && !parent()->visible()) ||
238 // Don't show the bubble when screen is locked as this results in two
239 // visible caps lock bubbles (crbug.com/105280). The greater problem of
240 // displaying bubbles from all caps lock menu buttons regardless of
241 // visibility is described in crbug.com/106776.
242 ScreenLocker::default_screen_locker())
243 return;
244
245 ++bubble_count_;
246 if (bubble_count_ > kMaxBubbleCount) {
247 should_show_bubble_ = false;
248 } else {
249 CreateAndShowBubble();
250 }
251 }
252
253 void CapsLockMenuButton::CreateAndShowBubble() {
254 if (IsBubbleShown()) {
255 NOTREACHED();
256 return;
257 }
258 bubble_controller_.reset(
259 StatusAreaBubbleController::ShowBubbleUnderViewForAWhile(
260 this,
261 new StatusAreaBubbleContentView(CreateImageViewWithCapsLockIcon(),
262 GetText())));
263 }
264
265 void CapsLockMenuButton::HideBubble() {
266 bubble_controller_.reset();
267 }
268
269 bool CapsLockMenuButton::HasCapsLock() const {
270 // A keyboard for Linux usually has Caps Lock.
271 if (!base::chromeos::IsRunningOnChromeOS())
272 return true;
273 // On the login screen, Caps Lock is not available.
274 if (!initialized_prefs_)
275 return false;
276
277 return remap_search_key_to_.GetValue() == input_method::kCapsLockKey;
278 }
279
280 void CapsLockMenuButton::InitializePrefMember() {
281 if (!initialized_prefs_) {
282 PrefService* prefs = GetPrefService();
283 if (prefs) {
284 initialized_prefs_ = true;
285 remap_search_key_to_.Init(
286 prefs::kLanguageXkbRemapSearchKeyTo, prefs, this);
287 }
288 }
289 }
290
291 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/status/caps_lock_menu_button.h ('k') | chrome/browser/chromeos/status/clock_menu_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698