Index: content/browser/renderer_host/touch_selection_controller_aura.cc |
diff --git a/content/browser/renderer_host/touch_selection_controller_aura.cc b/content/browser/renderer_host/touch_selection_controller_aura.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5b529233d7c5dd1f5af1e9ea9134cad93a28bd60 |
--- /dev/null |
+++ b/content/browser/renderer_host/touch_selection_controller_aura.cc |
@@ -0,0 +1,337 @@ |
+// 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 "content/browser/renderer_host/touch_selection_controller_aura.h" |
+ |
+#include "base/debug/stack_trace.h" |
+#include "content/browser/renderer_host/touch_handle_drawable_aura.h" |
+#include "ui/aura/client/cursor_client.h" |
+#include "ui/aura/env.h" |
+#include "ui/aura/window.h" |
+#include "ui/events/event.h" |
+#include "ui/events/gesture_detection/gesture_configuration.h" |
+#include "ui/events/gestures/motion_event_aura.h" |
+ |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+gfx::RectF Union(const gfx::RectF& r1, const gfx::RectF& r2) { |
+ float x = std::min(r1.x(), r2.x()); |
+ float y = std::min(r1.y(), r2.y()); |
+ float right = std::max(r1.right(), r2.right()); |
+ float bottom = std::max(r1.bottom(), r2.bottom()); |
+ return gfx::RectF(x, y, right - x, bottom - y); |
+} |
+ |
+} |
+ |
+TouchSelectionControllerAura::TouchSelectionControllerAura( |
+ TouchSelectionControllerAuraClient* client) |
+ : client_(client), |
+ motion_event_(new ui::MotionEventAura), |
+ quick_menu_(NULL), |
+ scroll_in_progress_(false), |
+ overscroll_in_progress_(false), |
+ handle_drag_in_progress_(false) { |
+ int tap_timeout_ms = |
+ ui::GestureConfiguration::GetInstance()->show_press_delay_in_ms(); |
+ int touch_slop_pixels = |
+ ui::GestureConfiguration::GetInstance() |
+ ->max_touch_move_in_pixels_for_click(); |
+ controller_.reset(new TouchSelectionController( |
+ this, |
+ base::TimeDelta::FromMilliseconds(tap_timeout_ms), |
+ touch_slop_pixels / client_->GetDeviceScaleFactor())); |
+} |
+ |
+TouchSelectionControllerAura::~TouchSelectionControllerAura() { |
+} |
+ |
+//void TouchSelectionControllerAura::SetTemporarilyHidden(bool hidden) { |
+// controller_->SetTemporarilyHidden(hidden); |
+// // hide menu |
+//} |
+ |
+void TouchSelectionControllerAura::OnSelectionEditable(bool editable) { |
+ controller_->OnSelectionEditable(editable); |
+ UpdateQuickMenu(); |
+} |
+ |
+void TouchSelectionControllerAura::OnSelectionEmpty(bool empty) { |
+ controller_->OnSelectionEmpty(empty); |
+ UpdateQuickMenu(); |
+} |
+ |
+ |
+void TouchSelectionControllerAura::OnSelectionBoundsChanged( |
+ const cc::ViewportSelectionBound& start, |
+ const cc::ViewportSelectionBound& end) { |
+ if (start_ == start && end_ == end) |
+ return; |
+ |
+ start_ = start; |
+ end_ = end; |
+ |
+ controller_->OnSelectionBoundsChanged(start, end); |
+ UpdateQuickMenu(); |
+} |
+ |
+void TouchSelectionControllerAura::HandleGestureEvent( |
+ ui::GestureEvent* event) { |
+ switch (event->type()) { |
+ case ui::ET_GESTURE_LONG_PRESS: |
+ controller_->OnLongPressEvent(); |
+ break; |
+ case ui::ET_GESTURE_TAP: |
+ if (!controller_->is_selection_active() && |
+ !controller_->is_selection_active() && |
+ GetBoundingRect().Contains(event->x(), event->y())) { |
+ controller_->ActivateSelection(start_, end_); |
+ event->SetHandled(); |
+ } else { |
+ controller_->OnTapEvent(); |
+ } |
+ break; |
+ case ui::ET_GESTURE_SCROLL_BEGIN: |
+ scroll_in_progress_ = true; |
+ UpdateQuickMenu(); |
+ break; |
+ case ui::ET_GESTURE_SCROLL_END: |
+ scroll_in_progress_ = false; |
+ UpdateQuickMenu(); |
+ break; |
+ default: |
+ break; |
+ } |
+} |
+ |
+void TouchSelectionControllerAura::HideAndDisallowShowingAutomatically() { |
+ controller_->HideAndDisallowShowingAutomatically(); |
+ UpdateQuickMenu(); |
+} |
+ |
+void TouchSelectionControllerAura::HandleTouchEvent(ui::TouchEvent* event) { |
+ const int index = motion_event_->FindPointerIndexOfId(event->touch_id()); |
+ const bool pointer_id_is_active = index != -1; |
+ |
+ if (event->type() != ui::ET_TOUCH_PRESSED && !pointer_id_is_active) |
+ return; |
+ |
+ if (event->type() == ui::ET_TOUCH_PRESSED && pointer_id_is_active) |
+ motion_event_.reset(new ui::MotionEventAura); |
+ |
+ motion_event_->OnTouch(*event); |
+ if (controller_->WillHandleTouchEvent(*motion_event_)) |
+ event->SetHandled(); |
+ motion_event_->CleanupRemovedTouchPoints(*event); |
+} |
+ |
+void TouchSelectionControllerAura::OnWindowMoved() { |
+ UpdateQuickMenu(); |
+} |
+ |
+void TouchSelectionControllerAura::OnOverscrollStarted() { |
+ overscroll_in_progress_ = true; |
+ UpdateQuickMenu(); |
+} |
+ |
+void TouchSelectionControllerAura::OnOverscrollCompleted() { |
+ overscroll_in_progress_ = false; |
+ UpdateQuickMenu(); |
+} |
+ |
+void TouchSelectionControllerAura::OnFlingCompleted() { |
+ scroll_in_progress_ = false; |
+ UpdateQuickMenu(); |
+} |
+ |
+gfx::RectF TouchSelectionControllerAura::GetCaretBounds() const { |
+ return GetBoundingRect(); |
+} |
+ |
+gfx::RectF TouchSelectionControllerAura::GetStartRect() const { |
+ return gfx::BoundingRect(start_.edge_top, start_.edge_bottom); |
+} |
+ |
+gfx::RectF TouchSelectionControllerAura::GetEndRect() const { |
+ return gfx::BoundingRect(end_.edge_top, end_.edge_bottom); |
+} |
+ |
+gfx::RectF TouchSelectionControllerAura::GetBoundingRect() const { |
+ return Union(GetStartRect(), GetEndRect()); |
+} |
+ |
+gfx::RectF TouchSelectionControllerAura::GetAnchorRect() const { |
+ // TODO: Crop to view bounds |
+ if (start_.visible && end_.visible) |
+ return GetBoundingRect(); |
+ if (start_.visible) |
+ return GetStartRect(); |
+ return GetEndRect(); |
+} |
+ |
+void TouchSelectionControllerAura::QuickMenuTimerFired() { |
+ DCHECK(controller_->is_insertion_active() || |
+ controller_->is_selection_active()); |
+ |
+ if (!start_.visible && !end_.visible) |
+ return; |
+ |
+ quick_menu_ = views::TouchEditingMenuView::Create( |
+ this, |
+ client_->ConvertRectToScreen(GetAnchorRect()), |
+ gfx::Size(20, 50), |
+ client_->GetParentWindow()->GetToplevelWindow()); |
+} |
+ |
+void TouchSelectionControllerAura::UpdateQuickMenu() { |
+ // Hide quick menu if there is any. |
+ if (quick_menu_) { |
+ quick_menu_->Close(); |
+ quick_menu_ = NULL; |
+ } else { |
+ quick_menu_timer_.Stop(); |
+ } |
+ |
+ // Start timer to show quick menu if necessary. |
+ if (!controller_->is_insertion_active() && |
+ !controller_->is_selection_active()) |
+ return; |
+ |
+ if (!IsQuickMenuAllowed()) |
+ return; |
+ |
+ quick_menu_timer_.Start( |
+ FROM_HERE, |
+ base::TimeDelta::FromMilliseconds(100), |
+ this, |
+ &TouchSelectionControllerAura::QuickMenuTimerFired); |
+} |
+ |
+bool TouchSelectionControllerAura::IsQuickMenuAllowed() const { |
+ return !scroll_in_progress_ && !overscroll_in_progress_ && |
+ !handle_drag_in_progress_; |
+} |
+ |
+bool TouchSelectionControllerAura::SupportsAnimation() const { |
+ return false; |
+} |
+ |
+void TouchSelectionControllerAura::SetNeedsAnimate() { |
+ NOTREACHED(); |
+} |
+ |
+void TouchSelectionControllerAura::MoveCaret(const gfx::PointF& position) { |
+ client_->MoveCaret(position); |
+} |
+ |
+void TouchSelectionControllerAura::SelectBetweenCoordinates( |
+ const gfx::PointF& start, |
+ const gfx::PointF& end) { |
+ client_->SelectBetweenCoordinates(start, end); |
+} |
+ |
+void TouchSelectionControllerAura::OnSelectionEvent( |
+ SelectionEventType event, |
+ const gfx::PointF& position) { |
+ //if (event != INSERTION_MOVED) |
+ // handle_drag_in_progress_ = false; |
+ switch (event) { |
+ case SELECTION_SHOWN: |
+ UpdateQuickMenu(); |
+ aura::Env::GetInstance()->AddPreTargetHandler(this); |
+ break; |
+ case SELECTION_CLEARED: |
+ aura::Env::GetInstance()->RemovePreTargetHandler(this); |
+ UpdateQuickMenu(); |
+ break; |
+ case SELECTION_DRAG_STARTED: |
+ handle_drag_in_progress_ = true; |
+ UpdateQuickMenu(); |
+ break; |
+ case SELECTION_DRAG_STOPPED: |
+ handle_drag_in_progress_ = false; |
+ UpdateQuickMenu(); |
+ break; |
+ case INSERTION_SHOWN: |
+ UpdateQuickMenu(); |
+ aura::Env::GetInstance()->AddPreTargetHandler(this); |
+ break; |
+ case INSERTION_MOVED: |
+ break; |
+ case INSERTION_TAPPED: |
+ //UpdateQuickMenu(); |
+ break; |
+ case INSERTION_CLEARED: |
+ aura::Env::GetInstance()->RemovePreTargetHandler(this); |
+ UpdateQuickMenu(); |
+ break; |
+ case INSERTION_DRAG_STARTED: |
+ //handle_drag_in_progress_ = true; |
+ //UpdateQuickMenu(); |
+ break; |
+ }; |
+} |
+ |
+scoped_ptr<TouchHandleDrawable> TouchSelectionControllerAura::CreateDrawable() { |
+ return scoped_ptr<TouchHandleDrawable>( |
+ new TouchHandleDrawableAura(client_->GetParentWindow())); |
+} |
+ |
+bool TouchSelectionControllerAura::IsCommandIdEnabled(int command_id) const { |
+ return client_->IsCommandIdEnabled(command_id); |
+} |
+ |
+void TouchSelectionControllerAura::ExecuteCommand(int command_id, |
+ int event_flags) { |
+ HideAndDisallowShowingAutomatically(); |
+ client_->ExecuteCommand(command_id, event_flags); |
+} |
+ |
+void TouchSelectionControllerAura::OpenContextMenu() { |
+ HideAndDisallowShowingAutomatically(); |
+ gfx::RectF anchor_rect = GetAnchorRect(); |
+ client_->OpenContextMenu( |
+ gfx::PointF(anchor_rect.CenterPoint().x(), anchor_rect.y())); |
+} |
+ |
+void TouchSelectionControllerAura::OnMenuClosed( |
+ views::TouchEditingMenuView* menu) { |
+ if (menu == quick_menu_) |
+ quick_menu_ = NULL; |
+} |
+ |
+void TouchSelectionControllerAura::OnKeyEvent(ui::KeyEvent* event) { |
+ LOG(ERROR) << "KeyEvent: " << event->name(); |
+ |
+ DCHECK(controller_->is_insertion_active() || |
+ controller_->is_selection_active()); |
+ |
+ HideAndDisallowShowingAutomatically(); |
+} |
+ |
+void TouchSelectionControllerAura::OnMouseEvent(ui::MouseEvent* event) { |
+ LOG(ERROR) << "MouseEvent: " << event->name(); |
+ |
+ DCHECK(controller_->is_insertion_active() || |
+ controller_->is_selection_active()); |
+ |
+ aura::client::CursorClient* cursor_client = aura::client::GetCursorClient( |
+ client_->GetParentWindow()->GetRootWindow()); |
+ if (!cursor_client || cursor_client->IsMouseEventsEnabled()) |
+ HideAndDisallowShowingAutomatically(); |
+} |
+ |
+void TouchSelectionControllerAura::OnScrollEvent(ui::ScrollEvent* event) { |
+ LOG(ERROR) << "ScrollEvent: " << event->name(); |
+ |
+ DCHECK(controller_->is_insertion_active() || |
+ controller_->is_selection_active()); |
+ |
+ HideAndDisallowShowingAutomatically(); |
+} |
+ |
+} |