diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-04 05:42:11 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-04 05:42:11 +0000 |
commit | 0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252 (patch) | |
tree | a023736d890db05978a3403d4b010c2e948a72c3 | |
parent | 08df0f2fc34a4abc51e7d5f5f37bcdaaef82cab6 (diff) | |
download | chromium_src-0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252.zip chromium_src-0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252.tar.gz chromium_src-0e7992cbfcf2922eb42cc85a4ccc8a9dfce2d252.tar.bz2 |
Allow WindowGtks to be moved and sized when the mouse is over the caption or sizing border.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/118218
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17608 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 17 | ||||
-rw-r--r-- | views/window/window_gtk.cc | 109 | ||||
-rw-r--r-- | views/window/window_gtk.h | 2 |
3 files changed, 119 insertions, 9 deletions
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 9d41882..d122af1 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -57,17 +57,19 @@ #include "grit/theme_resources.h" #include "grit/webkit_resources.h" #include "views/controls/menu/menu.h" +#if defined(OS_WIN) +#include "views/controls/scrollbar/native_scroll_bar.h" +#endif #include "views/fill_layout.h" #include "views/view.h" #include "views/widget/root_view.h" #include "views/window/dialog_delegate.h" +#if !defined(OS_WIN) +#include "views/window/hit_test.h" +#endif #include "views/window/non_client_view.h" #include "views/window/window.h" -#if defined(OS_WIN) -#include "views/controls/scrollbar/native_scroll_bar.h" -#endif - using base::TimeDelta; // static @@ -1177,7 +1179,6 @@ bool BrowserView::CanClose() const { } int BrowserView::NonClientHitTest(const gfx::Point& point) { -#if defined(OS_WIN) // Since the TabStrip only renders in some parts of the top of the window, // the un-obscured area is considered to be part of the non-client caption // area of the window. So we need to treat hit-tests in these regions as @@ -1185,6 +1186,7 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) { if (!frame_->GetWindow()->IsMaximized() && !frame_->GetWindow()->IsFullscreen()) { +#if defined(OS_WIN) CRect client_rect; ::GetClientRect(frame_->GetWindow()->GetNativeWindow(), &client_rect); gfx::Size resize_corner_size = ResizeCorner::GetSize(); @@ -1199,6 +1201,7 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) { return HTBOTTOMLEFT; return HTBOTTOMRIGHT; } +#endif } // Determine if the TabStrip exists and is capable of being clicked on. We @@ -1254,10 +1257,6 @@ int BrowserView::NonClientHitTest(const gfx::Point& point) { // If the point is somewhere else, delegate to the default implementation. return views::ClientView::NonClientHitTest(point); -#else - NOTIMPLEMENTED(); - return 0; -#endif } gfx::Size BrowserView::GetMinimumSize() { diff --git a/views/window/window_gtk.cc b/views/window/window_gtk.cc index 51c726c..138fef9 100644 --- a/views/window/window_gtk.cc +++ b/views/window/window_gtk.cc @@ -7,10 +7,71 @@ #include "app/gfx/path.h" #include "app/l10n_util.h" #include "base/gfx/rect.h" +#include "views/widget/root_view.h" #include "views/window/custom_frame_view.h" +#include "views/window/hit_test.h" #include "views/window/non_client_view.h" #include "views/window/window_delegate.h" +namespace { + +// Converts a Windows-style hit test result code into a GDK window edge. +GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) { + switch (hittest_code) { + case HTBOTTOM: + return GDK_WINDOW_EDGE_SOUTH; + case HTBOTTOMLEFT: + return GDK_WINDOW_EDGE_SOUTH_WEST; + case HTBOTTOMRIGHT: + case HTGROWBOX: + return GDK_WINDOW_EDGE_SOUTH_EAST; + case HTLEFT: + return GDK_WINDOW_EDGE_WEST; + case HTRIGHT: + return GDK_WINDOW_EDGE_EAST; + case HTTOP: + return GDK_WINDOW_EDGE_NORTH; + case HTTOPLEFT: + return GDK_WINDOW_EDGE_NORTH_WEST; + case HTTOPRIGHT: + return GDK_WINDOW_EDGE_NORTH_EAST; + default: + NOTREACHED(); + break; + } + // Default to something defaultish. + return HitTestCodeToGDKWindowEdge(HTGROWBOX); +} + +// Converts a Windows-style hit test result code into a GDK cursor type. +GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) { + switch (hittest_code) { + case HTBOTTOM: + return GDK_BOTTOM_SIDE; + case HTBOTTOMLEFT: + return GDK_BOTTOM_LEFT_CORNER; + case HTBOTTOMRIGHT: + case HTGROWBOX: + return GDK_BOTTOM_RIGHT_CORNER; + case HTLEFT: + return GDK_LEFT_SIDE; + case HTRIGHT: + return GDK_RIGHT_SIDE; + case HTTOP: + return GDK_TOP_SIDE; + case HTTOPLEFT: + return GDK_TOP_LEFT_CORNER; + case HTTOPRIGHT: + return GDK_TOP_RIGHT_CORNER; + default: + break; + } + // Default to something defaultish. + return GDK_ARROW; +} + +} // namespace + namespace views { WindowGtk::~WindowGtk() { @@ -188,6 +249,54 @@ void WindowGtk::FrameTypeChanged() { //////////////////////////////////////////////////////////////////////////////// // WindowGtk, WidgetGtk overrides: +gboolean WindowGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { + int hittest_code = + non_client_view_->NonClientHitTest(gfx::Point(event->x, event->y)); + switch (hittest_code) { + case HTCAPTION: { + gfx::Point screen_point(event->x, event->y); + View::ConvertPointToScreen(GetRootView(), &screen_point); + gtk_window_begin_move_drag(GetNativeWindow(), event->button, + screen_point.x(), screen_point.y(), + event->time); + return TRUE; + } + case HTBOTTOM: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + case HTGROWBOX: + case HTLEFT: + case HTRIGHT: + case HTTOP: + case HTTOPLEFT: + case HTTOPRIGHT: { + gfx::Point screen_point(event->x, event->y); + View::ConvertPointToScreen(GetRootView(), &screen_point); + gtk_window_begin_resize_drag(GetNativeWindow(), + HitTestCodeToGDKWindowEdge(hittest_code), + event->button, screen_point.x(), + screen_point.y(), event->time); + return TRUE; + } + default: + // Everything else falls into standard client event handling... + break; + } + return WidgetGtk::OnButtonPress(widget, event); +} + +gboolean WindowGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { + // Update the cursor for the screen edge. + int hittest_code = + non_client_view_->NonClientHitTest(gfx::Point(event->x, event->y)); + GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code); + GdkCursor* cursor = gdk_cursor_new(cursor_type); + gdk_window_set_cursor(widget->window, cursor); + gdk_cursor_destroy(cursor); + + return WidgetGtk::OnMotionNotify(widget, event); +} + void WindowGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { WidgetGtk::OnSizeAllocate(widget, allocation); diff --git a/views/window/window_gtk.h b/views/window/window_gtk.h index 94cca05..5012718 100644 --- a/views/window/window_gtk.h +++ b/views/window/window_gtk.h @@ -62,6 +62,8 @@ class WindowGtk : public WidgetGtk, public Window { virtual const Window* AsWindow() const { return this; } // Overridden from WidgetGtk: + virtual gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event); + virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event); virtual void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation); protected: |