diff options
-rw-r--r-- | ui/views/touchui/touch_selection_controller_impl.cc | 47 | ||||
-rw-r--r-- | ui/views/touchui/touch_selection_controller_impl.h | 3 | ||||
-rw-r--r-- | ui/views/views.gyp | 1 | ||||
-rw-r--r-- | ui/wm/core/masked_window_targeter.cc | 41 | ||||
-rw-r--r-- | ui/wm/public/masked_window_targeter.h | 38 | ||||
-rw-r--r-- | ui/wm/wm.gyp | 2 |
6 files changed, 129 insertions, 3 deletions
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc index 41720be..4f1aac4b1 100644 --- a/ui/views/touchui/touch_selection_controller_impl.cc +++ b/ui/views/touchui/touch_selection_controller_impl.cc @@ -17,6 +17,7 @@ #include "ui/gfx/size.h" #include "ui/views/corewm/shadow_types.h" #include "ui/views/widget/widget.h" +#include "ui/wm/public/masked_window_targeter.h" namespace { @@ -112,12 +113,31 @@ gfx::Rect ConvertFromScreen(ui::TouchEditable* client, const gfx::Rect& rect) { namespace views { +typedef TouchSelectionControllerImpl::EditingHandleView EditingHandleView; + +class TouchHandleWindowTargeter : public wm::MaskedWindowTargeter { + public: + TouchHandleWindowTargeter(aura::Window* window, + EditingHandleView* handle_view); + + virtual ~TouchHandleWindowTargeter() {} + + private: + // wm::MaskedWindowTargeter: + virtual void GetHitTestMask(aura::Window* window, + gfx::Path* mask) const OVERRIDE; + + EditingHandleView* handle_view_; + + DISALLOW_COPY_AND_ASSIGN(TouchHandleWindowTargeter); +}; + // A View that displays the text selection handle. class TouchSelectionControllerImpl::EditingHandleView : public views::WidgetDelegateView { public: - explicit EditingHandleView(TouchSelectionControllerImpl* controller, - gfx::NativeView context) + EditingHandleView(TouchSelectionControllerImpl* controller, + gfx::NativeView context) : controller_(controller), drag_offset_(0), draw_invisible_(false) { @@ -125,6 +145,10 @@ class TouchSelectionControllerImpl::EditingHandleView widget_->SetContentsView(this); widget_->SetAlwaysOnTop(true); + aura::Window* window = widget_->GetNativeWindow(); + window->set_event_targeter(scoped_ptr<ui::EventTargeter>( + new TouchHandleWindowTargeter(window, this))); + // We are owned by the TouchSelectionController. set_owned_by_client(); } @@ -235,6 +259,8 @@ class TouchSelectionControllerImpl::EditingHandleView SchedulePaint(); } + const gfx::Rect& selection_rect() const { return selection_rect_; } + private: scoped_ptr<Widget> widget_; TouchSelectionControllerImpl* controller_; @@ -254,6 +280,23 @@ class TouchSelectionControllerImpl::EditingHandleView DISALLOW_COPY_AND_ASSIGN(EditingHandleView); }; +TouchHandleWindowTargeter::TouchHandleWindowTargeter( + aura::Window* window, + EditingHandleView* handle_view) + : wm::MaskedWindowTargeter(window), + handle_view_(handle_view) { +} + +void TouchHandleWindowTargeter::GetHitTestMask(aura::Window* window, + gfx::Path* mask) const { + const gfx::Rect& selection_rect = handle_view_->selection_rect(); + gfx::Size image_size = GetHandleImageSize(); + mask->addRect(SkIntToScalar(0), SkIntToScalar(selection_rect.height()), + SkIntToScalar(image_size.width()) + 2 * kSelectionHandleHorizPadding, + SkIntToScalar(selection_rect.height() + image_size.height() + + kSelectionHandleVertPadding)); +} + TouchSelectionControllerImpl::TouchSelectionControllerImpl( ui::TouchEditable* client_view) : client_view_(client_view), diff --git a/ui/views/touchui/touch_selection_controller_impl.h b/ui/views/touchui/touch_selection_controller_impl.h index dc9babe..31c9bc0 100644 --- a/ui/views/touchui/touch_selection_controller_impl.h +++ b/ui/views/touchui/touch_selection_controller_impl.h @@ -21,6 +21,8 @@ class VIEWS_EXPORT TouchSelectionControllerImpl public TouchEditingMenuController, public WidgetObserver { public: + class EditingHandleView; + // Use TextSelectionController::create(). explicit TouchSelectionControllerImpl( ui::TouchEditable* client_view); @@ -33,7 +35,6 @@ class VIEWS_EXPORT TouchSelectionControllerImpl private: friend class TouchSelectionControllerImplTest; - class EditingHandleView; void SetDraggingHandle(EditingHandleView* handle); diff --git a/ui/views/views.gyp b/ui/views/views.gyp index b2810ee..ce8e690 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -37,6 +37,7 @@ '../native_theme/native_theme.gyp:native_theme', '../resources/ui_resources.gyp:ui_resources', '../ui.gyp:ui', + '../wm/wm.gyp:wm_public', ], 'defines': [ 'VIEWS_IMPLEMENTATION', diff --git a/ui/wm/core/masked_window_targeter.cc b/ui/wm/core/masked_window_targeter.cc new file mode 100644 index 0000000..3de6140 --- /dev/null +++ b/ui/wm/core/masked_window_targeter.cc @@ -0,0 +1,41 @@ +// Copyright 2014 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/wm/public/masked_window_targeter.h" + +#include "ui/aura/window.h" +#include "ui/gfx/path.h" + +namespace wm { + +MaskedWindowTargeter::MaskedWindowTargeter(aura::Window* masked_window) + : masked_window_(masked_window) { +} + +MaskedWindowTargeter::~MaskedWindowTargeter() {} + +bool MaskedWindowTargeter::EventLocationInsideBounds( + aura::Window* window, + const ui::LocatedEvent& event) const { + if (window == masked_window_) { + gfx::Path mask; + GetHitTestMask(window, &mask); + + gfx::Size size = window->bounds().size(); + SkRegion clip_region; + clip_region.setRect(0, 0, size.width(), size.height()); + + gfx::Point point = event.location(); + if (window->parent()) + aura::Window::ConvertPointToTarget(window->parent(), window, &point); + + SkRegion mask_region; + return mask_region.setPath(mask, clip_region) && + mask_region.contains(point.x(), point.y()); + } + + return WindowTargeter::EventLocationInsideBounds(window, event); +} + +} // namespace wm diff --git a/ui/wm/public/masked_window_targeter.h b/ui/wm/public/masked_window_targeter.h new file mode 100644 index 0000000..c5b4d88 --- /dev/null +++ b/ui/wm/public/masked_window_targeter.h @@ -0,0 +1,38 @@ +// Copyright 2014 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_WM_PUBLIC_MASKED_WINDOW_TARGETER_H_ +#define UI_WM_PUBLIC_MASKED_WINDOW_TARGETER_H_ + +#include "ui/aura/window_targeter.h" + +namespace gfx { +class Path; +} + +namespace wm { + +class MaskedWindowTargeter : public aura::WindowTargeter { + public: + explicit MaskedWindowTargeter(aura::Window* masked_window); + virtual ~MaskedWindowTargeter(); + + protected: + // Sets the hit-test mask for |window| in |mask| (in |window|'s local + // coordinate system). + virtual void GetHitTestMask(aura::Window* window, gfx::Path* mask) const = 0; + + // aura::WindowTargeter: + virtual bool EventLocationInsideBounds( + aura::Window* window, + const ui::LocatedEvent& event) const OVERRIDE; + + aura::Window* masked_window_; + + DISALLOW_COPY_AND_ASSIGN(MaskedWindowTargeter); +}; + +} // namespace wm + +#endif // UI_WM_PUBLIC_MASKED_WINDOW_TARGETER_H_ diff --git a/ui/wm/wm.gyp b/ui/wm/wm.gyp index 725d9ea..6071fac 100644 --- a/ui/wm/wm.gyp +++ b/ui/wm/wm.gyp @@ -17,7 +17,9 @@ ], 'sources': [ 'core/easy_resize_window_targeter.cc', + 'core/masked_window_targeter.cc', 'public/easy_resize_window_targeter.h', + 'public/masked_window_targeter.h', 'public/window_types.h', ], }, |