12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/touchui/touch_selection_controller_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "grit/ui_resources.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_strings.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/aura/client/cursor_client.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/aura/env.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/aura/window.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/image/image.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/path.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/masked_window_targeter.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_animations.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constants defining the visual attributes of selection handles 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kSelectionHandleLineWidth = 1; 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const SkColor kSelectionHandleLineColor = 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkColorSetRGB(0x42, 0x81, 0xf4); 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 31bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// When a handle is dragged, the drag position reported to the client view is 32bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// offset vertically to represent the cursor position. This constant specifies 33bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// the offset in pixels above the "O" (see pic below). This is required because 34bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// say if this is zero, that means the drag position we report is the point 35bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// right above the "O" or the bottom most point of the cursor "|". In that case, 36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// a vertical movement of even one pixel will make the handle jump to the line 37bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// below it. So when the user just starts dragging, the handle will jump to the 38bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// next line if the user makes any vertical movement. It is correct but 39bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// looks/feels weird. So we have this non-zero offset to prevent this jumping. 40bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// 41bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Editing handle widget showing the difference between the position of the 42bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// ET_GESTURE_SCROLL_UPDATE event and the drag position reported to the client: 43bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// _____ 44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// | |<-|---- Drag position reported to client 45bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// _ | O | 46bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Vertical Padding __| | <-|---- ET_GESTURE_SCROLL_UPDATE position 47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// |_ |_____|<--- Editing handle widget 48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// 49bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// | | 50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// T 51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Horizontal Padding 52bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// 53bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst int kSelectionHandleVerticalDragOffset = 5; 54bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Padding around the selection handle defining the area that will be included 56bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// in the touch target to make dragging the handle easier (see pic above). 57bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst int kSelectionHandleHorizPadding = 10; 58bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst int kSelectionHandleVertPadding = 20; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kContextMenuTimoutMs = 200; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kSelectionHandleQuickFadeDurationMs = 50; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Minimum height for selection handle bar. If the bar height is going to be 65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// less than this value, handle will not be shown. 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int kSelectionHandleBarMinHeight = 5; 67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Maximum amount that selection handle bar can stick out of client view's 68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// boundaries. 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int kSelectionHandleBarBottomAllowance = 3; 70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a widget to host SelectionHandleView. 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)views::Widget* CreateTouchSelectionPopupWidget( 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::NativeView context, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::WidgetDelegate* widget_delegate) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = new views::Widget; 76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch params.parent = context; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.delegate = widget_delegate; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget->Init(params); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return widget; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)gfx::Image* GetHandleImage() { 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static gfx::Image* handle_image = NULL; 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!handle_image) { 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed( 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IDR_TEXT_SELECTION_HANDLE); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return handle_image; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)gfx::Size GetHandleImageSize() { 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return GetHandleImage()->Size(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Cannot use gfx::UnionRect since it does not work for empty rects. 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochgfx::Rect Union(const gfx::Rect& r1, const gfx::Rect& r2) { 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int rx = std::min(r1.x(), r2.x()); 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int ry = std::min(r1.y(), r2.y()); 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int rr = std::max(r1.right(), r2.right()); 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int rb = std::max(r1.bottom(), r2.bottom()); 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return gfx::Rect(rx, ry, rr - rx, rb - ry); 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Convenience methods to convert a |rect| from screen to the |client|'s 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// coordinate system and vice versa. 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Note that this is not quite correct because it does not take into account 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// transforms such as rotation and scaling. This should be in TouchEditable. 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// TODO(varunjain): Fix this. 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochgfx::Rect ConvertFromScreen(ui::TouchEditable* client, const gfx::Rect& rect) { 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Point origin = rect.origin(); 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client->ConvertPointFromScreen(&origin); 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return gfx::Rect(origin, rect.size()); 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochgfx::Rect ConvertToScreen(ui::TouchEditable* client, const gfx::Rect& rect) { 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Point origin = rect.origin(); 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch client->ConvertPointToScreen(&origin); 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return gfx::Rect(origin, rect.size()); 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef TouchSelectionControllerImpl::EditingHandleView EditingHandleView; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TouchHandleWindowTargeter : public wm::MaskedWindowTargeter { 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TouchHandleWindowTargeter(aura::Window* window, 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EditingHandleView* handle_view); 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~TouchHandleWindowTargeter() {} 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // wm::MaskedWindowTargeter: 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool GetHitTestMask(aura::Window* window, 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Path* mask) const OVERRIDE; 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EditingHandleView* handle_view_; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TouchHandleWindowTargeter); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A View that displays the text selection handle. 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TouchSelectionControllerImpl::EditingHandleView 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : public views::WidgetDelegateView { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EditingHandleView(TouchSelectionControllerImpl* controller, 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::NativeView context) 154bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch : controller_(controller), 155bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch drag_offset_(0), 156bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch draw_invisible_(false) { 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) widget_.reset(CreateTouchSelectionPopupWidget(context, this)); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_->SetContentsView(this); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* window = widget_->GetNativeWindow(); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new TouchHandleWindowTargeter(window, this))); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are owned by the TouchSelectionController. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_owned_by_client(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~EditingHandleView() { 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetWidgetVisible(false, false); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from views::WidgetDelegateView: 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool WidgetHasHitTestMask() const OVERRIDE { 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetWidgetHitTestMask(gfx::Path* mask) const OVERRIDE { 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Size image_size = GetHandleImageSize(); 1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) mask->addRect(SkIntToScalar(0), SkIntToScalar(selection_rect_.height()), 180bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch SkIntToScalar(image_size.width()) + 2 * kSelectionHandleHorizPadding, 1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkIntToScalar(selection_rect_.height() + image_size.height() + 182bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch kSelectionHandleVertPadding)); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void DeleteDelegate() OVERRIDE { 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We are owned and deleted by TouchSelectionController. 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from views::View: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 191bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (draw_invisible_) 192bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return; 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Size image_size = GetHandleImageSize(); 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int cursor_pos_x = image_size.width() / 2 - kSelectionHandleLineWidth + 195bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch kSelectionHandleHorizPadding; 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Draw the cursor line. 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) canvas->FillRect( 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Rect(cursor_pos_x, 0, 2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2 * kSelectionHandleLineWidth + 1, selection_rect_.height()), 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kSelectionHandleLineColor); 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Draw the handle image. 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) canvas->DrawImageInt(*GetHandleImage()->ToImageSkia(), 2058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) kSelectionHandleHorizPadding, selection_rect_.height()); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->SetHandled(); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (event->type()) { 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_GESTURE_SCROLL_BEGIN: 2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch widget_->SetCapture(this); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller_->SetDraggingHandle(this); 2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) drag_offset_ = event->y() - selection_rect_.height() + 215bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch kSelectionHandleVerticalDragOffset; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 217bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch case ui::ET_GESTURE_SCROLL_UPDATE: { 218bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch gfx::Point drag_pos(event->location().x(), 219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch event->location().y() - drag_offset_); 220bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch controller_->SelectionHandleDragged(drag_pos); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 222bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ui::ET_GESTURE_SCROLL_END: 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ui::ET_SCROLL_FLING_START: 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch widget_->ReleaseCapture(); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller_->SetDraggingHandle(NULL); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE { 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Size image_size = GetHandleImageSize(); 235bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return gfx::Size(image_size.width() + 2 * kSelectionHandleHorizPadding, 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) image_size.height() + selection_rect_.height() + 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) kSelectionHandleVertPadding); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsWidgetVisible() const { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return widget_->IsVisible(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetWidgetVisible(bool visible, bool quick) { 2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (widget_->IsVisible() == visible) 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::SetWindowVisibilityAnimationDuration( 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) widget_->GetNativeView(), 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds( 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) quick ? kSelectionHandleQuickFadeDurationMs : 0)); 2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (visible) 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) widget_->Show(); 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) else 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) widget_->Hide(); 2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetSelectionRectInScreen(const gfx::Rect& rect) { 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Size image_size = GetHandleImageSize(); 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch selection_rect_ = rect; 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Rect widget_bounds( 261bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch rect.x() - image_size.width() / 2 - kSelectionHandleHorizPadding, 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rect.y(), 263bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch image_size.width() + 2 * kSelectionHandleHorizPadding, 264bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch rect.height() + image_size.height() + kSelectionHandleVertPadding); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) widget_->SetBounds(widget_bounds); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point GetScreenPosition() { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return widget_->GetClientAreaBoundsInScreen().origin(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch void SetDrawInvisible(bool draw_invisible) { 273bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (draw_invisible_ == draw_invisible) 274bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return; 275bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch draw_invisible_ = draw_invisible; 276bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch SchedulePaint(); 277bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 278bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& selection_rect() const { return selection_rect_; } 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Widget> widget_; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TouchSelectionControllerImpl* controller_; 2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Rect selection_rect_; 28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Vertical offset between the scroll event position and the drag position 28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // reported to the client view (see the ASCII figure at the top of the file 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // and its description for more details). 289bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch int drag_offset_; 290bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 291bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // If set to true, the handle will not draw anything, hence providing an empty 292bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // widget. We need this because we may want to stop showing the handle while 293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // it is being dragged. Since it is being dragged, we cannot destroy the 294bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // handle. 295bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch bool draw_invisible_; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EditingHandleView); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TouchHandleWindowTargeter::TouchHandleWindowTargeter( 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* window, 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EditingHandleView* handle_view) 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : wm::MaskedWindowTargeter(window), 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) handle_view_(handle_view) { 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool TouchHandleWindowTargeter::GetHitTestMask(aura::Window* window, 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Path* mask) const { 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect& selection_rect = handle_view_->selection_rect(); 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Size image_size = GetHandleImageSize(); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mask->addRect(SkIntToScalar(0), SkIntToScalar(selection_rect.height()), 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkIntToScalar(image_size.width()) + 2 * kSelectionHandleHorizPadding, 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkIntToScalar(selection_rect.height() + image_size.height() + 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kSelectionHandleVertPadding)); 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TouchSelectionControllerImpl::TouchSelectionControllerImpl( 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::TouchEditable* client_view) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : client_view_(client_view), 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_widget_(NULL), 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) selection_handle_1_(new EditingHandleView(this, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view->GetNativeView())), 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) selection_handle_2_(new EditingHandleView(this, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view->GetNativeView())), 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cursor_handle_(new EditingHandleView(this, 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view->GetNativeView())), 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_(NULL), 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dragging_handle_(NULL) { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_widget_ = Widget::GetTopLevelWidgetForNativeView( 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view_->GetNativeView()); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_widget_) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_widget_->AddObserver(this); 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::Env::GetInstance()->AddPreTargetHandler(this); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TouchSelectionControllerImpl::~TouchSelectionControllerImpl() { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HideContextMenu(); 339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::Env::GetInstance()->RemovePreTargetHandler(this); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_widget_) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_widget_->RemoveObserver(this); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::SelectionChanged() { 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect r1, r2; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view_->GetSelectionEndPoints(&r1, &r2); 347a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect screen_rect_1 = ConvertToScreen(client_view_, r1); 348a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect screen_rect_2 = ConvertToScreen(client_view_, r2); 349a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect client_bounds = client_view_->GetBounds(); 350a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (r1.y() < client_bounds.y()) 351a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch r1.Inset(0, client_bounds.y() - r1.y(), 0, 0); 352a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (r2.y() < client_bounds.y()) 353a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch r2.Inset(0, client_bounds.y() - r2.y(), 0, 0); 354a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect screen_rect_1_clipped = ConvertToScreen(client_view_, r1); 355a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect screen_rect_2_clipped = ConvertToScreen(client_view_, r2); 356a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (screen_rect_1_clipped == selection_end_point_1_clipped_ && 357a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch screen_rect_2_clipped == selection_end_point_2_clipped_) 3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) selection_end_point_1_ = screen_rect_1; 3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) selection_end_point_2_ = screen_rect_2; 362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch selection_end_point_1_clipped_ = screen_rect_1_clipped; 363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch selection_end_point_2_clipped_ = screen_rect_2_clipped; 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_view_->DrawsHandles()) { 366a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UpdateContextMenu(); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dragging_handle_) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to reposition only the selection handle that is being dragged. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The other handle stays the same. Also, the selection handle being dragged 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will always be at the end of selection, while the other handle will be at 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the start. 3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If the new location of this handle is out of client view, its widget 3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // should not get hidden, since it should still receive touch events. 3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Hence, we are not using |SetHandleSelectionRect()| method here. 377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch dragging_handle_->SetSelectionRectInScreen(screen_rect_2_clipped); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 379bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Temporary fix for selection handle going outside a window. On a webpage, 380bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // the page should scroll if the selection handle is dragged outside the 381bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // window. That does not happen currently. So we just hide the handle for 382bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // now. 383bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // TODO(varunjain): Fix this: crbug.com/269003 384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch dragging_handle_->SetDrawInvisible(!ShouldShowHandleFor(r2)); 385bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dragging_handle_ != cursor_handle_.get()) { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The non-dragging-handle might have recently become visible. 3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EditingHandleView* non_dragging_handle = selection_handle_1_.get(); 3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (dragging_handle_ == selection_handle_1_) { 3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) non_dragging_handle = selection_handle_2_.get(); 3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // if handle 1 is being dragged, it is corresponding to the end of 3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // selection and the other handle to the start of selection. 3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) selection_end_point_1_ = screen_rect_2; 3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) selection_end_point_2_ = screen_rect_1; 395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch selection_end_point_1_clipped_ = screen_rect_2_clipped; 396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch selection_end_point_2_clipped_ = screen_rect_1_clipped; 3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetHandleSelectionRect(non_dragging_handle, r1, screen_rect_1_clipped); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UpdateContextMenu(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if there is any selection at all. 404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (screen_rect_1.origin() == screen_rect_2.origin()) { 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) selection_handle_1_->SetWidgetVisible(false, false); 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) selection_handle_2_->SetWidgetVisible(false, false); 407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetHandleSelectionRect(cursor_handle_.get(), r1, screen_rect_1_clipped); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor_handle_->SetWidgetVisible(false, false); 412a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetHandleSelectionRect(selection_handle_1_.get(), r1, 413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch screen_rect_1_clipped); 414a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetHandleSelectionRect(selection_handle_2_.get(), r2, 415a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch screen_rect_2_clipped); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TouchSelectionControllerImpl::IsHandleDragInProgress() { 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !!dragging_handle_; 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TouchSelectionControllerImpl::HideHandles(bool quick) { 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) selection_handle_1_->SetWidgetVisible(false, quick); 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) selection_handle_2_->SetWidgetVisible(false, quick); 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor_handle_->SetWidgetVisible(false, quick); 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::SetDraggingHandle( 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EditingHandleView* handle) { 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dragging_handle_ = handle; 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dragging_handle_) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HideContextMenu(); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartContextMenuTimer(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TouchSelectionControllerImpl::SelectionHandleDragged( 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& drag_pos) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not want to show the context menu while dragging. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HideContextMenu(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(dragging_handle_); 444bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch gfx::Point drag_pos_in_client = drag_pos; 445bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ConvertPointToClientView(dragging_handle_, &drag_pos_in_client); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dragging_handle_ == cursor_handle_.get()) { 448bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch client_view_->MoveCaretTo(drag_pos_in_client); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find the stationary selection handle. 4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Rect fixed_handle_rect = selection_end_point_1_; 4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (selection_handle_1_ == dragging_handle_) 4558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) fixed_handle_rect = selection_end_point_2_; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find selection end points in client_view's coordinate system. 4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Point p2 = fixed_handle_rect.origin(); 4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) p2.Offset(0, fixed_handle_rect.height() / 2); 4607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client_view_->ConvertPointFromScreen(&p2); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Instruct client_view to select the region between p1 and p2. The position 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of |fixed_handle| is the start and that of |dragging_handle| is the end 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of selection. 465bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch client_view_->SelectRect(p2, drag_pos_in_client); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TouchSelectionControllerImpl::ConvertPointToClientView( 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EditingHandleView* source, gfx::Point* point) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View::ConvertPointToScreen(source, point); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view_->ConvertPointFromScreen(point); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TouchSelectionControllerImpl::SetHandleSelectionRect( 4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) EditingHandleView* handle, 4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Rect& rect, 4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const gfx::Rect& rect_in_screen) { 478a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch handle->SetWidgetVisible(ShouldShowHandleFor(rect), false); 4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (handle->IsWidgetVisible()) 4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) handle->SetSelectionRectInScreen(rect_in_screen); 4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 483a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool TouchSelectionControllerImpl::ShouldShowHandleFor( 484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const gfx::Rect& rect) const { 485a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (rect.height() < kSelectionHandleBarMinHeight) 486a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return false; 487a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect bounds = client_view_->GetBounds(); 488a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bounds.Inset(0, 0, 0, -kSelectionHandleBarBottomAllowance); 489a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return bounds.Contains(rect); 490a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 491a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TouchSelectionControllerImpl::IsCommandIdEnabled(int command_id) const { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return client_view_->IsCommandIdEnabled(command_id); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::ExecuteCommand(int command_id, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int event_flags) { 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HideContextMenu(); 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view_->ExecuteCommand(command_id, event_flags); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::OpenContextMenu() { 5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Context menu should appear centered on top of the selected region. 5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Rect rect = context_menu_->GetAnchorRect(); 5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const gfx::Point anchor(rect.CenterPoint().x(), rect.y()); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HideContextMenu(); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_view_->OpenContextMenu(anchor); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::OnMenuClosed(TouchEditingMenuView* menu) { 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (menu == context_menu_) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_ = NULL; 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::OnWidgetClosing(Widget* widget) { 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(client_widget_, widget); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_widget_ = NULL; 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::OnWidgetBoundsChanged( 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Widget* widget, 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& new_bounds) { 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(client_widget_, widget); 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HideContextMenu(); 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SelectionChanged(); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void TouchSelectionControllerImpl::OnKeyEvent(ui::KeyEvent* event) { 529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_view_->DestroyTouchSelection(); 530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void TouchSelectionControllerImpl::OnMouseEvent(ui::MouseEvent* event) { 533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) aura::client::CursorClient* cursor_client = aura::client::GetCursorClient( 534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_view_->GetNativeView()->GetRootWindow()); 535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!cursor_client || cursor_client->IsMouseEventsEnabled()) 536010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_view_->DestroyTouchSelection(); 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 539010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void TouchSelectionControllerImpl::OnScrollEvent(ui::ScrollEvent* event) { 540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) client_view_->DestroyTouchSelection(); 541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TouchSelectionControllerImpl::ContextMenuTimerFired() { 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get selection end points in client_view's space. 5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Rect end_rect_1_in_screen; 5467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Rect end_rect_2_in_screen; 547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (cursor_handle_->IsWidgetVisible()) { 548a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch end_rect_1_in_screen = selection_end_point_1_clipped_; 5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch end_rect_2_in_screen = end_rect_1_in_screen; 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 551a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch end_rect_1_in_screen = selection_end_point_1_clipped_; 552a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch end_rect_2_in_screen = selection_end_point_2_clipped_; 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Convert from screen to client. 5567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Rect end_rect_1(ConvertFromScreen(client_view_, end_rect_1_in_screen)); 5577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Rect end_rect_2(ConvertFromScreen(client_view_, end_rect_2_in_screen)); 5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if selection is completely inside the view, we display the context menu 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in the middle of the end points on the top. Else, we show it above the 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // visible handle. If no handle is visible, we do not show the menu. 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect menu_anchor; 563a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (ShouldShowHandleFor(end_rect_1) && 564a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ShouldShowHandleFor(end_rect_2)) 5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch menu_anchor = Union(end_rect_1_in_screen,end_rect_2_in_screen); 566a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch else if (ShouldShowHandleFor(end_rect_1)) 5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch menu_anchor = end_rect_1_in_screen; 568a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch else if (ShouldShowHandleFor(end_rect_2)) 5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch menu_anchor = end_rect_2_in_screen; 5707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!context_menu_); 5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch context_menu_ = TouchEditingMenuView::Create(this, menu_anchor, 575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetHandleImageSize(), 5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client_view_->GetNativeView()); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TouchSelectionControllerImpl::StartContextMenuTimer() { 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_menu_timer_.IsRunning()) 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_timer_.Start( 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kContextMenuTimoutMs), 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &TouchSelectionControllerImpl::ContextMenuTimerFired); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 589a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid TouchSelectionControllerImpl::UpdateContextMenu() { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide context menu to be shown when the timer fires. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HideContextMenu(); 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartContextMenuTimer(); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TouchSelectionControllerImpl::HideContextMenu() { 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_menu_) 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_->Close(); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_menu_ = NULL; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_menu_timer_.Stop(); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochgfx::NativeView TouchSelectionControllerImpl::GetCursorHandleNativeView() { 603a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return cursor_handle_->GetWidget()->GetNativeView(); 604a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 605a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point TouchSelectionControllerImpl::GetSelectionHandle1Position() { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return selection_handle_1_->GetScreenPosition(); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point TouchSelectionControllerImpl::GetSelectionHandle2Position() { 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return selection_handle_2_->GetScreenPosition(); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Point TouchSelectionControllerImpl::GetCursorHandlePosition() { 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return cursor_handle_->GetScreenPosition(); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TouchSelectionControllerImpl::IsSelectionHandle1Visible() { 6198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return selection_handle_1_->IsWidgetVisible(); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TouchSelectionControllerImpl::IsSelectionHandle2Visible() { 6238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return selection_handle_2_->IsWidgetVisible(); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool TouchSelectionControllerImpl::IsCursorHandleVisible() { 6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cursor_handle_->IsWidgetVisible(); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace views 631