summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/status_icons
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-07-29 17:14:53 +0100
committerBen Murdoch <benm@google.com>2010-08-04 14:29:45 +0100
commitc407dc5cd9bdc5668497f21b26b09d988ab439de (patch)
tree7eaf8707c0309516bdb042ad976feedaf72b0bb1 /chrome/browser/views/status_icons
parent0998b1cdac5733f299c12d88bc31ef9c8035b8fa (diff)
downloadexternal_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.zip
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.gz
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.bz2
Merge Chromium src@r53293
Change-Id: Ia79acf8670f385cee48c45b0a75371d8e950af34
Diffstat (limited to 'chrome/browser/views/status_icons')
-rw-r--r--chrome/browser/views/status_icons/status_icon_win.cc60
-rw-r--r--chrome/browser/views/status_icons/status_icon_win.h47
-rw-r--r--chrome/browser/views/status_icons/status_tray_win.cc79
-rw-r--r--chrome/browser/views/status_icons/status_tray_win.h42
-rw-r--r--chrome/browser/views/status_icons/status_tray_win_unittest.cc48
5 files changed, 276 insertions, 0 deletions
diff --git a/chrome/browser/views/status_icons/status_icon_win.cc b/chrome/browser/views/status_icons/status_icon_win.cc
new file mode 100644
index 0000000..53cfcad
--- /dev/null
+++ b/chrome/browser/views/status_icons/status_icon_win.cc
@@ -0,0 +1,60 @@
+// Copyright (c) 2010 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/views/status_icons/status_icon_win.h"
+
+#include "gfx/icon_util.h"
+#include "base/sys_string_conversions.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+StatusIconWin::StatusIconWin(UINT id, HWND window, UINT message)
+ : icon_id_(id),
+ window_(window),
+ message_id_(message) {
+ NOTIFYICONDATA icon_data;
+ InitIconData(&icon_data);
+ icon_data.uFlags = NIF_MESSAGE;
+ icon_data.uCallbackMessage = message_id_;
+ BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
+ DCHECK(result);
+}
+
+StatusIconWin::~StatusIconWin() {
+ // Remove our icon.
+ NOTIFYICONDATA icon_data;
+ InitIconData(&icon_data);
+ Shell_NotifyIcon(NIM_DELETE, &icon_data);
+}
+
+void StatusIconWin::SetImage(const SkBitmap& image) {
+ // Create the icon.
+ NOTIFYICONDATA icon_data;
+ InitIconData(&icon_data);
+ icon_data.uFlags = NIF_ICON;
+ icon_.Set(IconUtil::CreateHICONFromSkBitmap(image));
+ icon_data.hIcon = icon_.Get();
+ BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
+ DCHECK(result);
+}
+
+void StatusIconWin::SetPressedImage(const SkBitmap& image) {
+ // Ignore pressed images, since the standard on Windows is to not highlight
+ // pressed status icons.
+}
+
+void StatusIconWin::SetToolTip(const string16& tool_tip) {
+ // Create the icon.
+ NOTIFYICONDATA icon_data;
+ InitIconData(&icon_data);
+ icon_data.uFlags = NIF_TIP;
+ wcscpy_s(icon_data.szTip, tool_tip.c_str());
+ BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
+ DCHECK(result);
+}
+
+void StatusIconWin::InitIconData(NOTIFYICONDATA* icon_data) {
+ icon_data->cbSize = sizeof(icon_data);
+ icon_data->hWnd = window_;
+ icon_data->uID = icon_id_;
+}
diff --git a/chrome/browser/views/status_icons/status_icon_win.h b/chrome/browser/views/status_icons/status_icon_win.h
new file mode 100644
index 0000000..46be5ae
--- /dev/null
+++ b/chrome/browser/views/status_icons/status_icon_win.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_
+#define CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_
+
+#include <windows.h>
+#include <shellapi.h>
+
+#include "base/scoped_handle_win.h"
+#include "chrome/browser/status_icons/status_icon.h"
+
+class StatusIconWin : public StatusIcon {
+ public:
+ // Constructor which provides this icon's unique ID and messaging window.
+ StatusIconWin(UINT id, HWND window, UINT message);
+ virtual ~StatusIconWin();
+
+ // Overridden from StatusIcon:
+ virtual void SetImage(const SkBitmap& image);
+ virtual void SetPressedImage(const SkBitmap& image);
+ virtual void SetToolTip(const string16& tool_tip);
+
+ UINT icon_id() const { return icon_id_; }
+
+ UINT message_id() const { return message_id_; }
+
+ private:
+ void InitIconData(NOTIFYICONDATA* icon_data);
+
+ // The unique ID corresponding to this icon.
+ UINT icon_id_;
+
+ // Window used for processing messages from this icon.
+ HWND window_;
+
+ // The message identifier used for status icon messages.
+ UINT message_id_;
+
+ // The currently-displayed icon for the window.
+ ScopedHICON icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(StatusIconWin);
+};
+
+#endif // CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_
diff --git a/chrome/browser/views/status_icons/status_tray_win.cc b/chrome/browser/views/status_icons/status_tray_win.cc
new file mode 100644
index 0000000..8c1a998
--- /dev/null
+++ b/chrome/browser/views/status_icons/status_tray_win.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2010 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/views/status_icons/status_tray_win.h"
+
+#include "base/win_util.h"
+#include "chrome/browser/views/status_icons/status_icon_win.h"
+#include "chrome/common/chrome_constants.h"
+
+static const UINT kStatusIconMessage = WM_APP + 1;
+
+StatusTrayWin::StatusTrayWin()
+ : next_icon_id_(1) {
+ // Register our window class
+ HINSTANCE hinst = GetModuleHandle(NULL);
+ WNDCLASSEX wc = {0};
+ wc.cbSize = sizeof(wc);
+ wc.lpfnWndProc = StatusTrayWin::WndProcStatic;
+ wc.hInstance = hinst;
+ wc.lpszClassName = chrome::kStatusTrayWindowClass;
+ ATOM clazz = RegisterClassEx(&wc);
+ DCHECK(clazz);
+
+ // Create an offscreen window for handling messages for the status icons.
+ window_ = CreateWindow(chrome::kStatusTrayWindowClass,
+ 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0);
+ win_util::SetWindowUserData(window_, this);
+}
+
+LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam) {
+ StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>(
+ GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ return msg_wnd->WndProc(hwnd, message, wparam, lparam);
+}
+
+LRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam) {
+ // TODO(atwilson): Add support for right clicks and context menu messages
+ // (tracked in http://crbug.com/37375).
+ switch (message) {
+ case kStatusIconMessage:
+ switch (lparam) {
+ case WM_LBUTTONDOWN:
+ // Walk our icons, find which one was clicked on, and invoke its
+ // DispatchClickEvent() method.
+ for (StatusIconMap::const_iterator iter = status_icons().begin();
+ iter != status_icons().end();
+ ++iter) {
+ StatusIconWin* win_icon =
+ static_cast<StatusIconWin*>(iter->second);
+ if (win_icon->icon_id() == wparam)
+ win_icon->DispatchClickEvent();
+ }
+ return TRUE;
+ }
+ break;
+ }
+ return ::DefWindowProc(hwnd, message, wparam, lparam);
+}
+
+StatusTrayWin::~StatusTrayWin() {
+ if (window_)
+ DestroyWindow(window_);
+ UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL));
+}
+
+StatusIcon* StatusTrayWin::CreateStatusIcon() {
+ return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage);
+}
+
+StatusTray* StatusTray::Create() {
+ return new StatusTrayWin();
+}
diff --git a/chrome/browser/views/status_icons/status_tray_win.h b/chrome/browser/views/status_icons/status_tray_win.h
new file mode 100644
index 0000000..f3aa9d1
--- /dev/null
+++ b/chrome/browser/views/status_icons/status_tray_win.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_
+#define CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_
+
+#include <windows.h>
+
+#include "chrome/browser/status_icons/status_tray.h"
+
+class StatusTrayWin : public StatusTray {
+ public:
+ StatusTrayWin();
+ ~StatusTrayWin();
+
+ // Exposed for testing.
+ LRESULT CALLBACK WndProc(HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam);
+ protected:
+ // Overriden from StatusTray:
+ virtual StatusIcon* CreateStatusIcon();
+
+ private:
+ // Static callback invoked when a message comes in to our messaging window.
+ static LRESULT CALLBACK WndProcStatic(HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam);
+
+ // The unique icon ID we will assign to the next icon.
+ UINT next_icon_id_;
+ // The window used for processing events.
+ HWND window_;
+
+ DISALLOW_COPY_AND_ASSIGN(StatusTrayWin);
+};
+
+#endif // CHROME_BROWSER_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_
+
diff --git a/chrome/browser/views/status_icons/status_tray_win_unittest.cc b/chrome/browser/views/status_icons/status_tray_win_unittest.cc
new file mode 100644
index 0000000..073e50b
--- /dev/null
+++ b/chrome/browser/views/status_icons/status_tray_win_unittest.cc
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 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 "app/resource_bundle.h"
+#include "base/string_util.h"
+#include "chrome/browser/views/status_icons/status_icon_win.h"
+#include "chrome/browser/views/status_icons/status_tray_win.h"
+#include "grit/browser_resources.h"
+#include "grit/theme_resources.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class SkBitmap;
+
+class MockStatusIconObserver : public StatusIcon::Observer {
+ public:
+ MOCK_METHOD0(OnClicked, void());
+};
+
+TEST(StatusTrayWinTest, CreateTray) {
+ // Just tests creation/destruction.
+ StatusTrayWin tray;
+}
+
+TEST(StatusTrayWinTest, CreateIcon) {
+ // Create an icon, set the images and tooltip, then shut it down.
+ StatusTrayWin tray;
+ StatusIcon* icon = tray.GetStatusIcon(ASCIIToUTF16("test"));
+ SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_STATUS_TRAY_ICON);
+ icon->SetImage(*bitmap);
+ icon->SetPressedImage(*bitmap);
+ icon->SetToolTip(ASCIIToUTF16("tool tip"));
+}
+
+TEST(StatusTrayWinTest, ClickOnIcon) {
+ // Create an icon, send a fake click event, make sure observer is called.
+ StatusTrayWin tray;
+ StatusIconWin* icon = static_cast<StatusIconWin*>(
+ tray.GetStatusIcon(ASCIIToUTF16("test")));
+ MockStatusIconObserver observer;
+ icon->AddObserver(&observer);
+ EXPECT_CALL(observer, OnClicked());
+ // Mimic a click.
+ tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_LBUTTONDOWN);
+ icon->RemoveObserver(&observer);
+}