diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-09 07:35:32 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-09 07:35:32 +0000 |
commit | 213dac2f0bff9162502fe325b6ebb85a255efcb2 (patch) | |
tree | 3640cb1f19976e38677b8632537d2d41f8444d0f /chrome/browser/ui/views/status_icons | |
parent | 6de53d401aa8dc6c7e0a9874c71a95ce88ade50d (diff) | |
download | chromium_src-213dac2f0bff9162502fe325b6ebb85a255efcb2.zip chromium_src-213dac2f0bff9162502fe325b6ebb85a255efcb2.tar.gz chromium_src-213dac2f0bff9162502fe325b6ebb85a255efcb2.tar.bz2 |
Move browser/views to browser/ui/views
TBR=brettw
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/4694005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65508 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/views/status_icons')
6 files changed, 343 insertions, 0 deletions
diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.cc b/chrome/browser/ui/views/status_icons/status_icon_win.cc new file mode 100644 index 0000000..5545560 --- /dev/null +++ b/chrome/browser/ui/views/status_icons/status_icon_win.cc @@ -0,0 +1,89 @@ +// 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 "base/sys_string_conversions.h" +#include "gfx/icon_util.h" +#include "gfx/point.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "views/controls/menu/menu_2.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_; +} + +void StatusIconWin::UpdatePlatformContextMenu(menus::MenuModel* menu) { + // If no items are passed, blow away our context menu. + if (!menu) { + context_menu_.reset(); + return; + } + + // Create context menu with the new contents. + context_menu_.reset(new views::Menu2(menu)); +} + +void StatusIconWin::HandleClickEvent(int x, int y, bool left_mouse_click) { + // Pass to the observer if appropriate. + if (left_mouse_click && HasObservers()) { + DispatchClickEvent(); + return; + } + + // Event not sent to the observer, so display the context menu if one exists. + if (context_menu_.get()) { + // Set our window as the foreground window, so the context menu closes when + // we click away from it. + SetForegroundWindow(window_); + context_menu_->RunContextMenuAt(gfx::Point(x, y)); + } +} diff --git a/chrome/browser/ui/views/status_icons/status_icon_win.h b/chrome/browser/ui/views/status_icons/status_icon_win.h new file mode 100644 index 0000000..74c3742 --- /dev/null +++ b/chrome/browser/ui/views/status_icons/status_icon_win.h @@ -0,0 +1,65 @@ +// 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_UI_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_ +#define CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_ +#pragma once + +#include <windows.h> +#include <shellapi.h> + +#include "base/scoped_handle_win.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/status_icons/status_icon.h" + +namespace views { +class Menu2; +} + +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_; } + + // Handles a click event from the user - if |left_button_click| is true and + // there is a registered observer, passes the click event to the observer, + // otherwise displays the context menu if there is one. + void HandleClickEvent(int x, int y, bool left_button_click); + + protected: + // Overridden from StatusIcon. + virtual void UpdatePlatformContextMenu(menus::MenuModel* menu); + + 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_; + + // Context menu associated with this icon (if any). + scoped_ptr<views::Menu2> context_menu_; + + DISALLOW_COPY_AND_ASSIGN(StatusIconWin); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_ICON_WIN_H_ diff --git a/chrome/browser/ui/views/status_icons/status_tray_gtk.cc b/chrome/browser/ui/views/status_icons/status_tray_gtk.cc new file mode 100644 index 0000000..7cd0666 --- /dev/null +++ b/chrome/browser/ui/views/status_icons/status_tray_gtk.cc @@ -0,0 +1,10 @@ +// 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/status_icons/status_tray.h" + +// Status icons are not currently supported on linux/views. +StatusTray* StatusTray::Create() { + return NULL; +} diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.cc b/chrome/browser/ui/views/status_icons/status_tray_win.cc new file mode 100644 index 0000000..29ed025 --- /dev/null +++ b/chrome/browser/ui/views/status_icons/status_tray_win.cc @@ -0,0 +1,81 @@ +// 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) { + switch (message) { + case kStatusIconMessage: + switch (lparam) { + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_CONTEXTMENU: + // Walk our icons, find which one was clicked on, and invoke its + // HandleClickEvent() method. + for (StatusIconList::const_iterator iter = status_icons().begin(); + iter != status_icons().end(); + ++iter) { + StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter); + if (win_icon->icon_id() == wparam) { + POINT p; + GetCursorPos(&p); + win_icon->HandleClickEvent(p.x, p.y, lparam == WM_LBUTTONDOWN); + } + } + return TRUE; + } + break; + } + return ::DefWindowProc(hwnd, message, wparam, lparam); +} + +StatusTrayWin::~StatusTrayWin() { + if (window_) + DestroyWindow(window_); + UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL)); +} + +StatusIcon* StatusTrayWin::CreatePlatformStatusIcon() { + return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage); +} + +StatusTray* StatusTray::Create() { + return new StatusTrayWin(); +} diff --git a/chrome/browser/ui/views/status_icons/status_tray_win.h b/chrome/browser/ui/views/status_icons/status_tray_win.h new file mode 100644 index 0000000..c6d3c52 --- /dev/null +++ b/chrome/browser/ui/views/status_icons/status_tray_win.h @@ -0,0 +1,43 @@ +// 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_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_ +#define CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_ +#pragma once + +#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* CreatePlatformStatusIcon(); + + 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_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_WIN_H_ + diff --git a/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc b/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc new file mode 100644 index 0000000..c824755 --- /dev/null +++ b/chrome/browser/ui/views/status_icons/status_tray_win_unittest.cc @@ -0,0 +1,55 @@ +// 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/menus/simple_menu_model.h" +#include "app/resource_bundle.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.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, CreateIconAndMenu) { + // Create an icon, set the images, tooltip, and context menu, then shut it + // down. + StatusTrayWin tray; + StatusIcon* icon = tray.CreateStatusIcon(); + SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_STATUS_TRAY_ICON); + icon->SetImage(*bitmap); + icon->SetPressedImage(*bitmap); + icon->SetToolTip(ASCIIToUTF16("tool tip")); + menus::SimpleMenuModel* menu = new menus::SimpleMenuModel(NULL); + menu->AddItem(0, L"foo"); + icon->SetContextMenu(menu); +} + +TEST(StatusTrayWinTest, ClickOnIcon) { + // Create an icon, send a fake click event, make sure observer is called. + StatusTrayWin tray; + StatusIconWin* icon = static_cast<StatusIconWin*>(tray.CreateStatusIcon()); + MockStatusIconObserver observer; + icon->AddObserver(&observer); + EXPECT_CALL(observer, OnClicked()); + // Mimic a click. + tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_LBUTTONDOWN); + // Mimic a right-click - observer should not be called. + tray.WndProc(NULL, icon->message_id(), icon->icon_id(), WM_RBUTTONDOWN); + icon->RemoveObserver(&observer); +} |