diff options
author | Ben Murdoch <benm@google.com> | 2010-07-29 17:14:53 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-08-04 14:29:45 +0100 |
commit | c407dc5cd9bdc5668497f21b26b09d988ab439de (patch) | |
tree | 7eaf8707c0309516bdb042ad976feedaf72b0bb1 /chrome/browser/views/status_icons | |
parent | 0998b1cdac5733f299c12d88bc31ef9c8035b8fa (diff) | |
download | external_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')
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); +} |