OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/frame_host/touch_selection_controller_client_child_fra
me.h" |
| 6 |
| 7 #include "content/browser/frame_host/cross_process_frame_connector.h" |
| 8 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
| 9 #include "content/browser/renderer_host/input/touch_selection_controller_client_
manager.h" |
| 10 #include "content/browser/renderer_host/render_widget_host_delegate.h" |
| 11 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 12 #include "content/common/content_switches_internal.h" |
| 13 #include "content/common/view_messages.h" |
| 14 #include "ui/base/clipboard/clipboard.h" |
| 15 #include "ui/gfx/geometry/point_conversions.h" |
| 16 #include "ui/strings/grit/ui_strings.h" |
| 17 |
| 18 namespace content { |
| 19 |
| 20 TouchSelectionControllerClientChildFrame:: |
| 21 TouchSelectionControllerClientChildFrame( |
| 22 RenderWidgetHostViewChildFrame* rwhv, |
| 23 TouchSelectionControllerClientManager* manager) |
| 24 : rwhv_(rwhv), manager_(manager) { |
| 25 DCHECK(rwhv); |
| 26 DCHECK(manager_); |
| 27 } |
| 28 |
| 29 TouchSelectionControllerClientChildFrame:: |
| 30 ~TouchSelectionControllerClientChildFrame() { |
| 31 // TODO(wjmaclean): This assumes the manager_ is guaranteed to outlive us, |
| 32 // verify this is true. |
| 33 manager_->InvalidateClient(this); |
| 34 } |
| 35 |
| 36 void TouchSelectionControllerClientChildFrame::UpdateSelectionBoundsIfNeeded( |
| 37 const cc::Selection<gfx::SelectionBound>& selection, |
| 38 float device_scale_factor) { |
| 39 gfx::PointF start_edge_top = selection.start.edge_top(); |
| 40 gfx::PointF start_edge_bottom = selection.start.edge_bottom(); |
| 41 gfx::PointF end_edge_top = selection.end.edge_top(); |
| 42 gfx::PointF end_edge_bottom = selection.end.edge_bottom(); |
| 43 |
| 44 if (IsUseZoomForDSFEnabled()) { |
| 45 float viewportToDIPScale = 1.0f / device_scale_factor; |
| 46 |
| 47 start_edge_top.Scale(viewportToDIPScale); |
| 48 start_edge_bottom.Scale(viewportToDIPScale); |
| 49 end_edge_top.Scale(viewportToDIPScale); |
| 50 end_edge_bottom.Scale(viewportToDIPScale); |
| 51 } |
| 52 |
| 53 gfx::Point origin = rwhv_->GetViewOriginInRoot(); |
| 54 gfx::Vector2dF offset_v(origin.x(), origin.y()); |
| 55 start_edge_top += offset_v; |
| 56 start_edge_bottom += offset_v; |
| 57 end_edge_top += offset_v; |
| 58 end_edge_bottom += offset_v; |
| 59 |
| 60 cc::Selection<gfx::SelectionBound> transformed_selection(selection); |
| 61 transformed_selection.start.SetEdge(start_edge_top, start_edge_bottom); |
| 62 transformed_selection.end.SetEdge(end_edge_top, end_edge_bottom); |
| 63 |
| 64 if (transformed_selection.start != selection_start_ || |
| 65 transformed_selection.end != selection_end_) { |
| 66 selection_start_ = transformed_selection.start; |
| 67 selection_end_ = transformed_selection.end; |
| 68 manager_->UpdateClientSelectionBounds(selection_start_, selection_end_, |
| 69 this, this); |
| 70 } |
| 71 } |
| 72 |
| 73 gfx::Point TouchSelectionControllerClientChildFrame::ConvertFromRoot( |
| 74 const gfx::PointF& point_f) const { |
| 75 gfx::Point origin = rwhv_->GetViewOriginInRoot(); |
| 76 return gfx::ToRoundedPoint( |
| 77 gfx::PointF(point_f.x() - origin.x(), point_f.y() - origin.y())); |
| 78 } |
| 79 |
| 80 bool TouchSelectionControllerClientChildFrame::SupportsAnimation() const { |
| 81 return false; |
| 82 } |
| 83 |
| 84 void TouchSelectionControllerClientChildFrame::SetNeedsAnimate() {} |
| 85 |
| 86 void TouchSelectionControllerClientChildFrame::MoveCaret( |
| 87 const gfx::PointF& position) { |
| 88 RenderWidgetHostImpl* host = |
| 89 RenderWidgetHostImpl::From(rwhv_->GetRenderWidgetHost()); |
| 90 host->MoveCaret(ConvertFromRoot(position)); |
| 91 } |
| 92 |
| 93 void TouchSelectionControllerClientChildFrame::MoveRangeSelectionExtent( |
| 94 const gfx::PointF& extent) { |
| 95 RenderWidgetHostDelegate* host_delegate = |
| 96 RenderWidgetHostImpl::From(rwhv_->GetRenderWidgetHost())->delegate(); |
| 97 if (host_delegate) |
| 98 host_delegate->MoveRangeSelectionExtent(ConvertFromRoot(extent)); |
| 99 } |
| 100 |
| 101 void TouchSelectionControllerClientChildFrame::SelectBetweenCoordinates( |
| 102 const gfx::PointF& base, |
| 103 const gfx::PointF& extent) { |
| 104 RenderWidgetHostDelegate* host_delegate = |
| 105 RenderWidgetHostImpl::From(rwhv_->GetRenderWidgetHost())->delegate(); |
| 106 if (host_delegate) { |
| 107 host_delegate->SelectRange(ConvertFromRoot(base), ConvertFromRoot(extent)); |
| 108 } |
| 109 } |
| 110 |
| 111 void TouchSelectionControllerClientChildFrame::OnSelectionEvent( |
| 112 ui::SelectionEventType event) { |
| 113 NOTREACHED(); |
| 114 } |
| 115 |
| 116 std::unique_ptr<ui::TouchHandleDrawable> |
| 117 TouchSelectionControllerClientChildFrame::CreateDrawable() { |
| 118 NOTREACHED(); |
| 119 return std::unique_ptr<ui::TouchHandleDrawable>(); |
| 120 } |
| 121 |
| 122 bool TouchSelectionControllerClientChildFrame::IsCommandIdEnabled( |
| 123 int command_id) const { |
| 124 bool editable = rwhv_->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE; |
| 125 bool readable = rwhv_->GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD; |
| 126 // TODO(wjmaclean): The test for has_selection should be changed to |
| 127 // |
| 128 // rwhv_->GetSelectionRange(&selection_range); |
| 129 // bool has_selection = !selection_range.is_empty(); |
| 130 // |
| 131 // like in TouchSelectionControllerClientAura. Unfortunately this fails here |
| 132 // due to https://crbug.com/723790, which means that the first text |
| 133 // selected in an oopif subframe when it acquires focus will fail to send |
| 134 // a FrameHostMsg_SelectionChanged, meaning the TextInputManager won't |
| 135 // know about the new selection. |
| 136 bool has_selection = selection_start_.type() != gfx::SelectionBound::EMPTY && |
| 137 selection_end_.type() != gfx::SelectionBound::EMPTY && |
| 138 selection_start_ != selection_end_; |
| 139 switch (command_id) { |
| 140 case IDS_APP_CUT: |
| 141 return editable && readable && has_selection; |
| 142 case IDS_APP_COPY: |
| 143 return readable && has_selection; |
| 144 case IDS_APP_PASTE: { |
| 145 base::string16 result; |
| 146 ui::Clipboard::GetForCurrentThread()->ReadText( |
| 147 ui::CLIPBOARD_TYPE_COPY_PASTE, &result); |
| 148 return editable && !result.empty(); |
| 149 } |
| 150 default: |
| 151 return false; |
| 152 } |
| 153 } |
| 154 |
| 155 void TouchSelectionControllerClientChildFrame::ExecuteCommand(int command_id, |
| 156 int event_flags) { |
| 157 manager_->GetTouchSelectionController() |
| 158 ->HideAndDisallowShowingAutomatically(); |
| 159 RenderWidgetHostDelegate* host_delegate = |
| 160 RenderWidgetHostImpl::From(rwhv_->GetRenderWidgetHost())->delegate(); |
| 161 if (!host_delegate) |
| 162 return; |
| 163 |
| 164 switch (command_id) { |
| 165 case IDS_APP_CUT: |
| 166 host_delegate->Cut(); |
| 167 break; |
| 168 case IDS_APP_COPY: |
| 169 host_delegate->Copy(); |
| 170 break; |
| 171 case IDS_APP_PASTE: |
| 172 host_delegate->Paste(); |
| 173 break; |
| 174 default: |
| 175 NOTREACHED(); |
| 176 break; |
| 177 } |
| 178 } |
| 179 |
| 180 void TouchSelectionControllerClientChildFrame::RunContextMenu() { |
| 181 gfx::RectF anchor_rect = |
| 182 manager_->GetTouchSelectionController()->GetRectBetweenBounds(); |
| 183 gfx::PointF anchor_point = |
| 184 gfx::PointF(anchor_rect.CenterPoint().x(), anchor_rect.y()); |
| 185 gfx::Point origin = rwhv_->GetViewOriginInRoot(); |
| 186 anchor_point.Offset(-origin.x(), -origin.y()); |
| 187 RenderWidgetHostImpl* host = |
| 188 RenderWidgetHostImpl::From(rwhv_->GetRenderWidgetHost()); |
| 189 // TODO(wjmaclean): Probably this ViewMsg should be converted to a FrameMsg |
| 190 // since it will need to go to a RenderFrame once the Blink-side plumbing for |
| 191 // this is hooked up. |
| 192 host->Send(new ViewMsg_ShowContextMenu(host->GetRoutingID(), |
| 193 ui::MENU_SOURCE_TOUCH_EDIT_MENU, |
| 194 gfx::ToRoundedPoint(anchor_point))); |
| 195 |
| 196 // Hide selection handles after getting rect-between-bounds from touch |
| 197 // selection controller; otherwise, rect would be empty and the above |
| 198 // calculations would be invalid. |
| 199 manager_->GetTouchSelectionController() |
| 200 ->HideAndDisallowShowingAutomatically(); |
| 201 } |
| 202 |
| 203 } // namespace content |
OLD | NEW |