Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ash / magnifier / magnification_controller.cc
index dd3b0d8..f43154f 100644 (file)
@@ -8,15 +8,20 @@
 #include "ash/accessibility_delegate.h"
 #include "ash/ash_switches.h"
 #include "ash/display/root_window_transformers.h"
+#include "ash/host/ash_window_tree_host.h"
+#include "ash/host/root_window_transformer.h"
+#include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray_delegate.h"
 #include "base/command_line.h"
 #include "base/synchronization/waitable_event.h"
+#include "ui/aura/client/aura_constants.h"
 #include "ui/aura/client/cursor_client.h"
-#include "ui/aura/root_window_transformer.h"
 #include "ui/aura/window.h"
-#include "ui/aura/window_property.h"
 #include "ui/aura/window_tree_host.h"
+#include "ui/base/ime/input_method.h"
+#include "ui/base/ime/input_method_observer.h"
+#include "ui/base/ime/text_input_client.h"
 #include "ui/compositor/dip_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
@@ -29,6 +34,7 @@
 #include "ui/gfx/rect_conversions.h"
 #include "ui/gfx/screen.h"
 #include "ui/wm/core/compound_event_filter.h"
+#include "ui/wm/core/coordinate_conversion.h"
 
 namespace {
 
@@ -44,6 +50,10 @@ const float kScrollScaleChangeFactor = 0.05f;
 // |kPanningMergin| from the edge, the view-port moves.
 const int kPanningMergin = 100;
 
+// Gives a little panning margin for following caret, so that we will move the
+// view-port before the caret is completely out of sight.
+const int kCaretPanningMargin = 10;
+
 void MoveCursorTo(aura::WindowTreeHost* host, const gfx::Point& root_location) {
   gfx::Point3F host_location_3f(root_location);
   host->GetRootTransform().TransformPoint(&host_location_3f);
@@ -61,37 +71,38 @@ namespace ash {
 class MagnificationControllerImpl : virtual public MagnificationController,
                                     public ui::EventHandler,
                                     public ui::ImplicitAnimationObserver,
-                                    public aura::WindowObserver {
+                                    public aura::WindowObserver,
+                                    public ui::InputMethodObserver {
  public:
   MagnificationControllerImpl();
-  virtual ~MagnificationControllerImpl();
+  ~MagnificationControllerImpl() override;
 
   // MagnificationController overrides:
-  virtual void SetEnabled(bool enabled) OVERRIDE;
-  virtual bool IsEnabled() const OVERRIDE;
-  virtual void SetScale(float scale, bool animate) OVERRIDE;
-  virtual float GetScale() const OVERRIDE { return scale_; }
-  virtual void MoveWindow(int x, int y, bool animate) OVERRIDE;
-  virtual void MoveWindow(const gfx::Point& point, bool animate) OVERRIDE;
-  virtual gfx::Point GetWindowPosition() const OVERRIDE {
+  void SetEnabled(bool enabled) override;
+  bool IsEnabled() const override;
+  void SetScale(float scale, bool animate) override;
+  float GetScale() const override { return scale_; }
+  void MoveWindow(int x, int y, bool animate) override;
+  void MoveWindow(const gfx::Point& point, bool animate) override;
+  gfx::Point GetWindowPosition() const override {
     return gfx::ToFlooredPoint(origin_);
   }
-  virtual void SetScrollDirection(ScrollDirection direction) OVERRIDE;
+  void SetScrollDirection(ScrollDirection direction) override;
 
   // For test
-  virtual gfx::Point GetPointOfInterestForTesting() OVERRIDE {
+  gfx::Point GetPointOfInterestForTesting() override {
     return point_of_interest_;
   }
 
  private:
   // ui::ImplicitAnimationObserver overrides:
-  virtual void OnImplicitAnimationsCompleted() OVERRIDE;
+  void OnImplicitAnimationsCompleted() override;
 
   // aura::WindowObserver overrides:
-  virtual void OnWindowDestroying(aura::Window* root_window) OVERRIDE;
-  virtual void OnWindowBoundsChanged(aura::Window* window,
-                                     const gfx::Rect& old_bounds,
-                                     const gfx::Rect& new_bounds) OVERRIDE;
+  void OnWindowDestroying(aura::Window* root_window) override;
+  void OnWindowBoundsChanged(aura::Window* window,
+                             const gfx::Rect& old_bounds,
+                             const gfx::Rect& new_bounds) override;
 
   // Redraws the magnification window with the given origin position and the
   // given scale. Returns true if the window is changed; otherwise, false.
@@ -138,9 +149,29 @@ class MagnificationControllerImpl : virtual public MagnificationController,
   void ValidateScale(float* scale);
 
   // ui::EventHandler overrides:
-  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
-  virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE;
-  virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
+  void OnMouseEvent(ui::MouseEvent* event) override;
+  void OnScrollEvent(ui::ScrollEvent* event) override;
+  void OnTouchEvent(ui::TouchEvent* event) override;
+
+  // Moves the view port when |point| is located within
+  // |x_panning_margin| and |y_pannin_margin| to the edge of the visible
+  // window region. The view port will be moved so that the |point| will be
+  // moved to the point where it has |x_target_margin| and |y_target_margin|
+  // to the edge of the visible region.
+  void MoveMagnifierWindow(const gfx::Point& point,
+                           int x_panning_margin,
+                           int y_panning_margin,
+                           int x_target_margin,
+                           int y_target_margin);
+
+  // ui::InputMethodObserver:
+  void OnTextInputTypeChanged(const ui::TextInputClient* client) override {}
+  void OnFocus() override {}
+  void OnBlur() override {}
+  void OnTextInputStateChanged(const ui::TextInputClient* client) override {}
+  void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {}
+  void OnShowImeIfNeeded() override {}
+  void OnCaretBoundsChanged(const ui::TextInputClient* client) override;
 
   // Target root window. This must not be NULL.
   aura::Window* root_window_;
@@ -167,6 +198,8 @@ class MagnificationControllerImpl : virtual public MagnificationController,
 
   ScrollDirection scroll_direction_;
 
+  ui::InputMethod* input_method_;  // Not owned.
+
   DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl);
 };
 
@@ -179,13 +212,17 @@ MagnificationControllerImpl::MagnificationControllerImpl()
       is_enabled_(false),
       move_cursor_after_animation_(false),
       scale_(kNonMagnifiedScale),
-      scroll_direction_(SCROLL_NONE) {
+      scroll_direction_(SCROLL_NONE),
+      input_method_(NULL) {
   Shell::GetInstance()->AddPreTargetHandler(this);
   root_window_->AddObserver(this);
   point_of_interest_ = root_window_->bounds().CenterPoint();
 }
 
 MagnificationControllerImpl::~MagnificationControllerImpl() {
+  if (input_method_)
+    input_method_->RemoveObserver(this);
+
   root_window_->RemoveObserver(this);
 
   Shell::GetInstance()->RemovePreTargetHandler(this);
@@ -270,9 +307,10 @@ bool MagnificationControllerImpl::RedrawDIP(const gfx::PointF& position_in_dip,
 
   gfx::Display display =
       Shell::GetScreen()->GetDisplayNearestWindow(root_window_);
-  scoped_ptr<aura::RootWindowTransformer> transformer(
-      internal::CreateRootWindowTransformerForDisplay(root_window_, display));
-  root_window_->GetHost()->SetRootWindowTransformer(transformer.Pass());
+  scoped_ptr<RootWindowTransformer> transformer(
+      CreateRootWindowTransformerForDisplay(root_window_, display));
+  GetRootWindowController(root_window_)->ash_host()->SetRootWindowTransformer(
+      transformer.Pass());
 
   if (animate)
     is_on_animation_ = true;
@@ -314,55 +352,8 @@ void MagnificationControllerImpl::OnMouseMove(const gfx::Point& location) {
   DCHECK(root_window_);
 
   gfx::Point mouse(location);
-
-  int x = origin_.x();
-  int y = origin_.y();
-  bool start_zoom = false;
-
-  const gfx::Rect window_rect = gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
-  const int left = window_rect.x();
-  const int right = window_rect.right();
   int margin = kPanningMergin / scale_;  // No need to consider DPI.
-
-  int x_diff = 0;
-
-  if (mouse.x() < left + margin) {
-    // Panning left.
-    x_diff = mouse.x() - (left + margin);
-    start_zoom = true;
-  } else if (right - margin < mouse.x()) {
-    // Panning right.
-    x_diff = mouse.x() - (right - margin);
-    start_zoom = true;
-  }
-  x = left + x_diff;
-
-  const int top = window_rect.y();
-  const int bottom = window_rect.bottom();
-
-  int y_diff = 0;
-  if (mouse.y() < top + margin) {
-    // Panning up.
-    y_diff = mouse.y() - (top + margin);
-    start_zoom = true;
-  } else if (bottom - margin < mouse.y()) {
-    // Panning down.
-    y_diff = mouse.y() - (bottom - margin);
-    start_zoom = true;
-  }
-  y = top + y_diff;
-
-  if (start_zoom && !is_on_animation_) {
-    // No animation on panning.
-    bool animate = false;
-    bool ret = RedrawDIP(gfx::Point(x, y), scale_, animate);
-
-    if (ret) {
-      // If the magnified region is moved, hides the mouse cursor and moves it.
-      if (x_diff != 0 || y_diff != 0)
-        MoveCursorTo(root_window_->GetHost(), mouse);
-    }
-  }
+  MoveMagnifierWindow(mouse, margin, margin, margin, margin);
 }
 
 void MagnificationControllerImpl::AfterAnimationMoveCursorTo(
@@ -514,6 +505,13 @@ void MagnificationControllerImpl::SetScrollDirection(
 void MagnificationControllerImpl::SetEnabled(bool enabled) {
   Shell* shell = Shell::GetInstance();
   if (enabled) {
+    if (!input_method_) {
+      input_method_ =
+          root_window_->GetProperty(aura::client::kRootWindowInputMethodKey);
+      if (input_method_)
+        input_method_->AddObserver(this);
+    }
+
     float scale =
         Shell::GetInstance()->accessibility_delegate()->
         GetSavedScreenMagnifierScale();
@@ -533,6 +531,11 @@ void MagnificationControllerImpl::SetEnabled(bool enabled) {
     if (!is_enabled_)
       return;
 
+    if (input_method_) {
+      input_method_->RemoveObserver(this);
+      input_method_ = NULL;
+    }
+
     RedrawKeepingMousePosition(kNonMagnifiedScale, true);
     is_enabled_ = enabled;
   }
@@ -594,6 +597,87 @@ void MagnificationControllerImpl::OnTouchEvent(ui::TouchEvent* event) {
   }
 }
 
+void MagnificationControllerImpl::MoveMagnifierWindow(const gfx::Point& point,
+                                                      int x_panning_margin,
+                                                      int y_panning_margin,
+                                                      int x_target_margin,
+                                                      int y_target_margin) {
+  DCHECK(root_window_);
+  int x = origin_.x();
+  int y = origin_.y();
+  bool start_zoom = false;
+
+  const gfx::Rect window_rect = gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
+  const int left = window_rect.x();
+  const int right = window_rect.right();
+
+  int x_diff = 0;
+  if (point.x() < left + x_panning_margin) {
+    // Panning left.
+    x_diff = point.x() - (left + x_target_margin);
+    start_zoom = true;
+  } else if (right - x_panning_margin < point.x()) {
+    // Panning right.
+    x_diff = point.x() - (right - x_target_margin);
+    start_zoom = true;
+  }
+  x = left + x_diff;
+
+  const int top = window_rect.y();
+  const int bottom = window_rect.bottom();
+
+  int y_diff = 0;
+  if (point.y() < top + y_panning_margin) {
+    // Panning up.
+    y_diff = point.y() - (top + y_target_margin);
+    start_zoom = true;
+  } else if (bottom - y_panning_margin < point.y()) {
+    // Panning down.
+    y_diff = point.y() - (bottom - y_target_margin);
+    start_zoom = true;
+  }
+  y = top + y_diff;
+  if (start_zoom && !is_on_animation_) {
+    // No animation on panning.
+    bool animate = false;
+    bool ret = RedrawDIP(gfx::Point(x, y), scale_, animate);
+
+    if (ret) {
+      // If the magnified region is moved, hides the mouse cursor and moves it.
+      if (x_diff != 0 || y_diff != 0)
+        MoveCursorTo(root_window_->GetHost(), point);
+    }
+  }
+}
+
+void MagnificationControllerImpl::OnCaretBoundsChanged(
+    const ui::TextInputClient* client) {
+  // caret bounds in screen coordinates.
+  const gfx::Rect caret_bounds = client->GetCaretBounds();
+  // Note: OnCaretBoundsChanged could be fired OnTextInputTypeChanged during
+  // which the caret position is not set a meaning position, and we do not
+  // need to adjust the view port position based on the bogus caret position.
+  // This is only a transition period, the caret position will be fixed upon
+  // focusing right after.
+  if (caret_bounds.width() == 0 && caret_bounds.height() == 0)
+    return;
+
+  gfx::Point caret_origin = caret_bounds.origin();
+  // caret_origin in |root_window_| coordinates.
+  wm::ConvertPointFromScreen(root_window_, &caret_origin);
+
+  // Visible window_rect in |root_window_| coordinates.
+  const gfx::Rect visible_window_rect =
+      gfx::ToEnclosingRect(GetWindowRectDIP(scale_));
+
+  const int panning_margin = kCaretPanningMargin / scale_;
+  MoveMagnifierWindow(caret_origin,
+                      panning_margin,
+                      panning_margin,
+                      visible_window_rect.width() / 2,
+                      visible_window_rect.height() / 2);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // MagnificationController: