diff options
20 files changed, 557 insertions, 70 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 31e09af..a117bb3 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -21,6 +21,7 @@ #include "ash/launcher/launcher_delegate.h" #include "ash/launcher/launcher_model.h" #include "ash/magnifier/magnification_controller.h" +#include "ash/magnifier/partial_magnification_controller.h" #include "ash/root_window_controller.h" #include "ash/rotator/screen_rotation.h" #include "ash/screen_ash.h" @@ -229,18 +230,25 @@ bool HandleToggleRootWindowFullScreen() { // Magnify the screen bool HandleMagnifyScreen(int delta_index) { - // TODO(yoshiki): Create the class like MagnifierStepScaleController, and - // move the following scale control to it. - float scale = - ash::Shell::GetInstance()->magnification_controller()->GetScale(); - // Calculate rounded logarithm (base kMagnificationFactor) of scale. - int scale_index = - std::floor(std::log(scale) / std::log(kMagnificationFactor) + 0.5); - - int new_scale_index = std::max(0, std::min(8, scale_index + delta_index)); - - ash::Shell::GetInstance()->magnification_controller()-> - SetScale(std::pow(kMagnificationFactor, new_scale_index), true); + if (ash::Shell::GetInstance()->magnification_controller()->IsEnabled()) { + // TODO(yoshiki): Create the class like MagnifierStepScaleController, and + // move the following scale control to it. + float scale = + ash::Shell::GetInstance()->magnification_controller()->GetScale(); + // Calculate rounded logarithm (base kMagnificationFactor) of scale. + int scale_index = + std::floor(std::log(scale) / std::log(kMagnificationFactor) + 0.5); + + int new_scale_index = std::max(0, std::min(8, scale_index + delta_index)); + + ash::Shell::GetInstance()->magnification_controller()-> + SetScale(std::pow(kMagnificationFactor, new_scale_index), true); + } else if (ash::Shell::GetInstance()-> + partial_magnification_controller()->is_enabled()) { + float scale = delta_index > 0 ? kDefaultPartialMagnifiedScale : 1; + ash::Shell::GetInstance()->partial_magnification_controller()-> + SetScale(scale); + } return true; } diff --git a/ash/ash.gyp b/ash/ash.gyp index f7b9b55..f85b4a7 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -102,6 +102,10 @@ 'focus_cycler.h', 'high_contrast/high_contrast_controller.cc', 'high_contrast/high_contrast_controller.h', + 'keyboard_overlay/keyboard_overlay_delegate.cc', + 'keyboard_overlay/keyboard_overlay_delegate.h', + 'keyboard_overlay/keyboard_overlay_view.cc', + 'keyboard_overlay/keyboard_overlay_view.h', 'launcher/app_list_button.cc', 'launcher/app_list_button.h', 'launcher/background_animator.cc', @@ -133,10 +137,8 @@ 'launcher/tabbed_launcher_button.h', 'magnifier/magnification_controller.cc', 'magnifier/magnification_controller.h', - 'keyboard_overlay/keyboard_overlay_delegate.cc', - 'keyboard_overlay/keyboard_overlay_delegate.h', - 'keyboard_overlay/keyboard_overlay_view.cc', - 'keyboard_overlay/keyboard_overlay_view.h', + 'magnifier/partial_magnification_controller.cc', + 'magnifier/partial_magnification_controller.h', 'root_window_controller.cc', 'root_window_controller.h', 'rotator/screen_rotation.cc', diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc index d014cd4..d9c7db9 100644 --- a/ash/magnifier/magnification_controller.cc +++ b/ash/magnifier/magnification_controller.cc @@ -33,7 +33,6 @@ const float kScrollScaleChangeFactor = 0.05f; } // namespace namespace ash { -namespace internal { //////////////////////////////////////////////////////////////////////////////// // MagnificationControllerImpl: @@ -47,6 +46,7 @@ class MagnificationControllerImpl : virtual public MagnificationController, // 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; @@ -443,6 +443,10 @@ void MagnificationControllerImpl::SetEnabled(bool enabled) { } } +bool MagnificationControllerImpl::IsEnabled() const { + return is_enabled_; +} + //////////////////////////////////////////////////////////////////////////////// // MagnificationControllerImpl: aura::EventFilter implementation @@ -506,5 +510,4 @@ MagnificationController* MagnificationController::CreateInstance() { return new MagnificationControllerImpl(); } -} // namespace internal } // namespace ash diff --git a/ash/magnifier/magnification_controller.h b/ash/magnifier/magnification_controller.h index b274b4c..a110b93 100644 --- a/ash/magnifier/magnification_controller.h +++ b/ash/magnifier/magnification_controller.h @@ -16,7 +16,6 @@ class RootWindow; } namespace ash { -namespace internal { class MagnificationController { public: @@ -29,6 +28,8 @@ class MagnificationController { // Enables (or disables if |enabled| is false) screen magnifier feature. virtual void SetEnabled(bool enabled) = 0; + virtual bool IsEnabled() const = 0; + // Sets the magnification ratio. 1.0f means no magnification. virtual void SetScale(float scale, bool animate) = 0; // Returns the current magnification ratio. @@ -49,7 +50,6 @@ class MagnificationController { MagnificationController() {} }; -} // namespace internal } // namespace ash #endif // ASH_MAGNIFIER_MAGNIFICATION_CONTROLLER_H_ diff --git a/ash/magnifier/partial_magnification_controller.cc b/ash/magnifier/partial_magnification_controller.cc new file mode 100644 index 0000000..7b682a7 --- /dev/null +++ b/ash/magnifier/partial_magnification_controller.cc @@ -0,0 +1,236 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/magnifier/partial_magnification_controller.h" + +#include "ash/shell.h" +#include "ash/shell_window_ids.h" +#include "ui/aura/root_window.h" +#include "ui/views/corewm/compound_event_filter.h" +#include "ui/aura/window.h" +#include "ui/aura/window_property.h" +#include "ui/gfx/screen.h" +#include "ui/compositor/layer.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_delegate.h" + +namespace { + +const float kMinPartialMagnifiedScaleThreshold = 1.1f; + +// Number of pixels to make the border of the magnified area. +const int kZoomInset = 16; + +// Width of the magnified area. +const int kMagnifierWidth = 200; + +// Height of the magnified area. +const int kMagnifierHeight = 200; + +// Name of the magnifier window. +const char kPartialMagniferWindowName[] = "PartialMagnifierWindow"; + +} // namespace + +namespace ash { + +PartialMagnificationController::PartialMagnificationController() + : is_on_zooming_(false), + is_enabled_(false), + scale_(kNonPartialMagnifiedScale), + zoom_widget_(NULL) { + Shell::GetInstance()->AddPreTargetHandler(this); +} + +PartialMagnificationController::~PartialMagnificationController() { + CloseMagnifierWindow(); + + Shell::GetInstance()->RemovePreTargetHandler(this); +} + +void PartialMagnificationController::SetScale(float scale) { + if (!is_enabled_) + return; + + scale_ = scale; + + if (IsPartialMagnified()) { + CreateMagnifierWindow(); + } else { + CloseMagnifierWindow(); + } +} + +void PartialMagnificationController::SetEnabled(bool enabled) { + if (enabled) { + is_enabled_ = enabled; + SetScale(kDefaultPartialMagnifiedScale); + } else { + SetScale(kNonPartialMagnifiedScale); + is_enabled_ = enabled; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// PartialMagnificationController: ui::EventHandler implementation + +ui::EventResult PartialMagnificationController::OnKeyEvent( + ui::KeyEvent* event) { + return ui::ER_UNHANDLED; +} + +ui::EventResult PartialMagnificationController::OnMouseEvent( + ui::MouseEvent* event) { + if (IsPartialMagnified() && event->type() == ui::ET_MOUSE_MOVED) { + aura::Window* target = static_cast<aura::Window*>(event->target()); + aura::RootWindow* current_root = target->GetRootWindow(); + // TODO(zork): Handle the case where the event is captured on a different + // display, such as when a menu is opened. + gfx::Rect root_bounds = current_root->bounds(); + + if (root_bounds.Contains(event->root_location())) { + SwitchTargetRootWindow(current_root); + + OnMouseMove(event->root_location()); + } + } + + return ui::ER_UNHANDLED; +} + +ui::EventResult PartialMagnificationController::OnScrollEvent( + ui::ScrollEvent* event) { + return ui::ER_UNHANDLED; +} + +ui::EventResult PartialMagnificationController::OnTouchEvent( + ui::TouchEvent* event) { + return ui::ER_UNHANDLED; +} + +ui::EventResult PartialMagnificationController::OnGestureEvent( + ui::GestureEvent* event) { + return ui::ER_UNHANDLED; +} + +//////////////////////////////////////////////////////////////////////////////// +// PartialMagnificationController: aura::WindowObserver implementation + +void PartialMagnificationController::OnWindowDestroying( + aura::Window* window) { + CloseMagnifierWindow(); + + aura::RootWindow* new_root_window = GetCurrentRootWindow(); + if (new_root_window != window) + SwitchTargetRootWindow(new_root_window); +} + +void PartialMagnificationController::OnWidgetClosing( + views::Widget* widget) { + DCHECK_EQ(widget, zoom_widget_); + RemoveZoomWidgetObservers(); + zoom_widget_ = NULL; +} + +void PartialMagnificationController::OnMouseMove( + const gfx::Point& location_in_root) { + gfx::Point origin(location_in_root); + + origin.Offset(-kMagnifierWidth / 2, -kMagnifierHeight / 2); + + if (zoom_widget_) { + zoom_widget_->SetBounds(gfx::Rect(origin.x(), origin.y(), + kMagnifierWidth, kMagnifierHeight)); + } +} + +bool PartialMagnificationController::IsPartialMagnified() const { + return scale_ >= kMinPartialMagnifiedScaleThreshold; +} + +void PartialMagnificationController::CreateMagnifierWindow() { + if (zoom_widget_) + return; + + aura::RootWindow* root_window = GetCurrentRootWindow(); + if (!root_window) + return; + + root_window->AddObserver(this); + + gfx::Point mouse(root_window->GetLastMouseLocationInRoot()); + + zoom_widget_ = new views::Widget; + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.can_activate = false; + params.accept_events = false; + params.transparent = true; + params.parent = root_window; + zoom_widget_->Init(params); + zoom_widget_->SetBounds(gfx::Rect(mouse.x() - kMagnifierWidth / 2, + mouse.y() - kMagnifierHeight / 2, + kMagnifierWidth, kMagnifierHeight)); + zoom_widget_->set_focus_on_creation(false); + zoom_widget_->Show(); + + aura::Window* window = zoom_widget_->GetNativeView(); + window->SetName(kPartialMagniferWindowName); + + zoom_widget_->GetNativeView()->layer()->SetBounds( + gfx::Rect(0, 0, + kMagnifierWidth, + kMagnifierHeight)); + zoom_widget_->GetNativeView()->layer()->SetBackgroundZoom( + (kMagnifierWidth - (kMagnifierWidth / scale_)) / 2, + (kMagnifierHeight - (kMagnifierHeight / scale_)) / 2, + scale_, + kZoomInset); + + zoom_widget_->AddObserver(this); +} + +void PartialMagnificationController::CloseMagnifierWindow() { + if (zoom_widget_) { + RemoveZoomWidgetObservers(); + zoom_widget_->Close(); + zoom_widget_ = NULL; + } +} + +void PartialMagnificationController::RemoveZoomWidgetObservers() { + DCHECK(zoom_widget_); + zoom_widget_->RemoveObserver(this); + aura::RootWindow* root_window = + zoom_widget_->GetNativeView()->GetRootWindow(); + DCHECK(root_window); + root_window->RemoveObserver(this); +} + +void PartialMagnificationController::SwitchTargetRootWindow( + aura::RootWindow* new_root_window) { + if (zoom_widget_ && + new_root_window == zoom_widget_->GetNativeView()->GetRootWindow()) + return; + + CloseMagnifierWindow(); + + // Recreate the magnifier window by updating the scale factor. + SetScale(GetScale()); +} + +aura::RootWindow* PartialMagnificationController::GetCurrentRootWindow() { + Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); + for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); + iter != root_windows.end(); ++iter) { + aura::RootWindow* root_window = *iter; + if (root_window->ContainsPointInRoot( + root_window->GetLastMouseLocationInRoot())) + return root_window; + } + return NULL; +} + +} // namespace ash diff --git a/ash/magnifier/partial_magnification_controller.h b/ash/magnifier/partial_magnification_controller.h new file mode 100644 index 0000000..7908d97 --- /dev/null +++ b/ash/magnifier/partial_magnification_controller.h @@ -0,0 +1,99 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_MAGNIFIER_PARTIAL_MAGNIFICATION_CONTROLLER_H_ +#define ASH_MAGNIFIER_PARTIAL_MAGNIFICATION_CONTROLLER_H_ + +#include "ui/aura/window_observer.h" +#include "ui/base/events/event_handler.h" +#include "ui/gfx/point.h" +#include "ui/views/widget/widget_observer.h" + +namespace aura { +class RootWindow; +} + +namespace ash { + +const float kDefaultPartialMagnifiedScale = 1.5f; +const float kNonPartialMagnifiedScale = 1.0f; + +// Controls the partial screen magnifier, which is a small area of the screen +// which is zoomed in. The zoomed area follows the mouse cursor when enabled. +class PartialMagnificationController + : public ui::EventHandler, + public aura::WindowObserver, + public views::WidgetObserver { + public: + PartialMagnificationController(); + virtual ~PartialMagnificationController(); + + // Enables (or disables if |enabled| is false) partial screen magnifier + // feature. + virtual void SetEnabled(bool enabled); + + bool is_enabled() const { return is_enabled_; } + + // Sets the magnification ratio. 1.0f means no magnification. + void SetScale(float scale); + + // Returns the current magnification ratio. + float GetScale() const { return scale_; } + + private: + void OnMouseMove(const gfx::Point& location_in_root); + + // Switch PartialMagnified RootWindow to |new_root_window|. This does + // following: + // - Remove the magnifier from the current root window. + // - Create a magnifier in the new root_window |new_root_window|. + // - Switch the target window from current window to |new_root_window|. + void SwitchTargetRootWindow(aura::RootWindow* new_root_window); + + // Returns the root window that contains the mouse cursor. + aura::RootWindow* GetCurrentRootWindow(); + + // Return true if the magnification scale > kMinPartialMagnifiedScaleThreshold + bool IsPartialMagnified() const; + + // Create the magnifier window. + void CreateMagnifierWindow(); + + // Cleans up the window if needed. + void CloseMagnifierWindow(); + + // Removes this as an observer of the zoom widget and the root window. + void RemoveZoomWidgetObservers(); + + // ui::EventHandler overrides: + virtual ui::EventResult OnKeyEvent(ui::KeyEvent* event) OVERRIDE; + virtual ui::EventResult OnMouseEvent(ui::MouseEvent* event) OVERRIDE; + virtual ui::EventResult OnScrollEvent(ui::ScrollEvent* event) OVERRIDE; + virtual ui::EventResult OnTouchEvent(ui::TouchEvent* event) OVERRIDE; + virtual ui::EventResult OnGestureEvent(ui::GestureEvent* event) OVERRIDE; + + // Overridden from WindowObserver: + virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; + + // Overridden from WidgetObserver: + virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE; + + // True if the magnified window is in motion of zooming or un-zooming effect. + // Otherwise, false. + bool is_on_zooming_; + + bool is_enabled_; + + // Current scale, origin (left-top) position of the magnification window. + float scale_; + gfx::Point origin_; + + views::Widget* zoom_widget_; + + DISALLOW_COPY_AND_ASSIGN(PartialMagnificationController); +}; + +} // namespace ash + +#endif // ASH_MAGNIFIER_PARTIAL_MAGNIFICATION_CONTROLLER_H_ diff --git a/ash/shell.cc b/ash/shell.cc index 078305c..c3fddea 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -22,6 +22,7 @@ #include "ash/focus_cycler.h" #include "ash/high_contrast/high_contrast_controller.h" #include "ash/magnifier/magnification_controller.h" +#include "ash/magnifier/partial_magnification_controller.h" #include "ash/root_window_controller.h" #include "ash/screen_ash.h" #include "ash/shell_delegate.h" @@ -273,6 +274,7 @@ Shell::~Shell() { // Alphabetical. drag_drop_controller_.reset(); magnification_controller_.reset(); + partial_magnification_controller_.reset(); power_button_controller_.reset(); session_state_controller_.reset(); resize_shadow_controller_.reset(); @@ -479,7 +481,10 @@ void Shell::Init() { AddPreTargetHandler(window_modality_controller_.get()); magnification_controller_.reset( - internal::MagnificationController::CreateInstance()); + MagnificationController::CreateInstance()); + + partial_magnification_controller_.reset( + new PartialMagnificationController()); high_contrast_controller_.reset(new HighContrastController); video_detector_.reset(new VideoDetector); diff --git a/ash/shell.h b/ash/shell.h index 7c0c281..db67eb6 100644 --- a/ash/shell.h +++ b/ash/shell.h @@ -68,7 +68,9 @@ class DesktopBackgroundController; class DisplayController; class HighContrastController; class Launcher; +class MagnificationController; class NestedDispatcherController; +class PartialMagnificationController; class PowerButtonController; class ScreenAsh; class SessionStateController; @@ -94,7 +96,6 @@ class DragDropController; class EventClientImpl; class EventRewriterEventFilter; class FocusCycler; -class MagnificationController; class MouseCursorEventFilter; class OutputConfiguratorAnimation; class OverlayEventFilter; @@ -323,10 +324,14 @@ class ASH_EXPORT Shell : internal::SystemModalContainerEventFilterDelegate, return high_contrast_controller_.get(); } - internal::MagnificationController* magnification_controller() { + MagnificationController* magnification_controller() { return magnification_controller_.get(); } + PartialMagnificationController* partial_magnification_controller() { + return partial_magnification_controller_.get(); + } + ScreenAsh* screen() { return screen_; } // Force the shelf to query for it's current visibility state. @@ -494,7 +499,8 @@ class ASH_EXPORT Shell : internal::SystemModalContainerEventFilterDelegate, scoped_ptr<internal::FocusCycler> focus_cycler_; scoped_ptr<DisplayController> display_controller_; scoped_ptr<HighContrastController> high_contrast_controller_; - scoped_ptr<internal::MagnificationController> magnification_controller_; + scoped_ptr<MagnificationController> magnification_controller_; + scoped_ptr<PartialMagnificationController> partial_magnification_controller_; scoped_ptr<aura::FocusManager> focus_manager_; scoped_ptr<aura::client::UserActionClient> user_action_client_; scoped_ptr<internal::MouseCursorEventFilter> mouse_cursor_filter_; diff --git a/chrome/browser/chromeos/accessibility/accessibility_util.cc b/chrome/browser/chromeos/accessibility/accessibility_util.cc index 28f4ea5..8cc231c 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_util.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_util.cc @@ -8,6 +8,7 @@ #include "ash/high_contrast/high_contrast_controller.h" #include "ash/magnifier/magnification_controller.h" +#include "ash/magnifier/partial_magnification_controller.h" #include "ash/shell.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -37,6 +38,13 @@ using content::RenderViewHost; +namespace { +const char kScreenMagnifierOff[] = ""; +const char kScreenMagnifierFull[] = "full"; +const char kScreenMagnifierPartial[] = "partial"; +} + + namespace chromeos { namespace accessibility { @@ -185,13 +193,17 @@ void EnableHighContrast(bool enabled) { #endif } -void EnableScreenMagnifier(bool enabled) { +void SetScreenMagnifier(ScreenMagnifierType type) { PrefService* pref_service = g_browser_process->local_state(); - pref_service->SetBoolean(prefs::kScreenMagnifierEnabled, enabled); + pref_service->SetString(prefs::kScreenMagnifierType, + ScreenMagnifierNameFromType(type)); pref_service->CommitPendingWrite(); #if defined(USE_ASH) - ash::Shell::GetInstance()->magnification_controller()->SetEnabled(enabled); + ash::Shell::GetInstance()->magnification_controller()->SetEnabled( + type == MAGNIFIER_FULL); + ash::Shell::GetInstance()->partial_magnification_controller()->SetEnabled( + type == MAGNIFIER_PARTIAL); #endif } @@ -244,13 +256,38 @@ bool IsHighContrastEnabled() { return high_contrast_enabled; } -bool IsScreenMagnifierEnabled() { - if (!g_browser_process) { - return false; - } +ScreenMagnifierType GetScreenMagnifierType() { + if (!g_browser_process) + return MAGNIFIER_OFF; + PrefService* prefs = g_browser_process->local_state(); - bool enabled = prefs && prefs->GetBoolean(prefs::kScreenMagnifierEnabled); - return enabled; + std::string screen_magnifier_type; + if (!prefs) + return MAGNIFIER_OFF; + + return ScreenMagnifierTypeFromName( + prefs->GetString(prefs::kScreenMagnifierType).c_str()); +} + +ScreenMagnifierType ScreenMagnifierTypeFromName(const char type_name[]) { + if (0 == strcmp(type_name, kScreenMagnifierFull)) + return MAGNIFIER_FULL; + else if (0 == strcmp(type_name, kScreenMagnifierPartial)) + return MAGNIFIER_PARTIAL; + else + return MAGNIFIER_OFF; +} + +const char* ScreenMagnifierNameFromType(ScreenMagnifierType type) { + switch (type) { + case MAGNIFIER_OFF: + return kScreenMagnifierOff; + case MAGNIFIER_FULL: + return kScreenMagnifierFull; + case MAGNIFIER_PARTIAL: + return kScreenMagnifierPartial; + } + return kScreenMagnifierOff; } void MaybeSpeak(const std::string& utterance) { diff --git a/chrome/browser/chromeos/accessibility/accessibility_util.h b/chrome/browser/chromeos/accessibility/accessibility_util.h index e85d3dd..87c8148 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_util.h +++ b/chrome/browser/chromeos/accessibility/accessibility_util.h @@ -23,8 +23,14 @@ void EnableSpokenFeedback(bool enabled, content::WebUI* login_web_ui); // Enable or disable the high contrast mode for Chrome. void EnableHighContrast(bool enabled); -// Enable or disable the screen magnifier. -void EnableScreenMagnifier(bool enabled); +enum ScreenMagnifierType { + MAGNIFIER_OFF, + MAGNIFIER_FULL, + MAGNIFIER_PARTIAL, +}; + +// Set the type of screen magnifier, or disable it. +void SetScreenMagnifier(ScreenMagnifierType type); // Enable or disable the virtual keyboard. void EnableVirtualKeyboard(bool enabled); @@ -42,8 +48,14 @@ bool IsSpokenFeedbackEnabled(); // Returns true if High Contrast is enabled, or false if not. bool IsHighContrastEnabled(); -// Returns true if Screen Magnifier is enabled, or false if not. -bool IsScreenMagnifierEnabled(); +// Returns the current state of the screen magnifier. +ScreenMagnifierType GetScreenMagnifierType(); + +// Translates from a string to ScreenMagnifierType. +ScreenMagnifierType ScreenMagnifierTypeFromName(const char type_name[]); + +// Translates from a ScreenMagnifierType to type string. +const char* ScreenMagnifierNameFromType(ScreenMagnifierType type); // Speak the given text if the accessibility pref is already set. void MaybeSpeak(const std::string& utterance); diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 4943028..f6534be 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc @@ -410,10 +410,10 @@ void WizardController::RegisterPrefs(PrefService* local_state) { false, PrefService::UNSYNCABLE_PREF); } - if (local_state->FindPreference(prefs::kScreenMagnifierEnabled) == NULL) { - local_state->RegisterBooleanPref(prefs::kScreenMagnifierEnabled, - false, - PrefService::UNSYNCABLE_PREF); + if (local_state->FindPreference(prefs::kScreenMagnifierType) == NULL) { + local_state->RegisterStringPref(prefs::kScreenMagnifierType, + "", + PrefService::UNSYNCABLE_PREF); } if (local_state->FindPreference(prefs::kVirtualKeyboardEnabled) == NULL) { local_state->RegisterBooleanPref(prefs::kVirtualKeyboardEnabled, diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 03cfadd..fce3ef5 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc @@ -102,16 +102,16 @@ void Preferences::RegisterUserPrefs(PrefService* prefs) { false, PrefService::UNSYNCABLE_PREF); } - if (prefs->FindPreference(prefs::kScreenMagnifierEnabled) == NULL) { - prefs->RegisterBooleanPref(prefs::kScreenMagnifierEnabled, - false, - PrefService::UNSYNCABLE_PREF); - } if (prefs->FindPreference(prefs::kScreenMagnifierScale) == NULL) { prefs->RegisterDoublePref(prefs::kScreenMagnifierScale, std::numeric_limits<double>::min(), PrefService::UNSYNCABLE_PREF); } + if (prefs->FindPreference(prefs::kScreenMagnifierType) == NULL) { + prefs->RegisterStringPref(prefs::kScreenMagnifierType, + "", + PrefService::UNSYNCABLE_PREF); + } if (prefs->FindPreference(prefs::kVirtualKeyboardEnabled) == NULL) { prefs->RegisterBooleanPref(prefs::kVirtualKeyboardEnabled, false, diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index 6c6e1e0..417fdb9 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html @@ -619,8 +619,17 @@ <div class="option-name"> <div class="checkbox"> <label> - <input id="accessibility-screen-magnifier-check" type="checkbox"> <span i18n-content="accessibilityScreenMagnifier"></span> + <select id="accessibility-screen-magnifier-type"> + <option value="" + i18n-content="accessibilityScreenMagnifierOff"></option> + <option value="full" + i18n-content="accessibilityScreenMagnifierFull"> + </option> + <option value="partial" + i18n-content="accessibilityScreenMagnifierPartial"> + </option> + </select> </label> </div> </div> diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index 7ead86f..7513df2 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js @@ -392,9 +392,9 @@ cr.define('options', function() { [$('accessibility-high-contrast-check').checked]); }; - $('accessibility-screen-magnifier-check').onchange = function(event) { + $('accessibility-screen-magnifier-type').onchange = function(event) { chrome.send('screenMagnifierChange', - [$('accessibility-screen-magnifier-check').checked]); + [$('accessibility-screen-magnifier-type').value]); }; } @@ -1154,11 +1154,11 @@ cr.define('options', function() { }, /** - * Set the initial state of the screen magnifier checkbox. + * Set the initial state of the screen magnifier dropdown. * @private */ - setScreenMagnifierCheckboxState_: function(checked) { - $('accessibility-screen-magnifier-check').checked = checked; + setScreenMagnifierTypeState_: function(type) { + $('accessibility-screen-magnifier-type').value = type; }, /** @@ -1302,7 +1302,7 @@ cr.define('options', function() { 'setMetricsReportingSettingVisibility', 'setPasswordGenerationSettingVisibility', 'setProfilesInfo', - 'setScreenMagnifierCheckboxState', + 'setScreenMagnifierTypeState', 'setSpokenFeedbackCheckboxState', 'setThemesResetButtonEnabled', 'setVirtualKeyboardCheckboxState', diff --git a/chrome/browser/ui/ash/ash_init.cc b/chrome/browser/ui/ash/ash_init.cc index 5705e79..241bfc6ff 100644 --- a/chrome/browser/ui/ash/ash_init.cc +++ b/chrome/browser/ui/ash/ash_init.cc @@ -8,6 +8,7 @@ #include "ash/ash_switches.h" #include "ash/high_contrast/high_contrast_controller.h" #include "ash/magnifier/magnification_controller.h" +#include "ash/magnifier/partial_magnification_controller.h" #include "ash/shell.h" #include "ash/wm/event_rewriter_event_filter.h" #include "ash/wm/property_util.h" @@ -83,8 +84,12 @@ void OpenAsh() { ash::Shell::GetInstance()->high_contrast_controller()->SetEnabled( chromeos::accessibility::IsHighContrastEnabled()); + chromeos::accessibility::ScreenMagnifierType magnifier_type = + chromeos::accessibility::GetScreenMagnifierType(); ash::Shell::GetInstance()->magnification_controller()->SetEnabled( - chromeos::accessibility::IsScreenMagnifierEnabled()); + magnifier_type == chromeos::accessibility::MAGNIFIER_FULL); + ash::Shell::GetInstance()->partial_magnification_controller()->SetEnabled( + magnifier_type == chromeos::accessibility::MAGNIFIER_PARTIAL); if (!CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableZeroBrowsersOpenForTests)) { diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index 47d6e35..8c6485f7 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc @@ -287,6 +287,12 @@ void BrowserOptionsHandler::GetLocalizedValues(DictionaryValue* values) { IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_DESCRIPTION }, { "accessibilityTapDragging", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_TOUCHPAD_TAP_DRAGGING_DESCRIPTION }, + { "accessibilityScreenMagnifierOff", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_OFF }, + { "accessibilityScreenMagnifierFull", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_FULL }, + { "accessibilityScreenMagnifierPartial", + IDS_OPTIONS_SETTINGS_ACCESSIBILITY_SCREEN_MAGNIFIER_PARTIAL }, { "accessibilitySpokenFeedback", IDS_OPTIONS_SETTINGS_ACCESSIBILITY_DESCRIPTION }, { "accessibilityTitle", @@ -1269,10 +1275,13 @@ void BrowserOptionsHandler::HighContrastChangeCallback(const ListValue* args) { void BrowserOptionsHandler::ScreenMagnifierChangeCallback( const ListValue* args) { - bool enabled = false; - args->GetBoolean(0, &enabled); + std::string type_name; + args->GetString(0, &type_name); + + chromeos::accessibility::ScreenMagnifierType type = + chromeos::accessibility::ScreenMagnifierTypeFromName(type_name.c_str()); - chromeos::accessibility::EnableScreenMagnifier(enabled); + chromeos::accessibility::SetScreenMagnifier(type); } void BrowserOptionsHandler::VirtualKeyboardChangeCallback( @@ -1312,11 +1321,13 @@ void BrowserOptionsHandler::SetupAccessibilityFeatures() { web_ui()->CallJavascriptFunction( "BrowserOptions.setHighContrastCheckboxState", high_contrast_enabled); - base::FundamentalValue screen_magnifier_enabled( - pref_service->GetBoolean(prefs::kScreenMagnifierEnabled)); + + base::StringValue magnifier_type( + pref_service->GetString(prefs::kScreenMagnifierType)); web_ui()->CallJavascriptFunction( - "BrowserOptions.setScreenMagnifierCheckboxState", - screen_magnifier_enabled); + "BrowserOptions.setScreenMagnifierTypeState", + magnifier_type); + base::FundamentalValue virtual_keyboard_enabled( pref_service->GetBoolean(prefs::kVirtualKeyboardEnabled)); web_ui()->CallJavascriptFunction( diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index b12343a..07100c6 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -729,10 +729,10 @@ const char kLanguageXkbAutoRepeatInterval[] = const char kSpokenFeedbackEnabled[] = "settings.accessibility"; // A boolean pref which determines whether high conrast is enabled. const char kHighContrastEnabled[] = "settings.a11y.high_contrast_enabled"; -// A boolean pref which determines whether screen magnifier is enabled. -const char kScreenMagnifierEnabled[] = "settings.a11y.screen_magnifier"; // A double pref which determines a zooming scale of the screen magnifier. const char kScreenMagnifierScale[] = "settings.a11y.screen_magnifier_scale"; +// A string pref which determines what type of screen magnifier is enabled. +const char kScreenMagnifierType[] = "settings.a11y.screen_magnifier_type"; // A boolean pref which determines whether virtual keyboard is enabled. // TODO(hashimoto): Remove this pref. const char kVirtualKeyboardEnabled[] = "settings.a11y.virtual_keyboard"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e6cbd0b..3af7178 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -266,8 +266,8 @@ extern const char kLanguageXkbAutoRepeatDelay[]; extern const char kLanguageXkbAutoRepeatInterval[]; extern const char kSpokenFeedbackEnabled[]; extern const char kHighContrastEnabled[]; -extern const char kScreenMagnifierEnabled[]; extern const char kScreenMagnifierScale[]; +extern const char kScreenMagnifierType[]; extern const char kVirtualKeyboardEnabled[]; extern const char kLabsAdvancedFilesystemEnabled[]; extern const char kLabsMediaplayerEnabled[]; diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 5fc7aed..dcdd7e2 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc @@ -63,6 +63,10 @@ Layer::Layer() layer_inverted_(false), layer_mask_(NULL), layer_mask_back_link_(NULL), + zoom_x_offset_(0), + zoom_y_offset_(0), + zoom_(1), + zoom_inset_(0), delegate_(NULL), web_layer_(NULL), scale_content_(true), @@ -86,6 +90,10 @@ Layer::Layer(LayerType type) layer_inverted_(false), layer_mask_(NULL), layer_mask_back_link_(NULL), + zoom_x_offset_(0), + zoom_y_offset_(0), + zoom_(1), + zoom_inset_(0), delegate_(NULL), scale_content_(true), device_scale_factor_(1.0f) { @@ -235,12 +243,7 @@ float Layer::GetCombinedOpacity() const { void Layer::SetBackgroundBlur(int blur_radius) { background_blur_radius_ = blur_radius; - WebKit::WebFilterOperations filters; - if (background_blur_radius_) { - filters.append(WebKit::WebFilterOperation::createBlurFilter( - background_blur_radius_)); - } - web_layer_->setBackgroundFilters(filters); + SetLayerBackgroundFilters(); } void Layer::SetLayerSaturation(float saturation) { @@ -299,6 +302,18 @@ void Layer::SetMaskLayer(Layer* layer_mask) { layer_mask->layer_mask_back_link_ = this; } +void Layer::SetBackgroundZoom(float x_offset, + float y_offset, + float zoom, + int inset) { + zoom_x_offset_ = x_offset; + zoom_y_offset_ = y_offset; + zoom_ = zoom; + zoom_inset_ = inset; + + SetLayerBackgroundFilters(); +} + void Layer::SetLayerFilters() { WebKit::WebFilterOperations filters; if (layer_saturation_) { @@ -322,6 +337,24 @@ void Layer::SetLayerFilters() { web_layer_->setFilters(filters); } +void Layer::SetLayerBackgroundFilters() { + WebKit::WebFilterOperations filters; + if (zoom_ != 1) { + filters.append(WebKit::WebFilterOperation::createZoomFilter( + WebKit::WebRect(zoom_x_offset_, zoom_y_offset_, + (GetTargetBounds().width() / zoom_), + (GetTargetBounds().height() / zoom_)), + zoom_inset_)); + } + + if (background_blur_radius_) { + filters.append(WebKit::WebFilterOperation::createBlurFilter( + background_blur_radius_)); + } + + web_layer_->setBackgroundFilters(filters); +} + float Layer::GetTargetOpacity() const { if (animator_.get() && animator_->IsAnimatingProperty( LayerAnimationElement::OPACITY)) diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 51f1cf3..bd6b13d 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h @@ -168,6 +168,12 @@ class COMPOSITOR_EXPORT Layer // grayscale otherwise. float GetTargetGrayscale() const; + // Zoom the background by a factor of |zoom|. The upper left corner of the + // zoomed area is offset from the top left corner of the layer by |x_offset| + // and |y_offset|. The effect is blended along the edge across |inset| + // pixels. + void SetBackgroundZoom(float x_offset, float y_offset, float zoom, int inset); + // Invert the layer. bool layer_inverted() const { return layer_inverted_; } void SetLayerInverted(bool inverted); @@ -333,6 +339,9 @@ class COMPOSITOR_EXPORT Layer // Set all filters which got applied to the layer. void SetLayerFilters(); + // Set all filters which got applied to the layer background. + void SetLayerBackgroundFilters(); + const LayerType type_; Compositor* compositor_; @@ -379,6 +388,18 @@ class COMPOSITOR_EXPORT Layer // while attached to the main layer before the main layer is deleted. Layer* layer_mask_back_link_; + // When the layer is zoomed, this is the offset to the upper left corner of + // the area in the layer that is zoomed. + float zoom_x_offset_; + float zoom_y_offset_; + + // The zoom factor to scale the layer by. Zooming is disabled when this is + // set to 1. + float zoom_; + + // Width of the border in pixels, where the scaling is blended. + int zoom_inset_; + std::string name_; LayerDelegate* delegate_; |