diff options
author | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 13:24:35 +0000 |
---|---|---|
committer | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 13:24:35 +0000 |
commit | e73fd5d32e9206d40c4c9c016834c0ed5f09ecdf (patch) | |
tree | df2f0d93c68ad9e732ce9811a87cff81115bd116 /ui | |
parent | c63925ad27af4a2072c5b08a64b3bbfbc178744a (diff) | |
download | chromium_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.h | 2 | ||||
-rw-r--r-- | ui/views/context_menu_controller.h | 47 | ||||
-rw-r--r-- | ui/views/controls/menu/menu_controller.cc | 2 | ||||
-rw-r--r-- | ui/views/controls/scrollbar/base_scroll_bar.h | 2 | ||||
-rw-r--r-- | ui/views/controls/textfield/native_textfield_views.cc | 2 | ||||
-rw-r--r-- | ui/views/controls/textfield/native_textfield_views.h | 10 | ||||
-rw-r--r-- | ui/views/controls/textfield/native_textfield_win.cc | 2 | ||||
-rw-r--r-- | ui/views/debug_utils.cc | 76 | ||||
-rw-r--r-- | ui/views/debug_utils.h | 25 | ||||
-rw-r--r-- | ui/views/drag_controller.h | 50 | ||||
-rw-r--r-- | ui/views/drag_utils.cc | 101 | ||||
-rw-r--r-- | ui/views/drag_utils.h | 64 | ||||
-rw-r--r-- | ui/views/drag_utils_aura.cc | 26 | ||||
-rw-r--r-- | ui/views/drag_utils_gtk.cc | 46 | ||||
-rw-r--r-- | ui/views/drag_utils_win.cc | 72 | ||||
-rw-r--r-- | ui/views/metrics.cc | 11 | ||||
-rw-r--r-- | ui/views/metrics.h | 28 | ||||
-rw-r--r-- | ui/views/metrics_aura.cc | 41 | ||||
-rw-r--r-- | ui/views/metrics_gtk.cc | 20 | ||||
-rw-r--r-- | ui/views/metrics_win.cc | 22 | ||||
-rw-r--r-- | ui/views/mouse_watcher.cc | 211 | ||||
-rw-r--r-- | ui/views/mouse_watcher.h | 83 |
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_ |