Index: chrome/browser/speech/speech_input_extension_notification_ui.cc |
diff --git a/chrome/browser/speech/speech_input_extension_notification_ui.cc b/chrome/browser/speech/speech_input_extension_notification_ui.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..130a468e4bc13079b492ee59bdf08836aeffde49 |
--- /dev/null |
+++ b/chrome/browser/speech/speech_input_extension_notification_ui.cc |
@@ -0,0 +1,166 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/speech/speech_input_extension_notification_ui.h" |
+ |
+#include "base/lazy_instance.h" |
+#include "base/utf_string_conversions.h" |
+#include "chrome/browser/browser_process.h" |
+#include "chrome/browser/status_icons/status_icon.h" |
+#include "chrome/browser/status_icons/status_tray.h" |
+#include "chrome/common/extensions/extension.h" |
+#include "grit/chromium_strings.h" |
+#include "grit/generated_resources.h" |
+#include "grit/theme_resources.h" |
+#include "ui/base/l10n/l10n_util.h" |
+#include "ui/base/resource/resource_bundle.h" |
+#include "ui/gfx/canvas_skia.h" |
+#include "ui/gfx/rect.h" |
+#include "ui/gfx/skbitmap_operations.h" |
+ |
+namespace { |
+ |
+// A lazily initialized singleton to hold all the images used by the |
+// notification icon and safely destroy them on exit. |
+class NotificationTrayImages { |
+ public: |
+ SkBitmap* mic_full() { return mic_full_; } |
+ SkBitmap* mic_empty() { return mic_empty_; } |
+ SkBitmap* balloon_icon() { return balloon_icon_; } |
+ |
+ private: |
+ // Private constructor to enforce singleton. |
+ friend struct base::DefaultLazyInstanceTraits<NotificationTrayImages>; |
+ NotificationTrayImages(); |
+ |
+ // These bitmaps are owned by ResourceBundle and need not be destroyed. |
+ SkBitmap* mic_full_; // Tray mic image with full volume. |
+ SkBitmap* mic_empty_; // Tray mic image with zero volume. |
+ SkBitmap* balloon_icon_; // High resolution mic for the notification balloon. |
+}; |
+ |
+NotificationTrayImages::NotificationTrayImages() { |
+ int icon_ids[] = { |
+#if defined(OS_WIN) |
+ IDR_SPEECH_INPUT_TRAY_WINDOWS_MIC_EMPTY, |
Satish
2011/11/07 18:16:31
any reason why we need 3 different set of IDs? cou
Leandro Graciá Gil
2011/11/07 19:34:42
Done.
|
+ IDR_SPEECH_INPUT_TRAY_WINDOWS_MIC_FULL, |
+#elif defined(OS_MACOSX) |
+ IDR_SPEECH_INPUT_TRAY_MACOSX_MIC_EMPTY, |
+ IDR_SPEECH_INPUT_TRAY_MACOSX_MIC_FULL, |
+#else |
Satish
2011/11/07 18:16:31
can you make this into an explicit linux & chrome
Leandro Graciá Gil
2011/11/07 19:34:42
Done.
|
+ // Linux and Chrome OS icons. |
+ IDR_SPEECH_INPUT_TRAY_LINUX_MIC_EMPTY, |
+ IDR_SPEECH_INPUT_TRAY_LINUX_MIC_FULL, |
+#endif |
+ }; |
+ |
+ mic_empty_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_ids[0]); |
+ mic_full_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_ids[1]); |
+ balloon_icon_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
+ IDR_SPEECH_INPUT_TRAY_BALLOON_ICON); |
+} |
+ |
+base::LazyInstance<NotificationTrayImages> g_images(base::LINKER_INITIALIZED); |
+ |
+} // namespace |
+ |
+SpeechInputExtensionNotificationUI::SpeechInputExtensionNotificationUI( |
+ Profile* profile) |
+ : profile_(profile), |
+ tray_icon_(NULL) { |
+ mic_image_.reset(new SkBitmap()); |
+ mic_image_->setConfig(SkBitmap::kARGB_8888_Config, |
+ g_images.Get().mic_empty()->width(), |
+ g_images.Get().mic_empty()->height()); |
+ mic_image_->allocPixels(); |
+ |
+ buffer_image_.reset(new SkBitmap()); |
+ buffer_image_->setConfig(SkBitmap::kARGB_8888_Config, |
+ g_images.Get().mic_empty()->width(), |
+ g_images.Get().mic_empty()->height()); |
+ buffer_image_->allocPixels(); |
+} |
+ |
+SpeechInputExtensionNotificationUI::~SpeechInputExtensionNotificationUI() { |
+} |
+ |
+void SpeechInputExtensionNotificationUI::DrawVolume( |
+ SkCanvas* canvas, |
+ const SkBitmap& bitmap, |
+ float volume) { |
+ buffer_image_->eraseARGB(0, 0, 0, 0); |
+ |
+ int width = mic_image_->width(); |
+ int height = mic_image_->height(); |
+ SkCanvas buffer_canvas(*buffer_image_); |
+ |
+ buffer_canvas.save(); |
Satish
2011/11/07 18:16:31
since this is a scoped canvas and gets destroyed o
Leandro Graciá Gil
2011/11/07 19:34:42
Done.
|
+ const int kVolumeSteps = 6; |
Satish
2011/11/07 18:16:31
move this to an anonymous namespace constant
Leandro Graciá Gil
2011/11/07 19:34:42
Done.
|
+ SkScalar clip_top = |
+ (((1.0f - volume) * (height * (kVolumeSteps + 1))) - height) / |
+ kVolumeSteps; |
+ buffer_canvas.clipRect(SkRect::MakeLTRB(0, clip_top, |
+ SkIntToScalar(width), SkIntToScalar(height))); |
+ buffer_canvas.drawBitmap(bitmap, 0, 0); |
+ buffer_canvas.restore(); |
+ |
+ canvas->drawBitmap(*buffer_image_.get(), 0, 0); |
+} |
+ |
+void SpeechInputExtensionNotificationUI::SetVUMeterVolume(float volume) { |
+ if (!tray_icon_) |
+ return; |
+ |
+ mic_image_->eraseARGB(0, 0, 0, 0); |
+ SkCanvas canvas(*mic_image_); |
+ |
+ // Draw the empty volume image first and the current volume image on top. |
+ canvas.drawBitmap(*g_images.Get().mic_empty(), 0, 0); |
+ DrawVolume(&canvas, *g_images.Get().mic_full(), volume); |
+ |
+ tray_icon_->SetImage(*mic_image_.get()); |
+} |
+ |
+void SpeechInputExtensionNotificationUI::Show(const Extension* extension, |
+ bool show_balloon) { |
+ if (StatusTray* status_tray = g_browser_process->status_tray()) { |
+ DCHECK(!tray_icon_); |
+ tray_icon_ = status_tray->CreateStatusIcon(); |
+ DCHECK(tray_icon_); |
+ VLOG(1) << "Tray icon added."; |
+ |
+ SetVUMeterVolume(0.0f); |
+ tray_icon_->SetToolTip(l10n_util::GetStringFUTF16( |
+ IDS_SPEECH_INPUT_TRAY_TOOLTIP, |
+ UTF8ToUTF16(extension->name()), |
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
+ } else { |
+ VLOG(1) << "This platform doesn't support notification icons."; |
+ return; |
+ } |
+ |
+ if (show_balloon) |
+ ShowNotificationBalloon(extension); |
+} |
+ |
+void SpeechInputExtensionNotificationUI::Hide() { |
+ if (StatusTray* status_tray = g_browser_process->status_tray()) { |
+ DCHECK(tray_icon_); |
+ status_tray->RemoveStatusIcon(tray_icon_); |
+ tray_icon_ = NULL; |
+ VLOG(1) << "Tray icon removed."; |
+ } |
+} |
+ |
+void SpeechInputExtensionNotificationUI::ShowNotificationBalloon( |
+ const Extension* extension) { |
+ string16 title = l10n_util::GetStringUTF16( |
+ IDS_SPEECH_INPUT_TRAY_BALLOON_TITLE); |
+ string16 message = l10n_util::GetStringFUTF16( |
+ IDS_SPEECH_INPUT_TRAY_BALLOON_BODY, |
+ UTF8ToUTF16(extension->name()), |
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); |
+ |
+ tray_icon_->DisplayBalloon(*g_images.Get().balloon_icon(), title, message); |
+} |