Chromium Code Reviews| Index: ash/magnifier/magnification_controller.cc |
| diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc |
| index a649f30d4a4fd5399624340598853f5f58208903..0cbe4131bd6faf16f106c1d67689f677b133098e 100644 |
| --- a/ash/magnifier/magnification_controller.cc |
| +++ b/ash/magnifier/magnification_controller.cc |
| @@ -15,10 +15,13 @@ |
| #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/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" |
| @@ -31,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 { |
| @@ -46,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); |
| @@ -63,7 +71,8 @@ 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(); |
| @@ -144,6 +153,31 @@ class MagnificationControllerImpl : virtual public MagnificationController, |
| virtual void OnScrollEvent(ui::ScrollEvent* event) override; |
| virtual void OnTouchEvent(ui::TouchEvent* event) override; |
| + ui::InputMethod* GetInputMethod(); |
| + |
| + // 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 overrides: |
|
oshima
2014/10/23 18:36:49
// ui::InputMethodObserver:
jennyz
2014/10/23 19:34:56
Done.
|
| + virtual void OnTextInputTypeChanged( |
| + const ui::TextInputClient* client) override {} |
| + virtual void OnFocus() override {} |
| + virtual void OnBlur() override {} |
| + virtual void OnTextInputStateChanged( |
| + const ui::TextInputClient* client) override {} |
| + virtual void OnInputMethodDestroyed( |
| + const ui::InputMethod* input_method) override {} |
| + virtual void OnShowImeIfNeeded() override {} |
| + virtual void OnCaretBoundsChanged(const ui::TextInputClient* client) override; |
| + |
| // Target root window. This must not be NULL. |
| aura::Window* root_window_; |
| @@ -169,6 +203,8 @@ class MagnificationControllerImpl : virtual public MagnificationController, |
| ScrollDirection scroll_direction_; |
| + ui::InputMethod* input_method_; |
|
oshima
2014/10/23 18:36:49
document ownership.
jennyz
2014/10/23 19:34:56
Done.
|
| + |
| DISALLOW_COPY_AND_ASSIGN(MagnificationControllerImpl); |
| }; |
| @@ -181,13 +217,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); |
| @@ -317,55 +357,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( |
| @@ -517,6 +510,12 @@ void MagnificationControllerImpl::SetScrollDirection( |
| void MagnificationControllerImpl::SetEnabled(bool enabled) { |
| Shell* shell = Shell::GetInstance(); |
| if (enabled) { |
| + if (!input_method_) { |
| + input_method_ = GetInputMethod(); |
| + if (input_method_) |
| + input_method_->AddObserver(this); |
| + } |
| + |
| float scale = |
| Shell::GetInstance()->accessibility_delegate()-> |
| GetSavedScreenMagnifierScale(); |
| @@ -536,6 +535,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; |
| } |
| @@ -597,6 +601,91 @@ void MagnificationControllerImpl::OnTouchEvent(ui::TouchEvent* event) { |
| } |
| } |
| +ui::InputMethod* MagnificationControllerImpl::GetInputMethod() { |
| + return root_window_->GetProperty(aura::client::kRootWindowInputMethodKey); |
|
oshima
2014/10/23 18:36:49
optinoal: you may just want to inline this.
jennyz
2014/10/23 19:34:56
Done.
|
| +} |
| + |
| +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: |