Add Tizen-platform implementation of the selection feature.
authorSeungSeop Park <sns.park@samsung.com>
Thu, 29 May 2014 15:12:47 +0000 (11:12 -0400)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Tue, 10 Jul 2018 06:57:09 +0000 (06:57 +0000)
Change-Id: I33d061481bf7054ade6b4a930cd1a68225d1f56f

13 files changed:
tizen_src/impl/chromium-efl.gyp
tizen_src/impl/resource/Magnifier.edc [new file with mode: 0644]
tizen_src/impl/resource/images/magnifier_left.png [new file with mode: 0644]
tizen_src/impl/resource/images/magnifier_middle.png [new file with mode: 0644]
tizen_src/impl/resource/images/magnifier_right.png [new file with mode: 0644]
tizen_src/impl/selection_box_efl.cc [new file with mode: 0644]
tizen_src/impl/selection_box_efl.h [new file with mode: 0644]
tizen_src/impl/selection_controller_efl.cc [new file with mode: 0644]
tizen_src/impl/selection_controller_efl.h [new file with mode: 0644]
tizen_src/impl/selection_handle_efl.cc [new file with mode: 0644]
tizen_src/impl/selection_handle_efl.h [new file with mode: 0644]
tizen_src/impl/selection_magnifier_efl.cc [new file with mode: 0644]
tizen_src/impl/selection_magnifier_efl.h [new file with mode: 0644]

index ff7c396f6396af7d49f7b65846a23e4fe97d2eee..28aea20f54ecd578edaa3b6fbbe63fc3346fa406 100644 (file)
       'renderer/render_view_observer_efl.cc',
       'renderer/render_view_observer_efl.h',
       'resource/JavaScriptPopup.edc',
+      'resource/Magnifier.edc',
       'screen_efl.cc',
       'screen_efl.h',
+      'selection_box_efl.cc',
+      'selection_box_efl.h',
+      'selection_controller_efl.cc',
+      'selection_controller_efl.h',
+      'selection_handle_efl.cc',
+      'selection_handle_efl.h',
+      'selection_magnifier_efl.cc',
+      'selection_magnifier_efl.h',
       'url_request_context_getter_efl.cc',
       'url_request_context_getter_efl.h',
       'web_contents_delegate_efl.cc',
diff --git a/tizen_src/impl/resource/Magnifier.edc b/tizen_src/impl/resource/Magnifier.edc
new file mode 100644 (file)
index 0000000..f7f1adb
--- /dev/null
@@ -0,0 +1,102 @@
+collections {
+group {
+        name: "magnifier";
+        images {
+            image: "magnifier_left.png" COMP;
+            image: "magnifier_middle.png" COMP;
+            image: "magnifier_right.png" COMP;
+        }
+        parts {
+            part {
+                name: "bg";
+                mouse_events: 0;
+                scale: 1;
+                type: RECT;
+                description {
+                    state: "default" 0.0;
+                    fixed: 1 1;
+                    min: 332 177;
+                    align: 0.5 0.0;
+                    visible: 1;
+                    color: 0 0 0 0;
+                }
+            }
+            part {
+                name: "bg_left";
+                mouse_events: 0;
+                scale: 1;
+                description {
+                    state: "default" 0.0;
+                    fixed: 1 1;
+                    min: 146 177;
+                    align: 0.0 0.0;
+                    rel1 { relative: 0.0 0.0; to: "bg"; }
+                    rel2 { relative: 0.0 1.0; to: "bg"; }
+                    image {
+                        normal: "magnifier_left.png";
+                        border: 21 1 20 44;
+                    }
+                    image.middle: 1;
+                    fill.smooth: 0;
+                }
+            }
+            part {
+                name: "bg_middle";
+                mouse_events: 0;
+                scale: 1;
+                description {
+                    state: "default" 0.0;
+                    fixed: 1 1;
+                    min: 40 177;
+                    max: 40 999999;
+                    align: 0.0 0.0;
+                    rel1 { relative: 1.0 0.0; to: "bg_left"; }
+                    rel2 { relative: 1.0 1.0; to: "bg"; }
+                    image {
+                        normal: "magnifier_middle.png";
+                        border: 0 0 20 44;
+                    }
+                    image.middle: 1;
+                    fill.smooth: 0;
+                }
+            }
+            part {
+                name: "bg_right";
+                mouse_events: 0;
+                scale: 1;
+                description {
+                    state: "default" 0.0;
+                    fixed: 1 1;
+                    min: 146 177;
+                    rel1 { relative: 1.0 0.0; to: "bg_middle";}
+                    rel2.to: "bg";
+                    image {
+                        normal: "magnifier_right.png";
+                        border: 1 21 20 44;
+                    }
+                    image.middle: 1;
+                    fill.smooth: 0;
+                }
+            }
+            part {
+                name: "swallow";
+                type: SWALLOW;
+                mouse_events: 0;
+                scale: 1;
+                description {
+                    state: "default" 0.0;
+                    fixed: 1 1;
+                    align: 0.0 0.0;
+                    rel1 {
+                        to: "bg";
+                        offset: 21-5 22-8; //need to update when image with rounded corners releases
+                    }
+                    rel2 {
+                        to: "bg";
+                        offset: -21+5 -44+10;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tizen_src/impl/resource/images/magnifier_left.png b/tizen_src/impl/resource/images/magnifier_left.png
new file mode 100644 (file)
index 0000000..307c1dc
Binary files /dev/null and b/tizen_src/impl/resource/images/magnifier_left.png differ
diff --git a/tizen_src/impl/resource/images/magnifier_middle.png b/tizen_src/impl/resource/images/magnifier_middle.png
new file mode 100644 (file)
index 0000000..38bee91
Binary files /dev/null and b/tizen_src/impl/resource/images/magnifier_middle.png differ
diff --git a/tizen_src/impl/resource/images/magnifier_right.png b/tizen_src/impl/resource/images/magnifier_right.png
new file mode 100644 (file)
index 0000000..4467cd6
Binary files /dev/null and b/tizen_src/impl/resource/images/magnifier_right.png differ
diff --git a/tizen_src/impl/selection_box_efl.cc b/tizen_src/impl/selection_box_efl.cc
new file mode 100644 (file)
index 0000000..cf165d6
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "eweb_view.h"
+#include "selection_box_efl.h"
+
+namespace content {
+
+SelectionBoxEfl::SelectionBoxEfl(EWebView* parent_view)
+  : status_(false),
+    editable_(false),
+    is_anchor_first_(true),
+    context_params_(new ContextMenuParams()),
+    parent_view_(parent_view) {
+}
+
+void SelectionBoxEfl::UpdateHandleData() {
+  // Swap the handlers when these handles cross over
+  if (!is_anchor_first_) {
+    gfx::Rect swap_rect_;
+    swap_rect_ = left_rect_;
+    left_rect_ = right_rect_;
+    right_rect_ = swap_rect_;
+  }
+}
+
+void SelectionBoxEfl::UpdateSelectStringData(const base::string16& text) {
+  context_params_->selection_text = text;
+}
+
+void SelectionBoxEfl::UpdateRectData(const gfx::Rect& left_rect, const gfx::Rect& right_rect, bool is_anchor_first) {
+  is_anchor_first_ = is_anchor_first;
+  left_rect_ = left_rect;
+  right_rect_ = right_rect;
+
+  // Display point of context Menu
+  Evas_Coord x, y;
+  evas_object_geometry_get(parent_view_->evas_object(), &x, &y, 0, 0);
+  //context params suppose to be global - related to evas not the web view
+  context_params_->x = left_rect_.x() + x;
+  context_params_->y = left_rect_.y() + y;
+}
+
+bool SelectionBoxEfl::IsInEditField() const {
+  return (editable_ && !(left_rect_.width() && !(left_rect_.height())));
+}
+
+}
diff --git a/tizen_src/impl/selection_box_efl.h b/tizen_src/impl/selection_box_efl.h
new file mode 100644 (file)
index 0000000..f1065ec
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef selection_box_efl_h
+#define selection_box_efl_h
+
+#include "base/memory/scoped_ptr.h"
+#include "content/public/common/context_menu_params.h"
+#include "content/public/common/menu_item.h"
+#include "ui/gfx/range/range.h"
+#include "ui/gfx/rect.h"
+
+class EWebView;
+
+namespace content {
+
+// Hold the data related to drwaing the selection handlers
+// and context menu. Also stores all the data required for selection
+// controlling
+class SelectionBoxEfl {
+ public:
+  SelectionBoxEfl(EWebView* parent_view);
+
+  void SetStatus(bool enable) { status_ = enable; }
+  bool GetStatus() const { return status_; }
+  void SetEditable(bool enable) { editable_ = enable; }
+  bool GetEditable() const { return editable_; }
+  void UpdateHandleData();
+  void UpdateSelectStringData(const base::string16& text);
+  void UpdateRectData(const gfx::Rect& left_rect, const gfx::Rect& right_rect, bool is_anchor_first);
+  bool IsInEditField() const;
+  gfx::Rect GetLeftRect() const { return left_rect_; }
+  gfx::Rect GetRightRect() const { return right_rect_; }
+  ContextMenuParams* GetContextMenuParams() const { return context_params_.get(); }
+
+ private:
+  // Save the state of selection, if active or not
+  bool status_;
+
+  // Save if the selection is in one of the editable fields
+  bool editable_;
+
+  // Is set if handlers crossover rects are interchanged
+  bool is_anchor_first_;
+
+  // Start of selection
+  gfx::Rect left_rect_;
+
+  // End of selection
+  gfx::Rect right_rect_;
+
+  // Contains the menu item data for which context needs to be populated
+  scoped_ptr<ContextMenuParams> context_params_;
+
+  EWebView* parent_view_;
+};
+
+}
+#endif
diff --git a/tizen_src/impl/selection_controller_efl.cc b/tizen_src/impl/selection_controller_efl.cc
new file mode 100644 (file)
index 0000000..a0a63dc
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "eweb_view.h"
+#include "selection_controller_efl.h"
+#include "selection_handle_efl.h"
+#include "selection_box_efl.h"
+#include "selection_magnifier_efl.h"
+
+namespace content {
+
+static bool IsRectEmpty(const gfx::Rect& rect) {
+  return (rect.x() == 0 && rect.y() == 0 && rect.height() == 0 && rect.width() == 0);
+}
+
+SelectionControllerEfl::SelectionControllerEfl(EWebView* parent_view)
+    :  parent_view_(parent_view),
+       mouse_press_(false),
+       long_mouse_press_(false),
+       selection_data_(new SelectionBoxEfl(parent_view)),
+       start_handle_(new SelectionHandleEfl(this, SelectionHandleEfl::HANDLE_TYPE_LEFT, parent_view->evas_object())),
+       end_handle_(new SelectionHandleEfl(this, SelectionHandleEfl::HANDLE_TYPE_RIGHT, parent_view->evas_object())),
+       input_handle_(new SelectionHandleEfl(this, SelectionHandleEfl::HANDLE_TYPE_INPUT, parent_view->evas_object())),
+       magnifier_(new SelectionMagnifierEfl(this)) {
+  evas_object_event_callback_add(parent_view_->evas_object(), EVAS_CALLBACK_MOVE, &EvasParentViewMoveCallback, this);
+}
+
+void SelectionControllerEfl::SetSelectionStatus(bool enable) {
+  selection_data_->SetStatus(enable);
+}
+
+bool SelectionControllerEfl::GetSelectionStatus() const {
+  return selection_data_->GetStatus();
+}
+
+void SelectionControllerEfl::SetSelectionEditable(bool enable) {
+  selection_data_->SetEditable(enable);
+}
+
+bool SelectionControllerEfl::GetSelectionEditable() const {
+  return selection_data_->GetEditable();
+}
+
+void SelectionControllerEfl::UpdateSelectionData(const base::string16& text) {
+  selection_data_->UpdateSelectStringData(text);
+}
+
+void SelectionControllerEfl::UpdateMagnifierScreen(const SkBitmap& display_image) {
+  magnifier_->UpdateScreen(display_image);
+}
+
+void SelectionControllerEfl::UpdateSelectionDataAndShow(const gfx::Rect& left_rect, const gfx::Rect& right_rect, bool is_anchor_first) {
+  if (!IsSelectionValid(left_rect, right_rect)) {
+    Clear();
+    return;
+  }
+
+  selection_data_->UpdateRectData(left_rect, right_rect, is_anchor_first);
+  // Do not show the context menu and handlers untill long mouse press is released
+  if (long_mouse_press_)
+    return;
+
+  ShowHandleAndContextMenuIfRequired();
+}
+
+void SelectionControllerEfl::ShowHandleAndContextMenuIfRequired() {
+  if (!selection_data_->GetStatus())
+    return;
+
+  // Is in edit field and no text is selected. show only single handle
+  if (selection_data_->IsInEditField()) {
+    gfx::Rect left = selection_data_->GetLeftRect();
+    input_handle_->SetBasePosition(gfx::Point(left.x(), left.y()));
+    input_handle_->Move(gfx::Point(left.x(), left.y() + left.height()));
+    input_handle_->SetCursorHandlerStatus(true);
+
+    // Do not show the context menu during selection extend
+    if (!mouse_press_)
+      parent_view_->ShowContextMenu(*(selection_data_->GetContextMenuParams()), MENU_TYPE_SELECTION);
+    return;
+  }
+
+  // FIXME : Check the text Direction later
+  gfx::Rect left = selection_data_->GetLeftRect();
+  start_handle_->SetBasePosition(gfx::Point(left.x(), left.y()));
+  start_handle_->Move(gfx::Point(left.x(), left.y() + left.height()));
+  start_handle_->Show();
+
+  gfx::Rect right = selection_data_->GetRightRect();
+
+  end_handle_->SetBasePosition(gfx::Point(right.x(), right.y()));
+  end_handle_->Move(gfx::Point(right.x() + right.width(), right.y() + right.height()));
+  end_handle_->Show();
+
+  // Do not show the context menu during selection extend
+  if (!mouse_press_)
+    parent_view_->ShowContextMenu(*(selection_data_->GetContextMenuParams()), MENU_TYPE_SELECTION);
+  parent_view_->QuerySelectionStyle();
+}
+
+void SelectionControllerEfl::Clear() {
+  start_handle_->Hide();
+  end_handle_->Hide();
+  input_handle_->Hide();
+}
+
+void SelectionControllerEfl::OnMouseDown(const gfx::Point& touch_point) {
+  // Hide context menu on mouse down
+  parent_view_->CancelContextMenu(0);
+  mouse_press_ = true;
+  magnifier_->UpdateLocation(touch_point);
+  magnifier_->Move(touch_point);
+  magnifier_->Show();
+}
+
+void SelectionControllerEfl::OnMouseMove(const gfx::Point& touch_point, bool on_curson_handle) {
+  // FIXME : Check the text Direction later
+  magnifier_->UpdateLocation(touch_point);
+  magnifier_->Move(touch_point);
+  if (!on_curson_handle)
+    parent_view_->SelectRange(start_handle_->GetBasePosition(), end_handle_->GetBasePosition());
+  else
+    parent_view_->MoveCaret(input_handle_->GetBasePosition());
+}
+
+void SelectionControllerEfl::OnMouseUp(const gfx::Point& touch_point) {
+  selection_data_->UpdateHandleData();
+  mouse_press_ = false;
+  magnifier_->Hide();
+  ShowHandleAndContextMenuIfRequired();
+}
+
+void SelectionControllerEfl::GetSelectionBounds(gfx::Rect* left, gfx::Rect* right) {
+  if (left)
+    *left = selection_data_->GetLeftRect();
+  if (right)
+    *right = selection_data_->GetRightRect();
+}
+
+void SelectionControllerEfl::HandleLongPressEvent(const gfx::Point& touch_point) {
+  long_mouse_press_ = true;
+  magnifier_->HandleLongPress(touch_point);
+}
+
+void SelectionControllerEfl::HandleLongPressMoveEvent(const gfx::Point& touch_point) {
+  parent_view_->SelectClosestWord(touch_point);
+}
+
+void SelectionControllerEfl::HandleLongPressEndEvent() {
+  long_mouse_press_ = false;
+  ShowHandleAndContextMenuIfRequired();
+}
+
+bool SelectionControllerEfl::IsSelectionValid(const gfx::Rect& left_rect, const gfx::Rect& right_rect) {
+  // For all normal cases the widht will be 0 and we want to check empty which Implies
+  // x, y, h w all to be 0
+  if ((IsRectEmpty(left_rect) || IsRectEmpty(right_rect))) {
+    SetSelectionStatus(false);
+    return false;
+  }
+
+  // The most of sites return width of each rects as 0 when text is selected.
+  // However, some websites that have viewport attributes on meta tag v
+  // return width 0 right after they are loaded, even though text is not selected.
+  // Thus the width is not sufficient for checking selection condition.
+  // Further invesitigation showed left_rect and right_rect always have the same x,y values
+  // for such cases. So, the equality for x and y rather than width should be tested.
+  if (left_rect.x()==right_rect.x() && left_rect.y()==right_rect.y() &&
+      !selection_data_->IsInEditField() && !mouse_press_) {
+    SetSelectionStatus(false);
+    return false;
+  }
+
+  if (!GetSelectionStatus())
+    SetSelectionStatus(true);
+  return true;
+}
+
+void SelectionControllerEfl::ClearSelection() {
+  Clear();
+  parent_view_->CancelContextMenu(0);
+  selection_data_->SetStatus(false);
+}
+
+void SelectionControllerEfl::OnParentParentViewMove() {
+  parent_view_->CancelContextMenu(0);
+  start_handle_->Move(start_handle_->GetBasePosition());
+  end_handle_->Move(end_handle_->GetBasePosition());
+}
+
+}
diff --git a/tizen_src/impl/selection_controller_efl.h b/tizen_src/impl/selection_controller_efl.h
new file mode 100644 (file)
index 0000000..3d6e417
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef selection_controller_h
+#define selection_controller_h
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "ui/gfx/range/range.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/rect.h"
+#include "selection_handle_efl.h"
+#include "selection_box_efl.h"
+#include "selection_magnifier_efl.h"
+
+class EWebView;
+
+namespace content {
+
+// Controls the selection after long tap.
+// This handles long tap down, long tap move, long tap up.
+// On long tap down touch point is sent to engine by SendGestureEvent and magnifier is shown.
+// On long tap move touch events are sent to engine by SelectClosestWord and magnifier is shown.
+// On long tap up selection handlers are shown and context menu event is sent.
+// Hnadlers are shown to extent selection, On handler move touch points are sent to engine
+// by SelectRange to extend the selection
+class SelectionControllerEfl {
+ public:
+  explicit SelectionControllerEfl(EWebView* parent_view);
+
+  // Functions that handle long press, long press move and release
+  void HandleLongPressEvent(const gfx::Point& touch_point);
+  void HandleLongPressMoveEvent(const gfx::Point& touch_point);
+  void HandleLongPressEndEvent();
+  // Set if selection is valid
+  void SetSelectionStatus(bool enable);
+  bool GetSelectionStatus() const;
+  // Set if selection is in edit field
+  void SetSelectionEditable(bool enable);
+  bool GetSelectionEditable() const;
+  // To update the selection string
+  void UpdateSelectionData(const base::string16& text);
+  // To update the bitmap Image to show the magnifier
+  void UpdateMagnifierScreen(const SkBitmap& display_image);
+  // To update the selection bounds
+  void UpdateSelectionDataAndShow(const gfx::Rect& left_rect, const gfx::Rect& right_rect, bool is_anchor_first);
+  void GetSelectionBounds(gfx::Rect *left, gfx::Rect *right);
+  // Handles the mouse press,move and relase events on selection handles
+  void OnMouseDown(const gfx::Point& touch_point);
+  void OnMouseMove(const gfx::Point& touch_point, bool on_curson_handle);
+  void OnMouseUp(const gfx::Point& touch_point);
+
+  // Clears the selection and hides context menu and handles
+  void ClearSelection();
+  EWebView* GetParentView() { return parent_view_; }
+
+ private:
+  void ShowHandleAndContextMenuIfRequired();
+  void Clear();
+  bool IsSelectionValid(const gfx::Rect& left_rect, const gfx::Rect& right_rect);
+
+  static void EvasParentViewMoveCallback(void *data, Evas *e, Evas_Object *obj, void *event_info)
+  { reinterpret_cast<SelectionControllerEfl*>(data)->OnParentParentViewMove(); }
+
+  void OnParentParentViewMove();
+
+  // Is required to send back selction points and range extenstion co-ordinates
+  EWebView* parent_view_;
+
+  // Saves state so that context menu is not displyed during extending selection
+  bool mouse_press_;
+
+  // Saves state so that handlers and context menu is not shown when seletion change event occurs.
+  bool long_mouse_press_;
+
+  // Saves the data that are required to draw handle and context menu
+  scoped_ptr<SelectionBoxEfl> selection_data_;
+
+  // Points to start of the selection for extending selection
+  scoped_ptr<SelectionHandleEfl> start_handle_;
+
+  // Points to the end of the selection for extending selection
+  scoped_ptr<SelectionHandleEfl> end_handle_;
+
+  // Points to the caret in edit box where cursor is present
+  scoped_ptr<SelectionHandleEfl> input_handle_;
+
+  // Points to show the contents magnified
+  scoped_ptr<SelectionMagnifierEfl> magnifier_;
+};
+
+}
+#endif
diff --git a/tizen_src/impl/selection_handle_efl.cc b/tizen_src/impl/selection_handle_efl.cc
new file mode 100644 (file)
index 0000000..3e301c3
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "eweb_view.h"
+#include "selection_handle_efl.h"
+#include "selection_controller_efl.h"
+
+#include <Edje.h>
+#include <Eina.h>
+#include <Elementary.h>
+
+namespace content {
+
+const char* kLeftHandlePath = "elm/entry/selection/block_handle_left";
+const char* kRightHandlePath = "elm/entry/selection/block_handle_right";
+const char* kInputHandlePath = "elm/entry/cursor_handle/default";
+
+static const char* GetEdjeObjectGroupPath(SelectionHandleEfl::HandleType type) {
+  switch (type) {
+    case SelectionHandleEfl::HANDLE_TYPE_LEFT:
+      return kLeftHandlePath;
+    case SelectionHandleEfl::HANDLE_TYPE_RIGHT:
+      return kRightHandlePath;
+    case SelectionHandleEfl::HANDLE_TYPE_INPUT:
+      return kInputHandlePath;
+    default:
+      return NULL;
+  }
+}
+
+SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl* controller, HandleType type, Evas_Object* parent)
+  : base_point_(0,0),
+    current_touch_point_(0,0),
+    controller_(controller),
+    is_cursor_handle_(false) {
+  Evas* evas = evas_object_evas_get(parent);
+  handle_ = edje_object_add(evas);
+
+  const Eina_List* default_theme_list = elm_theme_list_get(0);
+  const Eina_List* ittr;
+  void* theme;
+  EINA_LIST_FOREACH(default_theme_list, ittr, theme) {
+    char* theme_path = elm_theme_list_item_path_get(static_cast<const char*>(theme), 0);
+    if (theme_path) {
+      edje_object_file_set(handle_, theme_path, GetEdjeObjectGroupPath(type));
+      free(theme_path);
+      break;
+    }
+  }
+
+  edje_object_signal_emit(handle_, "edje,focus,in", "edje");
+  edje_object_signal_emit(handle_, "elm,state,bottom", "elm");
+  evas_object_smart_member_add(handle_, parent);
+  evas_object_propagate_events_set(handle_, false);
+
+  evas_object_event_callback_add(handle_, EVAS_CALLBACK_MOUSE_DOWN, OnMouseDown, this);
+  evas_object_event_callback_add(handle_, EVAS_CALLBACK_MOUSE_UP, OnMouseUp, this);
+}
+
+SelectionHandleEfl::~SelectionHandleEfl() {
+  evas_object_event_callback_del(handle_, EVAS_CALLBACK_MOUSE_DOWN, OnMouseDown);
+  evas_object_event_callback_del(handle_, EVAS_CALLBACK_MOUSE_UP, OnMouseUp);
+  evas_object_del(handle_);
+}
+
+void SelectionHandleEfl::Show() {
+  // FIXME: Currently no viewport boudry checks present. Add later
+  evas_object_show(handle_);
+}
+
+void SelectionHandleEfl::Hide() {
+  evas_object_hide(handle_);
+}
+
+void SelectionHandleEfl::Move(const gfx::Point& point) {
+  // FIXME: Currently no viewport boudry checks present. Add later
+  // Also to check the handle direction based on the viewport
+  Evas_Coord x, y, width, height;
+  evas_object_geometry_get(controller_->GetParentView()->evas_object(), &x, &y, &width, &height);
+  evas_object_move(handle_, point.x() + x, point.y() + y);
+}
+
+void SelectionHandleEfl::OnMouseDown(void* data, Evas*, Evas_Object*, void* event_info) {
+  Evas_Event_Mouse_Down* event = static_cast<Evas_Event_Mouse_Down*>(event_info);
+  SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
+  evas_object_event_callback_add(handle->handle_, EVAS_CALLBACK_MOUSE_MOVE, OnMouseMove, handle);
+
+  Evas_Coord x, y;
+  evas_object_geometry_get(handle->controller_->GetParentView()->evas_object(), &x, &y, 0, 0);
+  handle->controller_->OnMouseDown(gfx::Point(event->canvas.x - x, event->canvas.y - y));
+}
+
+void SelectionHandleEfl::OnMouseMove(void* data, Evas*, Evas_Object*, void* event_info) {
+  Evas_Event_Mouse_Move* event = static_cast<Evas_Event_Mouse_Move*>(event_info);
+  SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
+  handle->current_touch_point_.SetPoint(event->cur.canvas.x, event->cur.canvas.y);
+   ecore_job_add(UpdateMouseMove, handle);
+}
+
+void SelectionHandleEfl::OnMouseUp(void* data, Evas*, Evas_Object*, void* event_info) {
+  Evas_Event_Mouse_Up* event = static_cast<Evas_Event_Mouse_Up*>(event_info);
+  SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
+  evas_object_event_callback_del(handle->handle_, EVAS_CALLBACK_MOUSE_MOVE, OnMouseMove);
+
+  Evas_Coord x, y;
+  evas_object_geometry_get(handle->controller_->GetParentView()->evas_object(), &x, &y, 0, 0);
+  handle->controller_->OnMouseUp(gfx::Point(event->canvas.x - x, event->canvas.y - y));
+}
+
+void SelectionHandleEfl::UpdateMouseMove(void* data) {
+  SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
+  Evas_Coord x, y;
+  evas_object_geometry_get(handle->controller_->GetParentView()->evas_object(), &x, &y, 0, 0);
+  if (!handle->is_cursor_handle_) {
+    int height = 0;
+    int width = 0;
+
+    edje_object_part_geometry_get(handle->handle_, "handle", NULL, NULL, &width, &height);
+
+    // The touch point on the handle will be approx middle of the handle.
+    // So proportionally x and y are calculated and subtracted from the actual touch point
+    // This will be the delta that is diff between old selection point the new one
+
+    int delta_x = handle->current_touch_point_.x() - x - (width/2);
+    int delta_y = handle->current_touch_point_.y() - y - (height/2);
+    handle->base_point_.SetPoint(delta_x, delta_y);
+    handle->controller_->OnMouseMove(gfx::Point(delta_x, delta_y), false);
+  } else {
+    handle->base_point_.set_x(handle->current_touch_point_.x() - x);
+    handle->controller_->OnMouseMove(gfx::Point(handle->current_touch_point_.x() - x, handle->current_touch_point_.y() - y), true);
+  }
+}
+
+}
diff --git a/tizen_src/impl/selection_handle_efl.h b/tizen_src/impl/selection_handle_efl.h
new file mode 100644 (file)
index 0000000..9a50c4d
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef selection_handle_h
+#define selection_handle_h
+
+#include "ui/gfx/point.h"
+
+#include <Evas.h>
+
+namespace content {
+
+class SelectionControllerEfl;
+
+// Controlls the display of handle.
+// Handle marks the start/end of selection. In case of editor used to move the carret
+// Listens on mouse up, down and move events.
+
+class SelectionHandleEfl {
+ public:
+  enum HandleType {
+    HANDLE_TYPE_LEFT,
+    HANDLE_TYPE_RIGHT,
+    HANDLE_TYPE_INPUT
+  };
+
+  SelectionHandleEfl(SelectionControllerEfl* controller, HandleType type, Evas_Object* parent);
+  ~SelectionHandleEfl();
+  void Show();
+  void Hide();
+  void Move(const gfx::Point& point);
+  void SetBasePosition(const gfx::Point& point) { base_point_ = point; }
+  gfx::Point GetBasePosition() const { return base_point_; }
+  void SetCursorHandlerStatus(bool enable) { is_cursor_handle_ = enable; }
+
+ private:
+  static void OnMouseDown(void* data, Evas*, Evas_Object*, void* event_info);
+  static void OnMouseMove(void* data, Evas*, Evas_Object*, void* event_info);
+  static void OnMouseUp(void* data, Evas*, Evas_Object*, void* event_info);
+  static void UpdateMouseMove(void* data);
+
+  // This point is one which will be used during extending selection
+  // it is in web view coordinates
+  gfx::Point base_point_;
+
+  // This captures the handle move points
+  // it is in evas coordinates
+  gfx::Point current_touch_point_;
+
+  // Parent to send back mouse events
+  content::SelectionControllerEfl* controller_;
+
+  // Handler object
+  Evas_Object* handle_;
+
+  // Is set if the handle is of type input
+  bool is_cursor_handle_;
+};
+
+} // namespace
+#endif
diff --git a/tizen_src/impl/selection_magnifier_efl.cc b/tizen_src/impl/selection_magnifier_efl.cc
new file mode 100644 (file)
index 0000000..b0fec35
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include "base/path_service.h"
+#include "base/files/file_path.h"
+#include "eweb_view.h"
+#include "paths_efl.h"
+#include "selection_magnifier_efl.h"
+#include "selection_controller_efl.h"
+
+#include <Elementary.h>
+
+namespace content {
+
+// Inherited from WK2 w.r.t tizen style
+const int kWidthOffset = 32;
+const int kHeightOffset = 60;
+
+SelectionMagnifierEfl::SelectionMagnifierEfl(content::SelectionControllerEfl* controller)
+  : controller_(controller),
+    content_image_(0),
+    animator_(0) {
+  Evas_Object* top_widget = elm_object_top_widget_get(
+      elm_object_parent_widget_get(controller->GetParentView()->evas_object()));
+  if (!top_widget)
+    top_widget = controller->GetParentView()->evas_object();
+
+  base::FilePath edj_dir;
+  base::FilePath magnifier_edj;
+  PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
+  magnifier_edj = edj_dir.Append(FILE_PATH_LITERAL("Magnifier.edj"));
+
+  container_ = elm_layout_add(top_widget);
+  elm_layout_file_set(container_, magnifier_edj.AsUTF8Unsafe().c_str(), "magnifier");
+  int get_height, get_width;
+  edje_object_part_geometry_get(elm_layout_edje_get(container_), "bg", 0, 0, &get_width, &get_height);
+  width_ = get_width - kWidthOffset;
+  height_ = get_height - kHeightOffset;
+}
+
+SelectionMagnifierEfl::~SelectionMagnifierEfl() {
+  if (content_image_) {
+    evas_object_del(content_image_);
+    content_image_ = 0;
+  }
+  if (container_)
+    evas_object_del(container_);
+}
+
+void SelectionMagnifierEfl::HandleLongPress(const gfx::Point& touch_point) {
+  evas_object_event_callback_add(controller_->GetParentView()->evas_object(),
+                                 EVAS_CALLBACK_MOUSE_UP,
+                                 OnAnimatorUp,
+                                 this);
+  UpdateLocation(touch_point);
+  Move(touch_point);
+  Show();
+  animator_ = ecore_animator_add(&SelectionMagnifierEfl::MoveAnimatorCallback, this);
+}
+
+Eina_Bool SelectionMagnifierEfl::MoveAnimatorCallback(void* data) {
+  SelectionMagnifierEfl* magnifier_data = static_cast<SelectionMagnifierEfl*>(data);
+
+  Evas_Coord_Point point;
+  evas_pointer_canvas_xy_get(evas_object_evas_get(magnifier_data->controller_->GetParentView()->evas_object()),
+                             &point.x,
+                             &point.y);
+  gfx::Point display_point(point.x, point.y);
+  magnifier_data->controller_->HandleLongPressMoveEvent(display_point);
+  magnifier_data->UpdateLocation(display_point);
+  magnifier_data->Move(display_point);
+  return ECORE_CALLBACK_RENEW;
+}
+
+void SelectionMagnifierEfl::OnAnimatorUp(void* data, Evas*, Evas_Object*, void*) {
+  SelectionMagnifierEfl* magnifier_data = static_cast<SelectionMagnifierEfl*>(data);
+  if (magnifier_data->animator_) {
+    ecore_animator_del(magnifier_data->animator_);
+    magnifier_data->animator_ = 0;
+  }
+  evas_object_event_callback_del(magnifier_data->controller_->GetParentView()->evas_object(),
+                                 EVAS_CALLBACK_MOUSE_UP,
+                                 OnAnimatorUp);
+  magnifier_data->Hide();
+  magnifier_data->controller_->HandleLongPressEndEvent();
+}
+
+void SelectionMagnifierEfl::UpdateLocation(const gfx::Point& location) {
+  gfx::Rect content_rect(location.x() - width_/2, location.y() - height_/2, width_, height_);
+  int device_x, device_y, device_width, device_height;
+  evas_object_geometry_get(controller_->GetParentView()->evas_object(),
+                           &device_x,
+                           &device_y,
+                           &device_width,
+                           &device_height);
+
+  // Adjustments for boundry conditions
+  if (content_rect.x() < 0)
+    content_rect.set_x(0);
+  else if ((content_rect.x() + width_) > device_width)
+    content_rect.set_x(device_width - width_);
+
+  if (content_rect.y() < 0)
+    content_rect.set_y(0);
+  else if ((content_rect.y() + height_) > device_height)
+    content_rect.set_y(device_height - height_);
+
+  controller_->GetParentView()->GetSnapShotForRect(content_rect);
+}
+
+void SelectionMagnifierEfl::UpdateScreen(const SkBitmap& display_image) {
+  if (content_image_) {
+    evas_object_del(content_image_);
+    content_image_ = 0;
+  }
+
+  Evas* evas = evas_object_evas_get(controller_->GetParentView()->evas_object());
+  content_image_ = evas_object_image_filled_add(evas);
+
+  evas_object_image_colorspace_set(content_image_, EVAS_COLORSPACE_ARGB8888);
+  evas_object_image_size_set(content_image_, width_, height_);
+  evas_object_image_alpha_set(content_image_, EINA_TRUE);
+
+  evas_object_image_data_copy_set(content_image_, display_image.getPixels());
+  evas_object_size_hint_min_set(content_image_, width_, height_);
+  evas_object_resize(content_image_, width_, height_);
+  evas_object_image_filled_set(content_image_, true);
+  evas_object_show(content_image_);
+
+  elm_object_part_content_set(container_, "swallow", content_image_);
+  evas_object_pass_events_set(content_image_, EINA_TRUE);
+  evas_object_clip_set(content_image_, container_);
+
+  evas_object_layer_set(container_, EVAS_LAYER_MAX);
+  evas_object_layer_set(content_image_, EVAS_LAYER_MAX);
+}
+
+// Inherited from WK2 w.r.t tizen style
+const int kMagnifierYOffset = 220;
+
+void SelectionMagnifierEfl::Move(const gfx::Point& location) {
+  gfx::Point magnifier_location(location.x(), location.y() - kMagnifierYOffset);
+  int device_x, device_y, device_width;
+  evas_object_geometry_get(controller_->GetParentView()->evas_object(),
+                           &device_x,
+                           &device_y,
+                           &device_width,
+                           0);
+
+  if ((magnifier_location.x() - (width_/2)) <= device_x)
+    magnifier_location.set_x(width_/2);
+  else if ((magnifier_location.x() + width_/2) > device_width)
+    magnifier_location.set_x(device_width - width_/2);
+
+  // Only top condition is considered as for the bottom part the magnifer
+  // will always be on top of the touch point so no need to consider
+  if (magnifier_location.y() < device_y)
+    magnifier_location.set_y(device_y);
+
+  evas_object_move(container_, magnifier_location.x(), magnifier_location.y());
+}
+
+void SelectionMagnifierEfl::Show() {
+  evas_object_show(container_);
+  controller_->GetParentView()->SmartCallback<EWebViewCallbacks::MagnifierShow>().call();
+}
+
+void SelectionMagnifierEfl::Hide() {
+  evas_object_hide(content_image_);
+  evas_object_hide(container_);
+  controller_->GetParentView()->SmartCallback<EWebViewCallbacks::MagnifierHide>().call();
+}
+
+}
diff --git a/tizen_src/impl/selection_magnifier_efl.h b/tizen_src/impl/selection_magnifier_efl.h
new file mode 100644 (file)
index 0000000..5519699
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#ifndef selection_magnifier_efl_h
+#define selection_magnifier_efl_h
+
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/point.h"
+
+#include <Ecore.h>
+#include <Eina.h>
+#include <Evas.h>
+
+namespace content {
+
+class SelectionControllerEfl;
+
+class SelectionMagnifierEfl {
+ public:
+  SelectionMagnifierEfl(content::SelectionControllerEfl* controller);
+  ~SelectionMagnifierEfl();
+
+  void HandleLongPress(const gfx::Point& touch_point);
+  void UpdateLocation(const gfx::Point& location);
+  void UpdateScreen(const SkBitmap& display_image);
+  void Move(const gfx::Point& location);
+  void Show();
+  void Hide();
+
+ private:
+  static Eina_Bool MoveAnimatorCallback(void* data);
+  static void OnAnimatorUp(void* data, Evas*, Evas_Object*, void*);
+
+  // Parent to send back mouse events
+  content::SelectionControllerEfl* controller_;
+
+  // Magnifier
+  Evas_Object* container_;
+
+  // Image displayed on popup
+  Evas_Object* content_image_;
+
+  // Magnifier Height
+  int height_;
+
+  // Magnifier width
+  int width_;
+
+  // Handle longmove
+  Ecore_Animator* animator_;
+};
+
+}
+
+#endif