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

Side by Side Diff: chrome/browser/speech/speech_input_extension_notification_ui.cc

Issue 8386074: Add a tray notification UI for speech input recording in the extension API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: requested file renames and api constants refactor. Created 9 years, 1 month 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) 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 #include "chrome/browser/speech/speech_input_extension_notification_ui.h"
6
7 #include "base/lazy_instance.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/status_icons/status_icon.h"
11 #include "chrome/browser/status_icons/status_tray.h"
12 #include "chrome/common/extensions/extension.h"
13 #include "grit/chromium_strings.h"
14 #include "grit/generated_resources.h"
15 #include "grit/theme_resources.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/canvas_skia.h"
19 #include "ui/gfx/rect.h"
20 #include "ui/gfx/skbitmap_operations.h"
21
22 namespace {
23
24 // A lazily initialized singleton to hold all the images used by the
25 // notification icon and safely destroy them on exit.
26 class NotificationTrayImages {
27 public:
28 SkBitmap* mic_full() { return mic_full_; }
29 SkBitmap* mic_empty() { return mic_empty_; }
30 SkBitmap* balloon_icon() { return balloon_icon_; }
31
32 private:
33 // Private constructor to enforce singleton.
34 friend struct base::DefaultLazyInstanceTraits<NotificationTrayImages>;
35 NotificationTrayImages();
36
37 // These bitmaps are owned by ResourceBundle and need not be destroyed.
38 SkBitmap* mic_full_; // Tray mic image with full volume.
39 SkBitmap* mic_empty_; // Tray mic image with zero volume.
40 SkBitmap* balloon_icon_; // High resolution mic for the notification balloon.
41 };
42
43 NotificationTrayImages::NotificationTrayImages() {
44 int icon_ids[] = {
45 #if defined(OS_WIN)
46 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.
47 IDR_SPEECH_INPUT_TRAY_WINDOWS_MIC_FULL,
48 #elif defined(OS_MACOSX)
49 IDR_SPEECH_INPUT_TRAY_MACOSX_MIC_EMPTY,
50 IDR_SPEECH_INPUT_TRAY_MACOSX_MIC_FULL,
51 #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.
52 // Linux and Chrome OS icons.
53 IDR_SPEECH_INPUT_TRAY_LINUX_MIC_EMPTY,
54 IDR_SPEECH_INPUT_TRAY_LINUX_MIC_FULL,
55 #endif
56 };
57
58 mic_empty_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_ids[0]);
59 mic_full_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_ids[1]);
60 balloon_icon_ = ResourceBundle::GetSharedInstance().GetBitmapNamed(
61 IDR_SPEECH_INPUT_TRAY_BALLOON_ICON);
62 }
63
64 base::LazyInstance<NotificationTrayImages> g_images(base::LINKER_INITIALIZED);
65
66 } // namespace
67
68 SpeechInputExtensionNotificationUI::SpeechInputExtensionNotificationUI(
69 Profile* profile)
70 : profile_(profile),
71 tray_icon_(NULL) {
72 mic_image_.reset(new SkBitmap());
73 mic_image_->setConfig(SkBitmap::kARGB_8888_Config,
74 g_images.Get().mic_empty()->width(),
75 g_images.Get().mic_empty()->height());
76 mic_image_->allocPixels();
77
78 buffer_image_.reset(new SkBitmap());
79 buffer_image_->setConfig(SkBitmap::kARGB_8888_Config,
80 g_images.Get().mic_empty()->width(),
81 g_images.Get().mic_empty()->height());
82 buffer_image_->allocPixels();
83 }
84
85 SpeechInputExtensionNotificationUI::~SpeechInputExtensionNotificationUI() {
86 }
87
88 void SpeechInputExtensionNotificationUI::DrawVolume(
89 SkCanvas* canvas,
90 const SkBitmap& bitmap,
91 float volume) {
92 buffer_image_->eraseARGB(0, 0, 0, 0);
93
94 int width = mic_image_->width();
95 int height = mic_image_->height();
96 SkCanvas buffer_canvas(*buffer_image_);
97
98 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.
99 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.
100 SkScalar clip_top =
101 (((1.0f - volume) * (height * (kVolumeSteps + 1))) - height) /
102 kVolumeSteps;
103 buffer_canvas.clipRect(SkRect::MakeLTRB(0, clip_top,
104 SkIntToScalar(width), SkIntToScalar(height)));
105 buffer_canvas.drawBitmap(bitmap, 0, 0);
106 buffer_canvas.restore();
107
108 canvas->drawBitmap(*buffer_image_.get(), 0, 0);
109 }
110
111 void SpeechInputExtensionNotificationUI::SetVUMeterVolume(float volume) {
112 if (!tray_icon_)
113 return;
114
115 mic_image_->eraseARGB(0, 0, 0, 0);
116 SkCanvas canvas(*mic_image_);
117
118 // Draw the empty volume image first and the current volume image on top.
119 canvas.drawBitmap(*g_images.Get().mic_empty(), 0, 0);
120 DrawVolume(&canvas, *g_images.Get().mic_full(), volume);
121
122 tray_icon_->SetImage(*mic_image_.get());
123 }
124
125 void SpeechInputExtensionNotificationUI::Show(const Extension* extension,
126 bool show_balloon) {
127 if (StatusTray* status_tray = g_browser_process->status_tray()) {
128 DCHECK(!tray_icon_);
129 tray_icon_ = status_tray->CreateStatusIcon();
130 DCHECK(tray_icon_);
131 VLOG(1) << "Tray icon added.";
132
133 SetVUMeterVolume(0.0f);
134 tray_icon_->SetToolTip(l10n_util::GetStringFUTF16(
135 IDS_SPEECH_INPUT_TRAY_TOOLTIP,
136 UTF8ToUTF16(extension->name()),
137 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
138 } else {
139 VLOG(1) << "This platform doesn't support notification icons.";
140 return;
141 }
142
143 if (show_balloon)
144 ShowNotificationBalloon(extension);
145 }
146
147 void SpeechInputExtensionNotificationUI::Hide() {
148 if (StatusTray* status_tray = g_browser_process->status_tray()) {
149 DCHECK(tray_icon_);
150 status_tray->RemoveStatusIcon(tray_icon_);
151 tray_icon_ = NULL;
152 VLOG(1) << "Tray icon removed.";
153 }
154 }
155
156 void SpeechInputExtensionNotificationUI::ShowNotificationBalloon(
157 const Extension* extension) {
158 string16 title = l10n_util::GetStringUTF16(
159 IDS_SPEECH_INPUT_TRAY_BALLOON_TITLE);
160 string16 message = l10n_util::GetStringFUTF16(
161 IDS_SPEECH_INPUT_TRAY_BALLOON_BODY,
162 UTF8ToUTF16(extension->name()),
163 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
164
165 tray_icon_->DisplayBalloon(*g_images.Get().balloon_icon(), title, message);
166 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698