diff options
author | oshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-19 19:06:15 +0000 |
---|---|---|
committer | oshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-19 19:06:15 +0000 |
commit | 8647714eef4b0eb718c5b2682f14c9b0f5ecce13 (patch) | |
tree | e38a7ec5f5839f3f2ffbe5c546bac5406e09258a /views/desktop | |
parent | 02fe9c2b6adab15311c621a611d2405f1ea6551b (diff) | |
download | chromium_src-8647714eef4b0eb718c5b2682f14c9b0f5ecce13.zip chromium_src-8647714eef4b0eb718c5b2682f14c9b0f5ecce13.tar.gz chromium_src-8647714eef4b0eb718c5b2682f14c9b0f5ecce13.tar.bz2 |
Simple WindowManager that can move/resize window.
Fixes TouchFrame's NonClientHitTest to ignore VirtualKeyboard area.
Move mouse capture logic to Window Manager so that nested
mouse capture with nested NWVs works correctly.
Note1: This is a tentative WM that allows us to move/resize window in views desktop until we have real window manager based on aura/layer API.
Note2: There is an compositor related issue and doesn't work well when compositor is enabled. I'll look into it after this CL.
Review URL: http://codereview.chromium.org/7530017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97492 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/desktop')
-rw-r--r-- | views/desktop/desktop_window_manager.cc | 193 | ||||
-rw-r--r-- | views/desktop/desktop_window_manager.h | 69 | ||||
-rw-r--r-- | views/desktop/desktop_window_view.cc | 6 |
3 files changed, 267 insertions, 1 deletions
diff --git a/views/desktop/desktop_window_manager.cc b/views/desktop/desktop_window_manager.cc new file mode 100644 index 0000000..7276ecc --- /dev/null +++ b/views/desktop/desktop_window_manager.cc @@ -0,0 +1,193 @@ +// 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 "views/desktop/desktop_window_manager.h" + +#include "views/events/event.h" +#include "views/widget/widget.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" +#include "views/widget/widget.h" +#include "views/widget/native_widget_private.h" +#include "views/widget/native_widget_views.h" +#include "views/widget/widget_delegate.h" +#if defined(OS_LINUX) +#include "views/window/hit_test.h" +#endif +#include "views/window/non_client_view.h" + +namespace { + +class MoveWindowController : public views::desktop::WindowController { + public: + MoveWindowController(views::Widget* widget, const gfx::Point& start) + : target_(widget), + offset_(start) { + } + + virtual ~MoveWindowController() { + } + + bool OnMouseEvent(const views::MouseEvent& event) { + if (event.type()== ui::ET_MOUSE_DRAGGED) { + gfx::Point origin = event.location().Subtract(offset_); + gfx::Rect rect = target_->GetWindowScreenBounds(); + rect.set_origin(origin); + target_->SetBounds(rect); + return true; + } + return false; + } + + private: + views::Widget* target_; + gfx::Point offset_; + + DISALLOW_COPY_AND_ASSIGN(MoveWindowController); +}; + +// Simple resize controller that handle all resize as if the bottom +// right corner is selected. +class ResizeWindowController : public views::desktop::WindowController { + public: + ResizeWindowController(views::Widget* widget) + : target_(widget) { + } + + virtual ~ResizeWindowController() { + } + + bool OnMouseEvent(const views::MouseEvent& event) OVERRIDE { + if (event.type()== ui::ET_MOUSE_DRAGGED) { + gfx::Point location = event.location(); + gfx::Rect rect = target_->GetWindowScreenBounds(); + gfx::Point size = location.Subtract(rect.origin()); + target_->SetSize(gfx::Size(std::max(10, size.x()), + std::max(10, size.y()))); + return true; + } + return false; + } + + private: + views::Widget* target_; + + DISALLOW_COPY_AND_ASSIGN(ResizeWindowController); +}; + +} // namespace + +namespace views { +namespace desktop { + +WindowController::WindowController() { +} + +WindowController::~WindowController() { +} + +//////////////////////////////////////////////////////////////////////////////// +// DesktopWindowManager, public: + +DesktopWindowManager::DesktopWindowManager(Widget* desktop) + : desktop_(desktop), + mouse_capture_(NULL) { +} + +DesktopWindowManager::~DesktopWindowManager() { +} + +//////////////////////////////////////////////////////////////////////////////// +// DesktopWindowManager, WindowManager implementation: + +void DesktopWindowManager::StartMoveDrag( + views::Widget* widget, + const gfx::Point& point) { + DCHECK(!window_controller_.get()); + DCHECK(!HasMouseCapture()); + if (!widget->IsMaximized() && !widget->IsMinimized()) { + gfx::Point new_point = point; + if (desktop_->non_client_view()) { + gfx::Rect client = + desktop_->non_client_view()->frame_view()->GetBoundsForClientView(); + new_point.Offset(client.x(), client.y()); + } + SetMouseCapture(); + window_controller_.reset(new MoveWindowController(widget, new_point)); + } +} + +void DesktopWindowManager::StartResizeDrag( + views::Widget* widget, const gfx::Point& point, int hittest_code) { + DCHECK(!window_controller_.get()); + DCHECK(!HasMouseCapture()); + if (!widget->IsMaximized() && + !widget->IsMinimized() && + (widget->widget_delegate() || widget->widget_delegate()->CanResize())) { + SetMouseCapture(); + window_controller_.reset(new ResizeWindowController(widget)); + } +} + +bool DesktopWindowManager::SetMouseCapture(views::Widget* widget) { + if (mouse_capture_) + return false; + if (mouse_capture_ == widget) + return true; + DCHECK(!HasMouseCapture()); + SetMouseCapture(); + mouse_capture_ = widget; + return true; +} + +bool DesktopWindowManager::ReleaseMouseCapture(views::Widget* widget) { + if (!widget || mouse_capture_ != widget) + return false; + DCHECK(HasMouseCapture()); + ReleaseMouseCapture(); + mouse_capture_ = NULL; + return true; +} + +bool DesktopWindowManager::HasMouseCapture(const views::Widget* widget) const { + return widget && mouse_capture_ == widget; +} + +bool DesktopWindowManager::HandleMouseEvent( + views::Widget* widget, const views::MouseEvent& event) { + + if (window_controller_.get()) { + if (!window_controller_->OnMouseEvent(event)) { + ReleaseMouseCapture(); + window_controller_.reset(); + } + return true; + } + + if (mouse_capture_) { + views::MouseEvent translated(event, widget->GetRootView(), + mouse_capture_->GetRootView()); + mouse_capture_->OnMouseEvent(translated); + return true; + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// DesktopWindowManager, private: + +void DesktopWindowManager::SetMouseCapture() { + return desktop_->native_widget_private()->SetMouseCapture(); +} + +void DesktopWindowManager::ReleaseMouseCapture() { + return desktop_->native_widget_private()->ReleaseMouseCapture(); +} + +bool DesktopWindowManager::HasMouseCapture() const { + return desktop_->native_widget_private()->HasMouseCapture(); +} + +} // namespace desktop +} // namespace views diff --git a/views/desktop/desktop_window_manager.h b/views/desktop/desktop_window_manager.h new file mode 100644 index 0000000..146bb2a --- /dev/null +++ b/views/desktop/desktop_window_manager.h @@ -0,0 +1,69 @@ +// 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 VIEWS_DESKTOP_DESKTOP_WINDOW_MANAGER_H_ +#define VIEWS_DESKTOP_DESKTOP_WINDOW_MANAGER_H_ + +#include "base/compiler_specific.h" +#include "base/scoped_ptr.h" +#include "views/widget/window_manager.h" + +namespace gfx { +class Point; +} + +namespace views { +class Widget; + +namespace desktop { +class WindowController; + +// A tentative window manager for views destktop until we have *right* +// implementation based on aura/layer API. This is minimum +// implmenetation and complicated actio like moving transformed window +// doesn't work. TODO(oshima): move active widget to WindowManager. +class DesktopWindowManager : public views::WindowManager { + public: + DesktopWindowManager(Widget* desktop); + virtual ~DesktopWindowManager(); + + // views::WindowManager implementations: + virtual void StartMoveDrag(views::Widget* widget, + const gfx::Point& point) OVERRIDE; + virtual void StartResizeDrag(views::Widget* widget, + const gfx::Point& point, + int hittest_code); + virtual bool SetMouseCapture(views::Widget* widget) OVERRIDE; + virtual bool ReleaseMouseCapture(views::Widget* widget) OVERRIDE; + virtual bool HasMouseCapture(const views::Widget* widget) const OVERRIDE; + virtual bool HandleMouseEvent(views::Widget* widget, + const views::MouseEvent& event) OVERRIDE; + + private: + void SetMouseCapture(); + void ReleaseMouseCapture(); + bool HasMouseCapture() const; + + views::Widget* desktop_; + views::Widget* mouse_capture_; + scoped_ptr<WindowController> window_controller_; + + DISALLOW_COPY_AND_ASSIGN(DesktopWindowManager); +}; + +// An behavioral interface for objects implements window resize/movement. +class WindowController { + public: + WindowController(); + virtual ~WindowController(); + virtual bool OnMouseEvent(const views::MouseEvent& event) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(WindowController); +}; + +} // namespace desktop +} // namespace views + +#endif // VIEWS_DESKTOP_DESKTOP_WINDOW_MANAGER_H_ diff --git a/views/desktop/desktop_window_view.cc b/views/desktop/desktop_window_view.cc index 966f2fc..1c3c72f 100644 --- a/views/desktop/desktop_window_view.cc +++ b/views/desktop/desktop_window_view.cc @@ -8,6 +8,7 @@ #include "ui/gfx/transform.h" #include "views/desktop/desktop_background.h" #include "views/desktop/desktop_window_root_view.h" +#include "views/desktop/desktop_window_manager.h" #include "views/layer_property_setter.h" #include "views/widget/native_widget_view.h" #include "views/widget/native_widget_views.h" @@ -51,7 +52,8 @@ class DesktopWindow : public Widget { if (native_widget) return native_widget->delegate()->OnMouseEvent(event); } - return Widget::OnMouseEvent(event); + return WindowManager::Get()->HandleMouseEvent(this, event) || + Widget::OnMouseEvent(event); } DesktopWindowView* desktop_window_view_; @@ -128,6 +130,8 @@ void DesktopWindowView::CreateDesktopWindow(DesktopType type) { views::Widget* window = new DesktopWindow(desktop_window_view); desktop_window_view->widget_ = window; + WindowManager::Install(new DesktopWindowManager(window)); + views::Widget::InitParams params; params.delegate = desktop_window_view; // In this environment, CreateChromeWindow will default to creating a views- |