summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authortfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 13:24:35 +0000
committertfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 13:24:35 +0000
commite73fd5d32e9206d40c4c9c016834c0ed5f09ecdf (patch)
treedf2f0d93c68ad9e732ce9811a87cff81115bd116 /ui
parentc63925ad27af4a2072c5b08a64b3bbfbc178744a (diff)
downloadchromium_src-e73fd5d32e9206d40c4c9c016834c0ed5f09ecdf.zip
chromium_src-e73fd5d32e9206d40c4c9c016834c0ed5f09ecdf.tar.gz
chromium_src-e73fd5d32e9206d40c4c9c016834c0ed5f09ecdf.tar.bz2
views: Move some random files from views/ to ui/views/.
BUG=104039 R=ben@chromium.org Review URL: http://codereview.chromium.org/8735009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112208 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/aura_shell/examples/window_type_launcher.h2
-rw-r--r--ui/views/context_menu_controller.h47
-rw-r--r--ui/views/controls/menu/menu_controller.cc2
-rw-r--r--ui/views/controls/scrollbar/base_scroll_bar.h2
-rw-r--r--ui/views/controls/textfield/native_textfield_views.cc2
-rw-r--r--ui/views/controls/textfield/native_textfield_views.h10
-rw-r--r--ui/views/controls/textfield/native_textfield_win.cc2
-rw-r--r--ui/views/debug_utils.cc76
-rw-r--r--ui/views/debug_utils.h25
-rw-r--r--ui/views/drag_controller.h50
-rw-r--r--ui/views/drag_utils.cc101
-rw-r--r--ui/views/drag_utils.h64
-rw-r--r--ui/views/drag_utils_aura.cc26
-rw-r--r--ui/views/drag_utils_gtk.cc46
-rw-r--r--ui/views/drag_utils_win.cc72
-rw-r--r--ui/views/metrics.cc11
-rw-r--r--ui/views/metrics.h28
-rw-r--r--ui/views/metrics_aura.cc41
-rw-r--r--ui/views/metrics_gtk.cc20
-rw-r--r--ui/views/metrics_win.cc22
-rw-r--r--ui/views/mouse_watcher.cc211
-rw-r--r--ui/views/mouse_watcher.h83
22 files changed, 933 insertions, 10 deletions
diff --git a/ui/aura_shell/examples/window_type_launcher.h b/ui/aura_shell/examples/window_type_launcher.h
index b597a24..8e41587 100644
--- a/ui/aura_shell/examples/window_type_launcher.h
+++ b/ui/aura_shell/examples/window_type_launcher.h
@@ -6,10 +6,10 @@
#define UI_AURA_SHELL_EXAMPLES_WINDOW_TYPE_LAUNCHER_H_
#pragma once
+#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/widget/widget_delegate.h"
-#include "views/context_menu_controller.h"
namespace views {
class MenuRunner;
diff --git a/ui/views/context_menu_controller.h b/ui/views/context_menu_controller.h
new file mode 100644
index 0000000..577ec62
--- /dev/null
+++ b/ui/views/context_menu_controller.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef UI_VIEWS_CONTEXT_MENU_CONTROLLER_H_
+#define UI_VIEWS_CONTEXT_MENU_CONTROLLER_H_
+#pragma once
+
+#include "views/views_export.h"
+
+namespace gfx {
+class Point;
+}
+
+namespace views {
+class View;
+
+// ContextMenuController is responsible for showing the context menu for a
+// View. To use a ContextMenuController invoke set_context_menu_controller on a
+// View. When the appropriate user gesture occurs ShowContextMenu is invoked
+// on the ContextMenuController.
+//
+// Setting a ContextMenuController on a view makes the view process mouse
+// events.
+//
+// It is up to subclasses that do their own mouse processing to invoke
+// the appropriate ContextMenuController method, typically by invoking super's
+// implementation for mouse processing.
+class VIEWS_EXPORT ContextMenuController {
+ public:
+ // Invoked to show the context menu for the source view. If |is_mouse_gesture|
+ // is true, |p| is the location of the mouse. If |is_mouse_gesture| is false,
+ // this method was not invoked by a mouse gesture and |p| is the recommended
+ // location to show the menu at.
+ //
+ // |p| is in screen coordinates.
+ virtual void ShowContextMenuForView(View* source,
+ const gfx::Point& p,
+ bool is_mouse_gesture) = 0;
+
+ protected:
+ virtual ~ContextMenuController() {}
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_CONTEXT_MENU_CONTROLLER_H_
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index 9678a81..bb96e93 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -18,9 +18,9 @@
#include "ui/views/controls/menu/menu_controller_delegate.h"
#include "ui/views/controls/menu/menu_scroll_view_container.h"
#include "ui/views/controls/menu/submenu_view.h"
+#include "ui/views/drag_utils.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
-#include "views/drag_utils.h"
#include "views/view_constants.h"
#include "views/views_delegate.h"
diff --git a/ui/views/controls/scrollbar/base_scroll_bar.h b/ui/views/controls/scrollbar/base_scroll_bar.h
index 8dee9b9..09d581e 100644
--- a/ui/views/controls/scrollbar/base_scroll_bar.h
+++ b/ui/views/controls/scrollbar/base_scroll_bar.h
@@ -6,10 +6,10 @@
#define UI_VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_
#pragma once
+#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/controls/scrollbar/scroll_bar.h"
-#include "views/context_menu_controller.h"
#include "views/repeat_controller.h"
namespace views {
diff --git a/ui/views/controls/textfield/native_textfield_views.cc b/ui/views/controls/textfield/native_textfield_views.cc
index d5d0b56..b324430 100644
--- a/ui/views/controls/textfield/native_textfield_views.cc
+++ b/ui/views/controls/textfield/native_textfield_views.cc
@@ -27,10 +27,10 @@
#include "ui/views/controls/textfield/textfield_views_model.h"
#include "ui/views/events/event.h"
#include "ui/views/ime/input_method.h"
+#include "ui/views/metrics.h"
#include "ui/views/widget/widget.h"
#include "views/background.h"
#include "views/border.h"
-#include "views/metrics.h"
#include "views/views_delegate.h"
#if defined(OS_LINUX)
diff --git a/ui/views/controls/textfield/native_textfield_views.h b/ui/views/controls/textfield/native_textfield_views.h
index 2cae9f4..a9cfbb8 100644
--- a/ui/views/controls/textfield/native_textfield_views.h
+++ b/ui/views/controls/textfield/native_textfield_views.h
@@ -11,12 +11,12 @@
#include "ui/base/ime/text_input_client.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/gfx/font.h"
+#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/textfield/native_textfield_wrapper.h"
#include "ui/views/controls/textfield/textfield_views_model.h"
+#include "ui/views/drag_controller.h"
#include "ui/views/touchui/touch_selection_controller.h"
#include "views/border.h"
-#include "views/context_menu_controller.h"
-#include "views/drag_controller.h"
#include "views/view.h"
namespace base {
@@ -60,8 +60,8 @@ class VIEWS_EXPORT NativeTextfieldViews : public TouchSelectionClientView,
virtual bool OnKeyPressed(const KeyEvent& event) OVERRIDE;
virtual bool GetDropFormats(
int* formats,
- std::set<OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
- virtual bool CanDrop(const OSExchangeData& data) OVERRIDE;
+ std::set<ui::OSExchangeData::CustomFormat>* custom_formats) OVERRIDE;
+ virtual bool CanDrop(const ui::OSExchangeData& data) OVERRIDE;
virtual int OnDragUpdated(const DropTargetEvent& event) OVERRIDE;
virtual int OnPerformDrop(const DropTargetEvent& event) OVERRIDE;
virtual void OnDragDone() OVERRIDE;
@@ -82,7 +82,7 @@ class VIEWS_EXPORT NativeTextfieldViews : public TouchSelectionClientView,
// Overridden from DragController:
virtual void WriteDragDataForView(View* sender,
const gfx::Point& press_pt,
- OSExchangeData* data) OVERRIDE;
+ ui::OSExchangeData* data) OVERRIDE;
virtual int GetDragOperationsForView(View* sender,
const gfx::Point& p) OVERRIDE;
virtual bool CanStartDragForView(View* sender,
diff --git a/ui/views/controls/textfield/native_textfield_win.cc b/ui/views/controls/textfield/native_textfield_win.cc
index 3b598e1..a8164a2 100644
--- a/ui/views/controls/textfield/native_textfield_win.cc
+++ b/ui/views/controls/textfield/native_textfield_win.cc
@@ -31,8 +31,8 @@
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/focus/focus_manager.h"
+#include "ui/views/metrics.h"
#include "ui/views/widget/widget.h"
-#include "views/metrics.h"
#include "views/views_delegate.h"
namespace views {
diff --git a/ui/views/debug_utils.cc b/ui/views/debug_utils.cc
new file mode 100644
index 0000000..23a75d2
--- /dev/null
+++ b/ui/views/debug_utils.cc
@@ -0,0 +1,76 @@
+// 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 "ui/views/debug_utils.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "views/view.h"
+
+#ifndef NDEBUG
+#include <iostream>
+#endif
+
+namespace views {
+
+#ifndef NDEBUG
+
+namespace {
+void PrintViewHierarchyImp(const View* view, int indent) {
+ std::wostringstream buf;
+ int ind = indent;
+ while (ind-- > 0)
+ buf << L' ';
+ buf << UTF8ToWide(view->GetClassName());
+ buf << L' ';
+ buf << view->id();
+ buf << L' ';
+ buf << view->x() << L"," << view->y() << L",";
+ buf << view->bounds().right() << L"," << view->bounds().bottom();
+ buf << L' ';
+ buf << view;
+
+ VLOG(1) << buf.str();
+ std::cout << buf.str() << std::endl;
+
+ for (int i = 0, count = view->child_count(); i < count; ++i)
+ PrintViewHierarchyImp(view->GetChildViewAt(i), indent + 2);
+}
+
+void PrintFocusHierarchyImp(const View* view, int indent) {
+ std::wostringstream buf;
+ int ind = indent;
+ while (ind-- > 0)
+ buf << L' ';
+ buf << UTF8ToWide(view->GetClassName());
+ buf << L' ';
+ buf << view->id();
+ buf << L' ';
+ buf << view->GetClassName().c_str();
+ buf << L' ';
+ buf << view;
+
+ VLOG(1) << buf.str();
+ std::cout << buf.str() << std::endl;
+
+ if (view->child_count() > 0)
+ PrintFocusHierarchyImp(view->GetChildViewAt(0), indent + 2);
+
+ const View* next_focusable = view->GetNextFocusableView();
+ if (next_focusable)
+ PrintFocusHierarchyImp(next_focusable, indent);
+}
+} // namespace
+
+void PrintViewHierarchy(const View* view) {
+ PrintViewHierarchyImp(view, 0);
+}
+
+void PrintFocusHierarchy(const View* view) {
+ PrintFocusHierarchyImp(view, 0);
+}
+
+} // namespace views
+
+#endif // NDEBUG
diff --git a/ui/views/debug_utils.h b/ui/views/debug_utils.h
new file mode 100644
index 0000000..b953c94
--- /dev/null
+++ b/ui/views/debug_utils.h
@@ -0,0 +1,25 @@
+// 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.
+
+#ifndef UI_VIEWS_DEBUG_UTILS_H_
+#define UI_VIEWS_DEBUG_UTILS_H_
+#pragma once
+
+namespace views {
+
+class View;
+
+#ifndef NDEBUG
+
+// Log the view hierarchy.
+void PrintViewHierarchy(const View* view);
+
+// Log the focus traversal hierarchy.
+void PrintFocusHierarchy(const View* view);
+
+#endif // NDEBUG
+
+} // namespace views
+
+#endif // UI_VIEWS_DEBUG_UTILS_H_
diff --git a/ui/views/drag_controller.h b/ui/views/drag_controller.h
new file mode 100644
index 0000000..94946d7
--- /dev/null
+++ b/ui/views/drag_controller.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef UI_VIEWS_DRAG_CONTROLLER_H_
+#define UI_VIEWS_DRAG_CONTROLLER_H_
+#pragma once
+
+#include "views/views_export.h"
+
+namespace gfx {
+class Point;
+}
+
+namespace ui {
+class OSExchangeData;
+}
+
+namespace views {
+class View;
+
+// DragController is responsible for writing drag data for a view, as well as
+// supplying the supported drag operations. Use DragController if you don't
+// want to subclass.
+class VIEWS_EXPORT DragController {
+ public:
+ // Writes the data for the drag.
+ virtual void WriteDragDataForView(View* sender,
+ const gfx::Point& press_pt,
+ ui::OSExchangeData* data) = 0;
+
+ // Returns the supported drag operations (see DragDropTypes for possible
+ // values). A drag is only started if this returns a non-zero value.
+ virtual int GetDragOperationsForView(View* sender,
+ const gfx::Point& p) = 0;
+
+ // Returns true if a drag operation can be started.
+ // |press_pt| represents the coordinates where the mouse was initially
+ // pressed down. |p| is the current mouse coordinates.
+ virtual bool CanStartDragForView(View* sender,
+ const gfx::Point& press_pt,
+ const gfx::Point& p) = 0;
+
+ protected:
+ virtual ~DragController() {}
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_DRAG_CONTROLLER_H_
diff --git a/ui/views/drag_utils.cc b/ui/views/drag_utils.cc
new file mode 100644
index 0000000..181a599
--- /dev/null
+++ b/ui/views/drag_utils.cc
@@ -0,0 +1,101 @@
+// 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 "ui/views/drag_utils.h"
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "googleurl/src/gurl.h"
+#include "grit/ui_resources.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/font.h"
+#include "ui/views/controls/button/text_button.h"
+
+namespace drag_utils {
+
+// Maximum width of the link drag image in pixels.
+static const int kLinkDragImageMaxWidth = 200;
+static const int kLinkDragImageVPadding = 3;
+
+// File dragging pixel measurements
+static const int kFileDragImageMaxWidth = 200;
+static const SkColor kFileDragImageTextColor = SK_ColorBLACK;
+
+void SetURLAndDragImage(const GURL& url,
+ const string16& title,
+ const SkBitmap& icon,
+ ui::OSExchangeData* data) {
+ DCHECK(url.is_valid() && data);
+
+ data->SetURL(url, title);
+
+ // Create a button to render the drag image for us.
+ views::TextButton button(NULL,
+ title.empty() ? UTF8ToUTF16(url.spec()) : title);
+ button.set_max_width(kLinkDragImageMaxWidth);
+ if (icon.isNull()) {
+ button.SetIcon(*ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_DEFAULT_FAVICON));
+ } else {
+ button.SetIcon(icon);
+ }
+ gfx::Size prefsize = button.GetPreferredSize();
+ button.SetBounds(0, 0, prefsize.width(), prefsize.height());
+
+ // Render the image.
+ gfx::CanvasSkia canvas(prefsize.width(), prefsize.height(), false);
+ button.PaintButton(&canvas, views::TextButton::PB_FOR_DRAG);
+ SetDragImageOnDataObject(canvas, prefsize,
+ gfx::Point(prefsize.width() / 2, prefsize.height() / 2), data);
+}
+
+void CreateDragImageForFile(const FilePath& file_name,
+ const SkBitmap* icon,
+ ui::OSExchangeData* data_object) {
+ DCHECK(icon);
+ DCHECK(data_object);
+
+ // Set up our text portion
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ gfx::Font font = rb.GetFont(ResourceBundle::BaseFont);
+
+ const int width = kFileDragImageMaxWidth;
+ // Add +2 here to allow room for the halo.
+ const int height = font.GetHeight() + icon->height() +
+ kLinkDragImageVPadding + 2;
+ gfx::CanvasSkia canvas(width, height, false /* translucent */);
+
+ // Paint the icon.
+ canvas.DrawBitmapInt(*icon, (width - icon->width()) / 2, 0);
+
+ string16 name = file_name.BaseName().LossyDisplayName();
+#if defined(OS_WIN)
+ // Paint the file name. We inset it one pixel to allow room for the halo.
+ canvas.DrawStringWithHalo(name, font, kFileDragImageTextColor, SK_ColorWHITE,
+ 1, icon->height() + kLinkDragImageVPadding + 1,
+ width - 2, font.GetHeight(),
+ gfx::Canvas::TEXT_ALIGN_CENTER);
+#else
+ canvas.DrawStringInt(name, font, kFileDragImageTextColor,
+ 0, icon->height() + kLinkDragImageVPadding,
+ width, font.GetHeight(), gfx::Canvas::TEXT_ALIGN_CENTER);
+#endif
+
+ SetDragImageOnDataObject(canvas, gfx::Size(width, height),
+ gfx::Point(width / 2, kLinkDragImageVPadding),
+ data_object);
+}
+
+void SetDragImageOnDataObject(const gfx::Canvas& canvas,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ SetDragImageOnDataObject(
+ canvas.AsCanvasSkia()->ExtractBitmap(), size, cursor_offset, data_object);
+}
+
+} // namespace drag_utils
diff --git a/ui/views/drag_utils.h b/ui/views/drag_utils.h
new file mode 100644
index 0000000..18098c6
--- /dev/null
+++ b/ui/views/drag_utils.h
@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef UI_VIEWS_DRAG_UTILS_H_
+#define UI_VIEWS_DRAG_UTILS_H_
+#pragma once
+
+#include <string>
+
+#include "base/file_path.h"
+#include "base/string16.h"
+#include "views/views_export.h"
+
+class GURL;
+class SkBitmap;
+
+namespace gfx {
+class Canvas;
+class Point;
+class Size;
+}
+
+namespace ui {
+class OSExchangeData;
+}
+using ui::OSExchangeData;
+
+namespace drag_utils {
+
+// Sets url and title on data as well as setting a suitable image for dragging.
+// The image looks like that of the bookmark buttons.
+VIEWS_EXPORT void SetURLAndDragImage(const GURL& url,
+ const string16& title,
+ const SkBitmap& icon,
+ ui::OSExchangeData* data);
+
+// Creates a dragging image to be displayed when the user drags a file from
+// Chrome (via the download manager, for example). The drag image is set into
+// the supplied data_object. 'file_name' can be a full path, but the directory
+// portion will be truncated in the drag image.
+VIEWS_EXPORT void CreateDragImageForFile(const FilePath& file_name,
+ const SkBitmap* icon,
+ ui::OSExchangeData* data_object);
+
+// Sets the drag image on data_object from the supplied canvas. width/height
+// are the size of the image to use, and the offsets give the location of
+// the hotspot for the drag image.
+VIEWS_EXPORT void SetDragImageOnDataObject(const gfx::Canvas& canvas,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object);
+
+// Sets the drag image on data_object from the supplied bitmap. width/height
+// are the size of the image to use, and the offsets give the location of
+// the hotspot for the drag image.
+VIEWS_EXPORT void SetDragImageOnDataObject(const SkBitmap& bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object);
+
+} // namespace drag_utils
+
+#endif // UI_VIEWS_DRAG_UTILS_H_
diff --git a/ui/views/drag_utils_aura.cc b/ui/views/drag_utils_aura.cc
new file mode 100644
index 0000000..f5665fb
--- /dev/null
+++ b/ui/views/drag_utils_aura.cc
@@ -0,0 +1,26 @@
+// 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 "ui/views/drag_utils.h"
+
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/size.h"
+
+namespace drag_utils {
+
+void SetDragImageOnDataObject(const SkBitmap& bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ ui::OSExchangeDataProviderAura& provider(
+ static_cast<ui::OSExchangeDataProviderAura&>(data_object->provider()));
+ provider.set_drag_image(bitmap);
+}
+
+} // namespace drag_utils
diff --git a/ui/views/drag_utils_gtk.cc b/ui/views/drag_utils_gtk.cc
new file mode 100644
index 0000000..45996e7
--- /dev/null
+++ b/ui/views/drag_utils_gtk.cc
@@ -0,0 +1,46 @@
+// 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 "ui/views/drag_utils.h"
+
+#include <gtk/gtk.h>
+
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_gtk.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/gtk_util.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/size.h"
+
+namespace drag_utils {
+
+void SetDragImageOnDataObject(const SkBitmap& bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ ui::OSExchangeDataProviderGtk& provider(
+ static_cast<ui::OSExchangeDataProviderGtk&>(data_object->provider()));
+
+ // Convert the bitmap into a GdkPixbuf.
+ GdkPixbuf* canvas_pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap);
+
+ // Make a new pixbuf of the requested size and copy it over.
+ GdkPixbuf* pixbuf = gdk_pixbuf_new(
+ gdk_pixbuf_get_colorspace(canvas_pixbuf),
+ gdk_pixbuf_get_has_alpha(canvas_pixbuf),
+ gdk_pixbuf_get_bits_per_sample(canvas_pixbuf),
+ size.width(),
+ size.height());
+ gdk_pixbuf_copy_area(canvas_pixbuf, 0, 0, size.width(), size.height(), pixbuf,
+ 0, 0);
+ g_object_unref(canvas_pixbuf);
+
+ // Set the drag data on to the provider.
+ provider.SetDragImage(pixbuf, cursor_offset);
+ g_object_unref(pixbuf);
+}
+
+} // namespace drag_utils
diff --git a/ui/views/drag_utils_win.cc b/ui/views/drag_utils_win.cc
new file mode 100644
index 0000000..3295f8f
--- /dev/null
+++ b/ui/views/drag_utils_win.cc
@@ -0,0 +1,72 @@
+// 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 "ui/views/drag_utils.h"
+
+#include <objidl.h>
+#include <shlobj.h>
+#include <shobjidl.h>
+
+#include "base/win/scoped_comptr.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/dragdrop/os_exchange_data_provider_win.h"
+#include "ui/gfx/canvas_skia.h"
+#include "ui/gfx/gdi_util.h"
+#include "ui/gfx/skbitmap_operations.h"
+
+namespace drag_utils {
+
+static void SetDragImageOnDataObject(HBITMAP hbitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ IDataObject* data_object) {
+ base::win::ScopedComPtr<IDragSourceHelper> helper;
+ HRESULT rv = CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
+ IID_IDragSourceHelper, helper.ReceiveVoid());
+ if (SUCCEEDED(rv)) {
+ SHDRAGIMAGE sdi;
+ sdi.sizeDragImage = size.ToSIZE();
+ sdi.crColorKey = 0xFFFFFFFF;
+ sdi.hbmpDragImage = hbitmap;
+ sdi.ptOffset = cursor_offset.ToPOINT();
+ helper->InitializeFromBitmap(&sdi, data_object);
+ }
+}
+
+// Blit the contents of the canvas to a new HBITMAP. It is the caller's
+// responsibility to release the |bits| buffer.
+static HBITMAP CreateHBITMAPFromSkBitmap(const SkBitmap& sk_bitmap) {
+ HDC screen_dc = GetDC(NULL);
+ BITMAPINFOHEADER header;
+ gfx::CreateBitmapHeader(sk_bitmap.width(), sk_bitmap.height(), &header);
+ void* bits;
+ HBITMAP bitmap =
+ CreateDIBSection(screen_dc, reinterpret_cast<BITMAPINFO*>(&header),
+ DIB_RGB_COLORS, &bits, NULL, 0);
+ DCHECK(sk_bitmap.rowBytes() == sk_bitmap.width() * 4);
+ SkAutoLockPixels lock(sk_bitmap);
+ memcpy(
+ bits, sk_bitmap.getPixels(), sk_bitmap.height() * sk_bitmap.rowBytes());
+ ReleaseDC(NULL, screen_dc);
+ return bitmap;
+}
+
+void SetDragImageOnDataObject(const SkBitmap& sk_bitmap,
+ const gfx::Size& size,
+ const gfx::Point& cursor_offset,
+ ui::OSExchangeData* data_object) {
+ DCHECK(data_object && !size.IsEmpty());
+ // InitializeFromBitmap() doesn't expect an alpha channel and is confused
+ // by premultiplied colors, so unpremultiply the bitmap.
+ // SetDragImageOnDataObject(HBITMAP) takes ownership of the bitmap.
+ HBITMAP bitmap = CreateHBITMAPFromSkBitmap(
+ SkBitmapOperations::UnPreMultiply(sk_bitmap));
+
+ // Attach 'bitmap' to the data_object.
+ SetDragImageOnDataObject(bitmap, size, cursor_offset,
+ ui::OSExchangeDataProviderWin::GetIDataObject(*data_object));
+}
+
+} // namespace drag_utils
diff --git a/ui/views/metrics.cc b/ui/views/metrics.cc
new file mode 100644
index 0000000..842ae66
--- /dev/null
+++ b/ui/views/metrics.cc
@@ -0,0 +1,11 @@
+// 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 "ui/views/metrics.h"
+
+namespace views {
+
+const int kDefaultMenuShowDelay = 400;
+
+} // namespace views
diff --git a/ui/views/metrics.h b/ui/views/metrics.h
new file mode 100644
index 0000000..1718ca7
--- /dev/null
+++ b/ui/views/metrics.h
@@ -0,0 +1,28 @@
+// 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.
+
+#ifndef UI_VIEWS_METRICS_H_
+#define UI_VIEWS_METRICS_H_
+#pragma once
+
+#include "views/views_export.h"
+
+namespace views {
+
+// NOTE: All times in this file are/should be expressed in milliseconds.
+
+// The default value for how long to wait before showing a menu button on hover.
+// This value is used if the OS doesn't supply one.
+extern const int kDefaultMenuShowDelay;
+
+// Returns the amount of time between double clicks.
+VIEWS_EXPORT int GetDoubleClickInterval();
+
+// Returns the amount of time to wait from hovering over a menu button until
+// showing the menu.
+VIEWS_EXPORT int GetMenuShowDelay();
+
+} // namespace views
+
+#endif // UI_VIEWS_METRICS_H_
diff --git a/ui/views/metrics_aura.cc b/ui/views/metrics_aura.cc
new file mode 100644
index 0000000..03aa832
--- /dev/null
+++ b/ui/views/metrics_aura.cc
@@ -0,0 +1,41 @@
+// 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 "ui/views/metrics.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+namespace {
+
+// Default double click interval in milliseconds.
+// Same as what gtk uses.
+const int kDefaultDoubleClickInterval = 500;
+
+} // namespace
+
+namespace views {
+
+int GetDoubleClickInterval() {
+#if defined(OS_WIN)
+ return ::GetDoubleClickTime();
+#else
+ // TODO(jennyz): This value may need to be adjusted on different platforms.
+ return kDefaultDoubleClickInterval;
+#endif
+}
+
+int GetMenuShowDelay() {
+#if defined(OS_WIN)
+ static DWORD delay = 0;
+ if (!delay && !SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0))
+ delay = kDefaultMenuShowDelay;
+ return delay;
+#else
+ return 0;
+#endif
+}
+
+} // namespace views
diff --git a/ui/views/metrics_gtk.cc b/ui/views/metrics_gtk.cc
new file mode 100644
index 0000000..b874bae
--- /dev/null
+++ b/ui/views/metrics_gtk.cc
@@ -0,0 +1,20 @@
+// 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 "ui/views/metrics.h"
+
+#include <gtk/gtk.h>
+
+namespace views {
+
+int GetDoubleClickInterval() {
+ GdkDisplay* display = gdk_display_get_default();
+ return display ? display->double_click_time : 500;
+}
+
+int GetMenuShowDelay() {
+ return kDefaultMenuShowDelay;
+}
+
+} // namespace views
diff --git a/ui/views/metrics_win.cc b/ui/views/metrics_win.cc
new file mode 100644
index 0000000..3e04446
--- /dev/null
+++ b/ui/views/metrics_win.cc
@@ -0,0 +1,22 @@
+// 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 "ui/views/metrics.h"
+
+#include <windows.h>
+
+namespace views {
+
+int GetDoubleClickInterval() {
+ return ::GetDoubleClickTime();
+}
+
+int GetMenuShowDelay() {
+ static DWORD delay = 0;
+ if (!delay && !SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &delay, 0))
+ delay = kDefaultMenuShowDelay;
+ return delay;
+}
+
+} // namespace views
diff --git a/ui/views/mouse_watcher.cc b/ui/views/mouse_watcher.cc
new file mode 100644
index 0000000..555af23
--- /dev/null
+++ b/ui/views/mouse_watcher.cc
@@ -0,0 +1,211 @@
+// 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 "ui/views/mouse_watcher.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/event_types.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "ui/base/events.h"
+#include "ui/gfx/screen.h"
+#include "ui/views/widget/widget.h"
+#include "views/view.h"
+
+namespace views {
+
+// Amount of time between when the mouse moves outside the view's zone and when
+// the listener is notified.
+const int kNotifyListenerTimeMs = 300;
+
+class MouseWatcher::Observer : public MessageLoopForUI::Observer {
+ public:
+ explicit Observer(MouseWatcher* mouse_watcher)
+ : mouse_watcher_(mouse_watcher),
+ ALLOW_THIS_IN_INITIALIZER_LIST(notify_listener_factory_(this)) {
+ MessageLoopForUI::current()->AddObserver(this);
+ }
+
+ ~Observer() {
+ MessageLoopForUI::current()->RemoveObserver(this);
+ }
+
+ // MessageLoop::Observer implementation:
+#if defined(OS_WIN)
+ virtual base::EventStatus WillProcessEvent(
+ const base::NativeEvent& event) OVERRIDE {
+ return base::EVENT_CONTINUE;
+ }
+
+ virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
+ // We spy on three different Windows messages here to see if the mouse has
+ // moved out of the bounds of the view. The messages are:
+ //
+ // WM_MOUSEMOVE:
+ // For when the mouse moves from the view into the rest of the browser UI,
+ // i.e. within the bounds of the same windows HWND.
+ // WM_MOUSELEAVE:
+ // For when the mouse moves out of the bounds of the view's HWND.
+ // WM_NCMOUSELEAVE:
+ // For notification when the mouse leaves the _non-client_ area.
+ //
+ switch (event.message) {
+ case WM_MOUSEMOVE:
+ HandleGlobalMouseMoveEvent(false);
+ break;
+ case WM_MOUSELEAVE:
+ case WM_NCMOUSELEAVE:
+ HandleGlobalMouseMoveEvent(true);
+ break;
+ }
+ }
+#elif defined(USE_WAYLAND)
+ virtual MessageLoopForUI::Observer::EventStatus WillProcessEvent(
+ base::wayland::WaylandEvent* event) OVERRIDE {
+ switch (event->type) {
+ case base::wayland::WAYLAND_MOTION:
+ HandleGlobalMouseMoveEvent(false);
+ break;
+ case base::wayland::WAYLAND_POINTER_FOCUS:
+ if (!event->pointer_focus.state)
+ HandleGlobalMouseMoveEvent(true);
+ break;
+ default:
+ break;
+ }
+ return EVENT_CONTINUE;
+ }
+#elif defined(USE_AURA)
+ virtual base::EventStatus WillProcessEvent(
+ const base::NativeEvent& event) OVERRIDE {
+ return base::EVENT_CONTINUE;
+ }
+ virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
+ switch (ui::EventTypeFromNative(event)) {
+ case ui::ET_MOUSE_MOVED:
+ case ui::ET_MOUSE_DRAGGED:
+ // DRAGGED is a special case of MOVED. See events_win.cc/events_x.cc.
+ HandleGlobalMouseMoveEvent(false);
+ break;
+ case ui::ET_MOUSE_EXITED:
+ HandleGlobalMouseMoveEvent(true);
+ break;
+ default:
+ break;
+ }
+ }
+#elif defined(TOOLKIT_USES_GTK)
+ virtual void WillProcessEvent(GdkEvent* event) OVERRIDE {
+ }
+
+ virtual void DidProcessEvent(GdkEvent* event) OVERRIDE {
+ switch (event->type) {
+ case GDK_MOTION_NOTIFY:
+ HandleGlobalMouseMoveEvent(false);
+ break;
+ case GDK_LEAVE_NOTIFY:
+ HandleGlobalMouseMoveEvent(true);
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+ private:
+ View* view() const { return mouse_watcher_->host_; }
+
+ // Returns whether or not the cursor is currently in the view's "zone" which
+ // is defined as a slightly larger region than the view.
+ bool IsCursorInViewZone() {
+ gfx::Rect bounds = view()->GetLocalBounds();
+ gfx::Point view_topleft(bounds.origin());
+ View::ConvertPointToScreen(view(), &view_topleft);
+ bounds.set_origin(view_topleft);
+ bounds.SetRect(view_topleft.x() - mouse_watcher_->hot_zone_insets_.left(),
+ view_topleft.y() - mouse_watcher_->hot_zone_insets_.top(),
+ bounds.width() + mouse_watcher_->hot_zone_insets_.width(),
+ bounds.height() + mouse_watcher_->hot_zone_insets_.height());
+
+ gfx::Point cursor_point = gfx::Screen::GetCursorScreenPoint();
+
+ return bounds.Contains(cursor_point.x(), cursor_point.y());
+ }
+
+ // Returns true if the mouse is over the view's window.
+ bool IsMouseOverWindow() {
+ Widget* widget = view()->GetWidget();
+ if (!widget)
+ return false;
+
+ return gfx::Screen::GetWindowAtCursorScreenPoint() ==
+ widget->GetNativeWindow();
+ }
+
+ // Called from the message loop observer when a mouse movement has occurred.
+ void HandleGlobalMouseMoveEvent(bool check_window) {
+ bool in_view = IsCursorInViewZone();
+ if (!in_view || (check_window && !IsMouseOverWindow())) {
+ // Mouse moved outside the view's zone, start a timer to notify the
+ // listener.
+ if (!notify_listener_factory_.HasWeakPtrs()) {
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&Observer::NotifyListener,
+ notify_listener_factory_.GetWeakPtr()),
+ !in_view ? kNotifyListenerTimeMs :
+ mouse_watcher_->notify_on_exit_time_ms_);
+ }
+ } else {
+ // Mouse moved quickly out of the view and then into it again, so cancel
+ // the timer.
+ notify_listener_factory_.InvalidateWeakPtrs();
+ }
+ }
+
+ void NotifyListener() {
+ mouse_watcher_->NotifyListener();
+ // WARNING: we've been deleted.
+ }
+
+ private:
+ MouseWatcher* mouse_watcher_;
+
+ // A factory that is used to construct a delayed callback to the listener.
+ base::WeakPtrFactory<Observer> notify_listener_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(Observer);
+};
+
+MouseWatcherListener::~MouseWatcherListener() {
+}
+
+MouseWatcher::MouseWatcher(View* host,
+ MouseWatcherListener* listener,
+ const gfx::Insets& hot_zone_insets)
+ : host_(host),
+ listener_(listener),
+ hot_zone_insets_(hot_zone_insets),
+ notify_on_exit_time_ms_(kNotifyListenerTimeMs) {
+}
+
+MouseWatcher::~MouseWatcher() {
+}
+
+void MouseWatcher::Start() {
+ if (!is_observing())
+ observer_.reset(new Observer(this));
+}
+
+void MouseWatcher::Stop() {
+ observer_.reset(NULL);
+}
+
+void MouseWatcher::NotifyListener() {
+ observer_.reset(NULL);
+ listener_->MouseMovedOutOfView();
+}
+
+} // namespace views
diff --git a/ui/views/mouse_watcher.h b/ui/views/mouse_watcher.h
new file mode 100644
index 0000000..cd739d2
--- /dev/null
+++ b/ui/views/mouse_watcher.h
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef UI_VIEWS_MOUSE_WATCHER_H_
+#define UI_VIEWS_MOUSE_WATCHER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/insets.h"
+#include "views/views_export.h"
+
+namespace views {
+
+class View;
+
+// MouseWatcherListener is notified when the mouse moves outside the view.
+class VIEWS_EXPORT MouseWatcherListener {
+ public:
+ virtual void MouseMovedOutOfView() = 0;
+
+ protected:
+ virtual ~MouseWatcherListener();
+};
+
+// MouseWatcher is used to watch mouse movement and notify its listener when the
+// mouse moves outside the bounds of a view.
+class VIEWS_EXPORT MouseWatcher {
+ public:
+ // Creates a new MouseWatcher. |hot_zone_insets| is added to the bounds of
+ // the view to determine the active zone. For example, if
+ // |hot_zone_insets.bottom()| is 10, then the listener is not notified if
+ // the y coordinate is between the origin of the view and height of the view
+ // plus 10.
+ MouseWatcher(views::View* host,
+ MouseWatcherListener* listener,
+ const gfx::Insets& hot_zone_insets);
+ ~MouseWatcher();
+
+ // Sets the amount to delay before notifying the listener when the mouse exits
+ // the view by way of going to another window.
+ void set_notify_on_exit_time_ms(int time) { notify_on_exit_time_ms_ = time; }
+
+ // Starts watching mouse movements. When the mouse moves outside the bounds of
+ // the view the listener is notified. |Start| may be invoked any number of
+ // times. If the mouse moves outside the bounds of the view the listener is
+ // notified and watcher stops watching events.
+ void Start();
+
+ // Stops watching mouse events.
+ void Stop();
+
+ private:
+ class Observer;
+
+ // Are we currently observing events?
+ bool is_observing() const { return observer_.get() != NULL; }
+
+ // Notifies the listener and stops watching events.
+ void NotifyListener();
+
+ // View we're listening for events over.
+ View* host_;
+
+ // Our listener.
+ MouseWatcherListener* listener_;
+
+ // Insets added to the bounds of the view.
+ const gfx::Insets hot_zone_insets_;
+
+ // Does the actual work of listening for mouse events.
+ scoped_ptr<Observer> observer_;
+
+ // See description above setter.
+ int notify_on_exit_time_ms_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseWatcher);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_MOUSE_WATCHER_H_