1 // Copyright 2013 Samsung Electronics. 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.
5 #include "selection_magnifier_efl.h"
7 #include <Elementary.h>
9 #include "base/files/file_path.h"
10 #include "base/path_service.h"
11 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
12 #include "content/browser/selection/selection_controller_efl.h"
13 #include "content/common/paths_efl.h"
14 #include "content/public/browser/browser_thread.h"
18 // Inherited from WK2 w.r.t tizen style
19 const int kHeightOffset = 60;
20 const float kZoomScale = 0.66;
22 SelectionMagnifierEfl::SelectionMagnifierEfl(
23 content::SelectionControllerEfl* controller)
24 : controller_(controller), content_image_(0), shown_(false) {
25 base::FilePath edj_dir;
26 base::FilePath magnifier_edj;
27 base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
28 magnifier_edj = edj_dir.Append(FILE_PATH_LITERAL("Magnifier.edj"));
31 elm_layout_add(controller_->rwhva()->offscreen_helper()->content_image());
32 elm_layout_file_set(container_, magnifier_edj.AsUTF8Unsafe().c_str(), "magnifier");
33 edje_object_part_geometry_get(elm_layout_edje_get(container_), "bg", 0, 0, &width_, &height_);
36 SelectionMagnifierEfl::~SelectionMagnifierEfl() {
37 DisconnectCallbacks();
39 evas_object_del(content_image_);
43 evas_object_del(container_);
46 void SelectionMagnifierEfl::HandleLongPress(const gfx::Point& touch_point) {
47 evas_object_event_callback_add(
48 controller_->rwhva()->offscreen_helper()->content_image(),
49 EVAS_CALLBACK_MOUSE_MOVE, OnAnimatorMove, this);
50 evas_object_event_callback_add(
51 controller_->rwhva()->offscreen_helper()->content_image(),
52 EVAS_CALLBACK_MOUSE_UP, OnAnimatorUp, this);
53 // Call OnAnimatorMove here, so that the magnifier widget
54 // gets properly placed. Other calls to it are expected to
55 // happen as a react to finger/mouse movements.
60 void SelectionMagnifierEfl::DisconnectCallbacks() {
61 evas_object_event_callback_del(
62 controller_->rwhva()->offscreen_helper()->content_image(),
63 EVAS_CALLBACK_MOUSE_MOVE, OnAnimatorMove);
64 evas_object_event_callback_del(
65 controller_->rwhva()->offscreen_helper()->content_image(),
66 EVAS_CALLBACK_MOUSE_UP, OnAnimatorUp);
69 void SelectionMagnifierEfl::OnAnimatorMove(void* data, Evas*, Evas_Object*, void*) {
70 SelectionMagnifierEfl* magnifier_data = static_cast<SelectionMagnifierEfl*>(data);
71 DCHECK(magnifier_data);
74 magnifier_data->OnAnimatorMove();
77 void SelectionMagnifierEfl::OnAnimatorMove() {
78 Evas_Coord_Point point;
79 evas_pointer_canvas_xy_get(
81 controller_->rwhva()->offscreen_helper()->content_image()),
83 gfx::Point display_point(point.x, point.y);
84 controller_->HandleLongPressMoveEvent(display_point);
85 UpdateLocation(display_point);
89 void SelectionMagnifierEfl::OnAnimatorUp(void* data, Evas*, Evas_Object*, void*) {
90 SelectionMagnifierEfl* magnifier_data = static_cast<SelectionMagnifierEfl*>(data);
91 DCHECK(magnifier_data);
94 magnifier_data->OnAnimatorUp();
97 void SelectionMagnifierEfl::OnAnimatorUp() {
98 DisconnectCallbacks();
100 controller_->HandleLongPressEndEvent();
103 void SelectionMagnifierEfl::MagnifierGetSnapshotCb(Evas_Object* image,
106 SelectionMagnifierEfl* selection_magnifier =
107 static_cast<SelectionMagnifierEfl*>(user_data);
109 if (selection_magnifier->content_image_) {
110 evas_object_del(selection_magnifier->content_image_);
111 selection_magnifier->content_image_ = 0;
114 selection_magnifier->content_image_ = image;
115 evas_object_show(selection_magnifier->content_image_);
117 elm_object_part_content_set(selection_magnifier->container_,
118 "swallow", selection_magnifier->content_image_);
119 evas_object_pass_events_set(selection_magnifier->content_image_, EINA_TRUE);
120 evas_object_clip_set(selection_magnifier->content_image_,
121 selection_magnifier->container_);
123 evas_object_layer_set(selection_magnifier->container_, EVAS_LAYER_MAX);
124 evas_object_layer_set(selection_magnifier->content_image_, EVAS_LAYER_MAX);
127 void SelectionMagnifierEfl::UpdateLocation(const gfx::Point& location) {
128 int device_x, device_y, device_width, device_height;
129 evas_object_geometry_get(
130 controller_->rwhva()->offscreen_helper()->content_image(), &device_x,
131 &device_y, &device_width, &device_height);
133 int zoomedWidth = width_ * kZoomScale;
134 int zoomedHeight = height_ * kZoomScale;
136 if (zoomedWidth > device_width)
137 zoomedWidth = device_width;
139 if (zoomedHeight > device_height)
140 zoomedHeight = device_height;
142 gfx::Rect content_rect(location.x() - zoomedWidth/2,
143 location.y() - zoomedHeight/2, zoomedWidth, zoomedHeight);
145 // Adjustments for boundry conditions
146 if (content_rect.x() < device_x)
147 content_rect.set_x(device_x);
148 else if ((content_rect.x() + zoomedWidth) > device_x + device_width)
149 content_rect.set_x(device_x + device_width - zoomedWidth);
151 if (content_rect.y() < device_y) // Do not let location to be less then magnifier y value
152 content_rect.set_y(device_y);
153 else if (content_rect.y() > device_y + device_height - zoomedHeight)
154 content_rect.set_y(device_y + device_height - zoomedHeight);
157 rect.x = content_rect.x();
158 rect.y = content_rect.y();
159 rect.w = content_rect.width();
160 rect.h = content_rect.height();
161 #if !defined(USE_AURA)
162 RenderWidgetHostViewEfl* rwhv =
163 static_cast<RenderWidgetHostViewEfl*>(web_contents_.GetRenderWidgetHostView());
165 rwhv->RequestSnapshotAsync(rect, MagnifierGetSnapshotCb, this);
169 void SelectionMagnifierEfl::Move(const gfx::Point& location) {
170 int device_x, device_y, device_width, device_height;
171 evas_object_geometry_get(
172 controller_->rwhva()->offscreen_helper()->content_image(), &device_x,
173 &device_y, &device_width, &device_height);
175 int magnifier_x = location.x();
176 int magnifier_y = location.y() - height_ - kHeightOffset;
178 if (magnifier_y < device_y) // Do not let location to be out of screen
179 magnifier_y = device_y;
180 else if (magnifier_y > device_height + device_y - height_)
181 magnifier_y = device_height + device_y - height_;
183 if (magnifier_x < device_x + width_/2) // Do not let location to be out of screen
184 magnifier_x = device_x + width_/2;
185 else if (magnifier_x > device_width + device_x - width_/2)
186 magnifier_x = device_width + device_x - width_/2;
188 evas_object_move(container_, magnifier_x, magnifier_y);
191 void SelectionMagnifierEfl::Show() {
193 evas_object_show(container_);
194 #if !defined(USE_AURA)
195 RenderWidgetHostViewEfl* rwhv =
196 static_cast<RenderWidgetHostViewEfl*>(web_contents_.GetRenderWidgetHostView());
198 rwhv->set_magnifier(true);
200 if (controller_->rwhva()->offscreen_helper()->ewk_view()) {
201 evas_object_smart_callback_call(
202 controller_->rwhva()->offscreen_helper()->ewk_view(), "magnifier,show",
207 void SelectionMagnifierEfl::Hide() {
209 evas_object_hide(content_image_);
210 evas_object_hide(container_);
211 #if !defined(USE_AURA)
212 RenderWidgetHostViewEfl* rwhv =
213 static_cast<RenderWidgetHostViewEfl*>(web_contents_.GetRenderWidgetHostView());
215 rwhv->set_magnifier(false);
217 if (controller_->rwhva()->offscreen_helper()->ewk_view()) {
218 evas_object_smart_callback_call(
219 controller_->rwhva()->offscreen_helper()->ewk_view(), "magnifier,hide",