Commit 03251dfb authored by MinChen's avatar MinChen Committed by Commit Bot

ash: Position power button menu next to power button.

doc: go/add-power-button-location

changes in this cl:
- Add a switch kAshPowerButtonPosition with value to store the related
  power button position info that read at ChromeOS side.

- Parse the value of the switch in PowerButtonController.

- Get the menu bounds origins in different screen orientations according
  to the position info in PowerButtonMenuScreenView. This will help to
  set the bounds of the menu in each screen orientation.

- Get the menu animation direction and transform distance according to the
  position info in PowerButtonMenuView. We need to minus the animation
  transform when setting the bounds of the menu before showing the menu.

- Add PowerButtonControllerWithPositionTest*.


Bug: 818331
Change-Id: I0a1191072b85db59ed2d1d20e5ce25266a357e95
Reviewed-on: https://chromium-review.googlesource.com/963644
Commit-Queue: min c <minch@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarQiang Xu <warx@google.com>
Cr-Commit-Position: refs/heads/master@{#545130}
parent fb0cf370
...@@ -74,6 +74,17 @@ const char kAshEnableScaleSettingsTray[] = "ash-enable-scale-settings-tray"; ...@@ -74,6 +74,17 @@ const char kAshEnableScaleSettingsTray[] = "ash-enable-scale-settings-tray";
// Enables the stylus tools next to the status area. // Enables the stylus tools next to the status area.
const char kAshForceEnableStylusTools[] = "force-enable-stylus-tools"; const char kAshForceEnableStylusTools[] = "force-enable-stylus-tools";
// Power button position includes the power button's physical display side and
// the percentage for power button center position to the display's
// width/height in landscape_primary screen orientation. The value is a JSON
// object containing a "position" property with the value "left", "right",
// "top", or "bottom". For "left" and "right", a "y" property specifies the
// button's center position as a fraction of the display's height (in [0.0,
// 1.0]) relative to the top of the display. For "top" and "bottom", an "x"
// property gives the position as a fraction of the display's width relative to
// the left side of the display.
const char kAshPowerButtonPosition[] = "ash-power-button-position";
// Enables required things for the selected UI mode, regardless of whether the // Enables required things for the selected UI mode, regardless of whether the
// Chromebook is currently in the selected UI mode. // Chromebook is currently in the selected UI mode.
const char kAshUiMode[] = "force-tablet-mode"; const char kAshUiMode[] = "force-tablet-mode";
......
...@@ -33,6 +33,7 @@ ASH_PUBLIC_EXPORT extern const char kAshEnableTabletMode[]; ...@@ -33,6 +33,7 @@ ASH_PUBLIC_EXPORT extern const char kAshEnableTabletMode[];
ASH_PUBLIC_EXPORT extern const char kAshEnableWaylandServer[]; ASH_PUBLIC_EXPORT extern const char kAshEnableWaylandServer[];
ASH_PUBLIC_EXPORT extern const char kAshEnableMirroredScreen[]; ASH_PUBLIC_EXPORT extern const char kAshEnableMirroredScreen[];
ASH_PUBLIC_EXPORT extern const char kAshForceEnableStylusTools[]; ASH_PUBLIC_EXPORT extern const char kAshForceEnableStylusTools[];
ASH_PUBLIC_EXPORT extern const char kAshPowerButtonPosition[];
ASH_PUBLIC_EXPORT extern const char kAshUiMode[]; ASH_PUBLIC_EXPORT extern const char kAshUiMode[];
ASH_PUBLIC_EXPORT extern const char kAshUiModeAuto[]; ASH_PUBLIC_EXPORT extern const char kAshUiModeAuto[];
ASH_PUBLIC_EXPORT extern const char kAshUiModeClamshell[]; ASH_PUBLIC_EXPORT extern const char kAshUiModeClamshell[];
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ash/system/power/power_button_controller.h" #include "ash/system/power/power_button_controller.h"
#include <limits> #include <limits>
#include <string>
#include <utility> #include <utility>
#include "ash/accelerators/accelerator_controller.h" #include "ash/accelerators/accelerator_controller.h"
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "ash/wm/session_state_animator.h" #include "ash/wm/session_state_animator.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager/backlight.pb.h" #include "chromeos/dbus/power_manager/backlight.pb.h"
...@@ -73,6 +75,14 @@ constexpr base::TimeDelta PowerButtonController::kIgnoreRepeatedButtonUpDelay; ...@@ -73,6 +75,14 @@ constexpr base::TimeDelta PowerButtonController::kIgnoreRepeatedButtonUpDelay;
constexpr base::TimeDelta constexpr base::TimeDelta
PowerButtonController::kIgnorePowerButtonAfterResumeDelay; PowerButtonController::kIgnorePowerButtonAfterResumeDelay;
constexpr const char* PowerButtonController::kPositionField;
constexpr const char* PowerButtonController::kXField;
constexpr const char* PowerButtonController::kYField;
constexpr const char* PowerButtonController::kLeftPosition;
constexpr const char* PowerButtonController::kRightPosition;
constexpr const char* PowerButtonController::kTopPosition;
constexpr const char* PowerButtonController::kBottomPosition;
PowerButtonController::PowerButtonController( PowerButtonController::PowerButtonController(
BacklightsForcedOffSetter* backlights_forced_off_setter) BacklightsForcedOffSetter* backlights_forced_off_setter)
: backlights_forced_off_setter_(backlights_forced_off_setter), : backlights_forced_off_setter_(backlights_forced_off_setter),
...@@ -356,6 +366,7 @@ void PowerButtonController::StartPowerMenuAnimation() { ...@@ -356,6 +366,7 @@ void PowerButtonController::StartPowerMenuAnimation() {
if (!menu_widget_) if (!menu_widget_)
menu_widget_ = CreateMenuWidget(); menu_widget_ = CreateMenuWidget();
menu_widget_->SetContentsView(new PowerButtonMenuScreenView( menu_widget_->SetContentsView(new PowerButtonMenuScreenView(
power_button_position_, power_button_offset_percentage_,
base::BindRepeating(&PowerButtonController::SetShowMenuAnimationDone, base::BindRepeating(&PowerButtonController::SetShowMenuAnimationDone,
base::Unretained(this)))); base::Unretained(this))));
menu_widget_->Show(); menu_widget_->Show();
...@@ -382,6 +393,8 @@ void PowerButtonController::ProcessCommandLine() { ...@@ -382,6 +393,8 @@ void PowerButtonController::ProcessCommandLine() {
observe_accelerometer_events_ = cl->HasSwitch(switches::kAshEnableTabletMode); observe_accelerometer_events_ = cl->HasSwitch(switches::kAshEnableTabletMode);
force_clamshell_power_button_ = force_clamshell_power_button_ =
cl->HasSwitch(switches::kForceClamshellPowerButton); cl->HasSwitch(switches::kForceClamshellPowerButton);
ParsePowerButtonPositionSwitch();
} }
void PowerButtonController::InitTabletPowerButtonMembers() { void PowerButtonController::InitTabletPowerButtonMembers() {
...@@ -409,4 +422,56 @@ void PowerButtonController::SetShowMenuAnimationDone() { ...@@ -409,4 +422,56 @@ void PowerButtonController::SetShowMenuAnimationDone() {
show_menu_animation_done_ = true; show_menu_animation_done_ = true;
} }
void PowerButtonController::ParsePowerButtonPositionSwitch() {
const base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
if (!cl->HasSwitch(switches::kAshPowerButtonPosition))
return;
std::unique_ptr<base::DictionaryValue> position_info =
base::DictionaryValue::From(base::JSONReader::Read(
cl->GetSwitchValueASCII(switches::kAshPowerButtonPosition)));
if (!position_info) {
LOG(ERROR) << switches::kAshPowerButtonPosition << " flag has no value";
return;
}
std::string str_power_button_position;
if (!position_info->GetString(kPositionField, &str_power_button_position)) {
LOG(ERROR) << kPositionField << " field is always needed if "
<< switches::kAshPowerButtonPosition << " is set";
return;
}
if (str_power_button_position == kLeftPosition) {
power_button_position_ = PowerButtonPosition::LEFT;
} else if (str_power_button_position == kRightPosition) {
power_button_position_ = PowerButtonPosition::RIGHT;
} else if (str_power_button_position == kTopPosition) {
power_button_position_ = PowerButtonPosition::TOP;
} else if (str_power_button_position == kBottomPosition) {
power_button_position_ = PowerButtonPosition::BOTTOM;
} else {
LOG(ERROR) << "Invalid " << kPositionField << " field in "
<< switches::kAshPowerButtonPosition;
return;
}
if (power_button_position_ == PowerButtonPosition::LEFT ||
power_button_position_ == PowerButtonPosition::RIGHT) {
if (!position_info->GetDouble(kYField, &power_button_offset_percentage_)) {
LOG(ERROR) << kYField << " not set in "
<< switches::kAshPowerButtonPosition;
power_button_position_ = PowerButtonPosition::NONE;
return;
}
} else {
if (!position_info->GetDouble(kXField, &power_button_offset_percentage_)) {
LOG(ERROR) << kXField << " not set in "
<< switches::kAshPowerButtonPosition;
power_button_position_ = PowerButtonPosition::NONE;
return;
}
}
}
} // namespace ash } // namespace ash
...@@ -57,6 +57,9 @@ class ASH_EXPORT PowerButtonController ...@@ -57,6 +57,9 @@ class ASH_EXPORT PowerButtonController
LEGACY, LEGACY,
}; };
// The physical display side of power button.
enum class PowerButtonPosition { NONE, LEFT, TOP, RIGHT, BOTTOM };
// Amount of time since last screen state change that power button event needs // Amount of time since last screen state change that power button event needs
// to be ignored. // to be ignored.
static constexpr base::TimeDelta kScreenStateChangeDelay = static constexpr base::TimeDelta kScreenStateChangeDelay =
...@@ -73,6 +76,18 @@ class ASH_EXPORT PowerButtonController ...@@ -73,6 +76,18 @@ class ASH_EXPORT PowerButtonController
static constexpr base::TimeDelta kIgnorePowerButtonAfterResumeDelay = static constexpr base::TimeDelta kIgnorePowerButtonAfterResumeDelay =
base::TimeDelta::FromSeconds(2); base::TimeDelta::FromSeconds(2);
// Value of switches::kAshPowerButtonPosition stored in JSON format. These
// are the field names of the flag.
static constexpr const char* kPositionField = "position";
static constexpr const char* kXField = "x";
static constexpr const char* kYField = "y";
// Value of |kPositionField|.
static constexpr const char* kLeftPosition = "left";
static constexpr const char* kRightPosition = "right";
static constexpr const char* kTopPosition = "top";
static constexpr const char* kBottomPosition = "bottom";
explicit PowerButtonController( explicit PowerButtonController(
BacklightsForcedOffSetter* backlights_forced_off_setter); BacklightsForcedOffSetter* backlights_forced_off_setter);
~PowerButtonController() override; ~PowerButtonController() override;
...@@ -157,6 +172,10 @@ class ASH_EXPORT PowerButtonController ...@@ -157,6 +172,10 @@ class ASH_EXPORT PowerButtonController
// Sets |show_menu_animation_done_| to true. // Sets |show_menu_animation_done_| to true.
void SetShowMenuAnimationDone(); void SetShowMenuAnimationDone();
// A helper function called by ProcessCommandLine to parse the value of
// switches::kAshPowerButtonPosition.
void ParsePowerButtonPositionSwitch();
// Are the power or lock buttons currently held? // Are the power or lock buttons currently held?
bool power_button_down_ = false; bool power_button_down_ = false;
bool lock_button_down_ = false; bool lock_button_down_ = false;
...@@ -228,6 +247,15 @@ class ASH_EXPORT PowerButtonController ...@@ -228,6 +247,15 @@ class ASH_EXPORT PowerButtonController
// The fullscreen widget of power button menu. // The fullscreen widget of power button menu.
std::unique_ptr<views::Widget> menu_widget_; std::unique_ptr<views::Widget> menu_widget_;
// The physical display side of power button in landscape primary.
PowerButtonPosition power_button_position_ = PowerButtonPosition::NONE;
// The center of the power button's offset from the top of the screen (for
// left/right) or left side of the screen (for top/bottom) in
// landscape_primary. Values are in [0.0, 1.0] and express a fraction of the
// display's height or width, respectively.
double power_button_offset_percentage_ = 0.f;
ScopedObserver<BacklightsForcedOffSetter, BacklightsForcedOffSetter::Observer> ScopedObserver<BacklightsForcedOffSetter, BacklightsForcedOffSetter::Observer>
backlights_forced_off_observer_; backlights_forced_off_observer_;
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
#include "ash/system/power/power_button_menu_screen_view.h" #include "ash/system/power/power_button_menu_screen_view.h"
#include <utility>
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/system/power/power_button_controller.h"
#include "ash/system/power/power_button_menu_view.h" #include "ash/system/power/power_button_menu_view.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ui/compositor/layer.h" #include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor/scoped_layer_animation_settings.h"
...@@ -24,8 +26,20 @@ constexpr SkColor kShieldColor = SkColorSetARGBMacro(0xFF, 0x00, 0x00, 0x00); ...@@ -24,8 +26,20 @@ constexpr SkColor kShieldColor = SkColorSetARGBMacro(0xFF, 0x00, 0x00, 0x00);
// Opacity of the power button menu fullscreen background shield. // Opacity of the power button menu fullscreen background shield.
constexpr float kPowerButtonMenuOpacity = 0.6f; constexpr float kPowerButtonMenuOpacity = 0.6f;
// TODO(minch): Get the internal display size instead if needed.
// Gets the landscape size of the primary display. For landscape orientation,
// the width is always larger than height.
gfx::Size GetPrimaryDisplayLandscapeSize() {
gfx::Rect bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
return gfx::Size(std::max(bounds.width(), bounds.height()),
std::min(bounds.width(), bounds.height()));
}
} // namespace } // namespace
using PowerButtonPosition = PowerButtonController::PowerButtonPosition;
using TransformDirection = PowerButtonMenuView::TransformDirection;
class PowerButtonMenuScreenView::PowerButtonMenuBackgroundView class PowerButtonMenuScreenView::PowerButtonMenuBackgroundView
: public views::View, : public views::View,
public ui::ImplicitAnimationObserver { public ui::ImplicitAnimationObserver {
...@@ -72,15 +86,21 @@ class PowerButtonMenuScreenView::PowerButtonMenuBackgroundView ...@@ -72,15 +86,21 @@ class PowerButtonMenuScreenView::PowerButtonMenuBackgroundView
}; };
PowerButtonMenuScreenView::PowerButtonMenuScreenView( PowerButtonMenuScreenView::PowerButtonMenuScreenView(
base::RepeatingClosure show_animation_done) { PowerButtonPosition power_button_position,
double power_button_offset_percentage,
base::RepeatingClosure show_animation_done)
: power_button_position_(power_button_position),
power_button_offset_percentage_(power_button_offset_percentage) {
power_button_screen_background_shield_ = power_button_screen_background_shield_ =
new PowerButtonMenuBackgroundView(show_animation_done); new PowerButtonMenuBackgroundView(show_animation_done);
AddChildView(power_button_screen_background_shield_); AddChildView(power_button_screen_background_shield_);
power_button_menu_view_ = new PowerButtonMenuView(power_button_position_);
power_button_menu_view_ = new PowerButtonMenuView();
AddChildView(power_button_menu_view_); AddChildView(power_button_menu_view_);
display::Screen::GetScreen()->AddObserver(this); display::Screen::GetScreen()->AddObserver(this);
if (power_button_position_ != PowerButtonPosition::NONE)
InitializeMenuBoundsOrigins();
} }
PowerButtonMenuScreenView::~PowerButtonMenuScreenView() { PowerButtonMenuScreenView::~PowerButtonMenuScreenView() {
...@@ -93,13 +113,16 @@ void PowerButtonMenuScreenView::ScheduleShowHideAnimation(bool show) { ...@@ -93,13 +113,16 @@ void PowerButtonMenuScreenView::ScheduleShowHideAnimation(bool show) {
} }
void PowerButtonMenuScreenView::Layout() { void PowerButtonMenuScreenView::Layout() {
const gfx::Rect contents_bounds = GetContentsBounds(); power_button_screen_background_shield_->SetBoundsRect(GetContentsBounds());
power_button_screen_background_shield_->SetBoundsRect(contents_bounds);
gfx::Rect menu_bounds = GetMenuBounds();
PowerButtonMenuView::TransformDisplacement transform_displacement =
power_button_menu_view_->GetTransformDisplacement();
if (transform_displacement.direction == TransformDirection::X)
menu_bounds.set_x(menu_bounds.x() - transform_displacement.distance);
else if (transform_displacement.direction == TransformDirection::Y)
menu_bounds.set_y(menu_bounds.y() - transform_displacement.distance);
// TODO(minch): Get the menu bounds according to the power button position.
gfx::Rect menu_bounds = contents_bounds;
menu_bounds.ClampToCenteredSize(power_button_menu_view_->GetPreferredSize());
menu_bounds.set_y(menu_bounds.y() - PowerButtonMenuView::kMenuViewTopPadding);
power_button_menu_view_->SetBoundsRect(menu_bounds); power_button_menu_view_->SetBoundsRect(menu_bounds);
} }
...@@ -122,6 +145,135 @@ void PowerButtonMenuScreenView::OnDisplayMetricsChanged( ...@@ -122,6 +145,135 @@ void PowerButtonMenuScreenView::OnDisplayMetricsChanged(
uint32_t changed_metrics) { uint32_t changed_metrics) {
GetWidget()->SetBounds( GetWidget()->SetBounds(
display::Screen::GetScreen()->GetPrimaryDisplay().bounds()); display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
LayoutWithoutTransform();
}
void PowerButtonMenuScreenView::LayoutWithoutTransform() {
power_button_screen_background_shield_->SetBoundsRect(GetContentsBounds());
power_button_menu_view_->layer()->SetTransform(gfx::Transform());
power_button_menu_view_->SetBoundsRect(GetMenuBounds());
}
void PowerButtonMenuScreenView::InitializeMenuBoundsOrigins() {
// Power button position offset in pixels from the top when the button is at
// the left/right of the screen after rotation.
int left_power_button_y = 0, right_power_button_y = 0;
// Power button position offset in pixels from the left when the button is at
// the top/bottom of the screen after rotation.
int top_power_button_x = 0, bottom_power_button_x = 0;
// The screen orientation when the power button is at the
// left/right/top/bottom of the screen after rotation.
OrientationLockType left_screen_orientation, right_screen_orientation,
top_screen_orientation, bottom_screen_orientation;
const gfx::Size landscape_size = GetPrimaryDisplayLandscapeSize();
int display_width = landscape_size.width();
int display_height = landscape_size.height();
if (power_button_position_ == PowerButtonPosition::TOP ||
power_button_position_ == PowerButtonPosition::BOTTOM) {
std::swap(display_width, display_height);
}
int power_button_offset = display_height * power_button_offset_percentage_;
switch (power_button_position_) {
case PowerButtonPosition::LEFT:
case PowerButtonPosition::BOTTOM:
left_power_button_y = bottom_power_button_x = power_button_offset;
right_power_button_y = top_power_button_x =
display_height - power_button_offset;
break;
case PowerButtonPosition::RIGHT:
case PowerButtonPosition::TOP:
left_power_button_y = bottom_power_button_x =
display_height - power_button_offset;
right_power_button_y = top_power_button_x = power_button_offset;
break;
default:
NOTREACHED();
return;
}
switch (power_button_position_) {
case PowerButtonPosition::LEFT:
left_screen_orientation = OrientationLockType::kLandscapePrimary;
right_screen_orientation = OrientationLockType::kLandscapeSecondary;
top_screen_orientation = OrientationLockType::kPortraitPrimary;
bottom_screen_orientation = OrientationLockType::kPortraitSecondary;
break;
case PowerButtonPosition::RIGHT:
left_screen_orientation = OrientationLockType::kLandscapeSecondary;
right_screen_orientation = OrientationLockType::kLandscapePrimary;
top_screen_orientation = OrientationLockType::kPortraitSecondary;
bottom_screen_orientation = OrientationLockType::kPortraitPrimary;
break;
case PowerButtonPosition::TOP:
left_screen_orientation = OrientationLockType::kPortraitSecondary;
right_screen_orientation = OrientationLockType::kPortraitPrimary;
top_screen_orientation = OrientationLockType::kLandscapePrimary;
bottom_screen_orientation = OrientationLockType::kLandscapeSecondary;
break;
case PowerButtonPosition::BOTTOM:
left_screen_orientation = OrientationLockType::kPortraitPrimary;
right_screen_orientation = OrientationLockType::kPortraitSecondary;
top_screen_orientation = OrientationLockType::kLandscapeSecondary;
bottom_screen_orientation = OrientationLockType::kLandscapePrimary;
break;
default:
NOTREACHED();
return;
}
const gfx::Size menu_size = power_button_menu_view_->GetPreferredSize();
// Power button position offset from the left when the button is at the left
// is always zero.
menu_bounds_origins_.insert(std::make_pair(
left_screen_orientation,
gfx::Point(PowerButtonMenuView::kMenuViewTransformDistanceDp,
left_power_button_y - menu_size.height() / 2)));
menu_bounds_origins_.insert(std::make_pair(
right_screen_orientation,
gfx::Point(display_width -
PowerButtonMenuView::kMenuViewTransformDistanceDp -
menu_size.width(),
right_power_button_y - menu_size.height() / 2)));
// Power button position offset from the top when the button is at the top
// is always zero.
menu_bounds_origins_.insert(std::make_pair(
top_screen_orientation,
gfx::Point(top_power_button_x - menu_size.width() / 2,
PowerButtonMenuView::kMenuViewTransformDistanceDp)));
menu_bounds_origins_.insert(std::make_pair(
bottom_screen_orientation,
gfx::Point(bottom_power_button_x - menu_size.width() / 2,
display_width -
PowerButtonMenuView::kMenuViewTransformDistanceDp -
menu_size.height())));
}
gfx::Rect PowerButtonMenuScreenView::GetMenuBounds() {
gfx::Rect menu_bounds;
if (power_button_position_ == PowerButtonPosition::NONE ||
!Shell::Get()
->tablet_mode_controller()
->IsTabletModeWindowManagerEnabled()) {
menu_bounds = GetContentsBounds();
menu_bounds.ClampToCenteredSize(
power_button_menu_view_->GetPreferredSize());
} else {
menu_bounds.set_origin(
menu_bounds_origins_[Shell::Get()
->screen_orientation_controller()
->GetCurrentOrientation()]);
menu_bounds.set_size(power_button_menu_view_->GetPreferredSize());
}
return menu_bounds;
} }
} // namespace ash } // namespace ash
...@@ -5,7 +5,11 @@ ...@@ -5,7 +5,11 @@
#ifndef ASH_SYSTEM_POWER_POWER_BUTTON_MENU_SCREEN_VIEW_H_ #ifndef ASH_SYSTEM_POWER_POWER_BUTTON_MENU_SCREEN_VIEW_H_
#define ASH_SYSTEM_POWER_POWER_BUTTON_MENU_SCREEN_VIEW_H_ #define ASH_SYSTEM_POWER_POWER_BUTTON_MENU_SCREEN_VIEW_H_
#include <unordered_map>
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/display/screen_orientation_controller_chromeos.h"
#include "ash/system/power/power_button_controller.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/display/display_observer.h" #include "ui/display/display_observer.h"
#include "ui/views/view.h" #include "ui/views/view.h"
...@@ -21,7 +25,9 @@ class ASH_EXPORT PowerButtonMenuScreenView : public views::View, ...@@ -21,7 +25,9 @@ class ASH_EXPORT PowerButtonMenuScreenView : public views::View,
public: public:
// |show_animation_done| is a callback for when the animation that shows the // |show_animation_done| is a callback for when the animation that shows the
// power menu has finished. // power menu has finished.
explicit PowerButtonMenuScreenView( PowerButtonMenuScreenView(
PowerButtonController::PowerButtonPosition power_button_position,
double power_button_offset,
base::RepeatingClosure show_animation_done); base::RepeatingClosure show_animation_done);
~PowerButtonMenuScreenView() override; ~PowerButtonMenuScreenView() override;
...@@ -47,11 +53,32 @@ class ASH_EXPORT PowerButtonMenuScreenView : public views::View, ...@@ -47,11 +53,32 @@ class ASH_EXPORT PowerButtonMenuScreenView : public views::View,
void OnDisplayMetricsChanged(const display::Display& display, void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override; uint32_t changed_metrics) override;
// Lays out the view without animation transform.
void LayoutWithoutTransform();
// Initializes |menu_bounds_origins_| according to power button position info.
void InitializeMenuBoundsOrigins();
// Gets the bounds of power button menu.
gfx::Rect GetMenuBounds();
// Created by PowerButtonMenuScreenView. Owned by views hierarchy. // Created by PowerButtonMenuScreenView. Owned by views hierarchy.
PowerButtonMenuView* power_button_menu_view_ = nullptr; PowerButtonMenuView* power_button_menu_view_ = nullptr;
PowerButtonMenuBackgroundView* power_button_screen_background_shield_ = PowerButtonMenuBackgroundView* power_button_screen_background_shield_ =
nullptr; nullptr;
// The physical display side of power button in landscape primary.
PowerButtonController::PowerButtonPosition power_button_position_;
// The center of the power button's offset from the top of the screen (for
// left/right) or left side of the screen (for top/bottom) in
// landscape_primary. Values are in [0.0, 1.0] and express a fraction of the
// display's height or width, respectively.
double power_button_offset_percentage_ = 0.f;
// The origin of the menu bounds in different screen orientations.
std::unordered_map<OrientationLockType, gfx::Point> menu_bounds_origins_;
DISALLOW_COPY_AND_ASSIGN(PowerButtonMenuScreenView); DISALLOW_COPY_AND_ASSIGN(PowerButtonMenuScreenView);
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ash/system/power/power_button_menu_view.h" #include "ash/system/power/power_button_menu_view.h"
#include "ash/display/screen_orientation_controller_chromeos.h"
#include "ash/resources/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller.h" #include "ash/session/session_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
#include "ash/system/power/power_button_menu_item_view.h" #include "ash/system/power/power_button_menu_item_view.h"
#include "ash/system/user/login_status.h" #include "ash/system/user/login_status.h"
#include "ash/wm/lock_state_controller.h" #include "ash/wm/lock_state_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
...@@ -28,7 +30,11 @@ constexpr int kMenuViewRoundRectRadiusDp = 16; ...@@ -28,7 +30,11 @@ constexpr int kMenuViewRoundRectRadiusDp = 16;
} // namespace } // namespace
PowerButtonMenuView::PowerButtonMenuView() { using PowerButtonPosition = PowerButtonController::PowerButtonPosition;
PowerButtonMenuView::PowerButtonMenuView(
PowerButtonPosition power_button_position)
: power_button_position_(power_button_position) {
SetPaintToLayer(); SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false); layer()->SetFillsBoundsOpaquely(false);
...@@ -57,13 +63,64 @@ void PowerButtonMenuView::ScheduleShowHideAnimation(bool show) { ...@@ -57,13 +63,64 @@ void PowerButtonMenuView::ScheduleShowHideAnimation(bool show) {
// Animation of the menu view bounds change. // Animation of the menu view bounds change.
if (show) { if (show) {
gfx::Transform transform; gfx::Transform transform;
transform.Translate(0, kMenuViewTopPadding); TransformDisplacement transform_displacement = GetTransformDisplacement();
if (transform_displacement.direction == TransformDirection::X)
transform.Translate(transform_displacement.distance, 0);
else if (transform_displacement.direction == TransformDirection::Y)
transform.Translate(0, transform_displacement.distance);
layer()->SetTransform(transform); layer()->SetTransform(transform);
} else { } else {
layer()->SetTransform(gfx::Transform()); layer()->SetTransform(gfx::Transform());
} }
} }
PowerButtonMenuView::TransformDisplacement
PowerButtonMenuView::GetTransformDisplacement() const {
TransformDisplacement transform_displacement;
if (power_button_position_ == PowerButtonPosition::NONE ||
!Shell::Get()
->tablet_mode_controller()
->IsTabletModeWindowManagerEnabled()) {
transform_displacement.direction = TransformDirection::Y;
transform_displacement.distance = kMenuViewTransformDistanceDp;
return transform_displacement;
}
OrientationLockType screen_orientation =
Shell::Get()->screen_orientation_controller()->GetCurrentOrientation();
bool is_left_or_right = power_button_position_ == PowerButtonPosition::LEFT ||
power_button_position_ == PowerButtonPosition::RIGHT;
if (IsLandscapeOrientation(screen_orientation)) {
transform_displacement.direction =
is_left_or_right ? TransformDirection::X : TransformDirection::Y;
} else {
transform_displacement.direction =
is_left_or_right ? TransformDirection::Y : TransformDirection::X;
}
bool positive_transform = false;
if (is_left_or_right) {
bool is_primary = IsPrimaryOrientation(screen_orientation);
positive_transform = power_button_position_ == PowerButtonPosition::LEFT
? is_primary
: !is_primary;
} else {
bool is_landscape_primary_or_portrait_secondary =
screen_orientation == OrientationLockType::kLandscapePrimary ||
screen_orientation == OrientationLockType::kPortraitSecondary;
positive_transform = power_button_position_ == PowerButtonPosition::TOP
? is_landscape_primary_or_portrait_secondary
: !is_landscape_primary_or_portrait_secondary;
}
transform_displacement.distance = positive_transform
? kMenuViewTransformDistanceDp
: -kMenuViewTransformDistanceDp;
return transform_displacement;
}
void PowerButtonMenuView::CreateItems() { void PowerButtonMenuView::CreateItems() {
power_off_item_ = new PowerButtonMenuItemView( power_off_item_ = new PowerButtonMenuItemView(
this, kSystemPowerButtonMenuPowerOffIcon, this, kSystemPowerButtonMenuPowerOffIcon,
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef ASH_SYSTEM_POWER_BUTTON_MENU_VIEW_H_ #ifndef ASH_SYSTEM_POWER_POWER_BUTTON_MENU_VIEW_H_
#define ASH_SYSTEM_POWER_BUTTON_MENU_VIEW_H_ #define ASH_SYSTEM_POWER_POWER_BUTTON_MENU_VIEW_H_
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/system/power/power_button_controller.h"
#include "base/macros.h" #include "base/macros.h"
#include "ui/compositor/layer_animation_observer.h" #include "ui/compositor/layer_animation_observer.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
...@@ -23,10 +24,21 @@ class ASH_EXPORT PowerButtonMenuView : public views::View, ...@@ -23,10 +24,21 @@ class ASH_EXPORT PowerButtonMenuView : public views::View,
// The duration of the animation to show or hide the power button menu view. // The duration of the animation to show or hide the power button menu view.
static constexpr int kAnimationTimeoutMs = 500; static constexpr int kAnimationTimeoutMs = 500;
// Top padding of the menu view. // Distance of the menu animation transform.
static constexpr int kMenuViewTopPadding = 16; static constexpr int kMenuViewTransformDistanceDp = 16;
PowerButtonMenuView(); // Direction of the animation transform. X means to translate from
// x-coordinate. Y means to translate from y-coordinate.
enum class TransformDirection { NONE, X, Y };
// The translate direction and distance of the animation transform.
struct TransformDisplacement {
TransformDirection direction;
int distance;
};
explicit PowerButtonMenuView(
PowerButtonController::PowerButtonPosition power_button_position);
~PowerButtonMenuView() override; ~PowerButtonMenuView() override;
bool sign_out_item_for_testing() const { return sign_out_item_; } bool sign_out_item_for_testing() const { return sign_out_item_; }
...@@ -34,6 +46,9 @@ class ASH_EXPORT PowerButtonMenuView : public views::View, ...@@ -34,6 +46,9 @@ class ASH_EXPORT PowerButtonMenuView : public views::View,
// Schedules an animation to show or hide the view. // Schedules an animation to show or hide the view.
void ScheduleShowHideAnimation(bool show); void ScheduleShowHideAnimation(bool show);
// Gets the transform displacement, which contains direction and distance.
TransformDisplacement GetTransformDisplacement() const;
private: private:
// Creates the items that in the menu. // Creates the items that in the menu.
void CreateItems(); void CreateItems();
...@@ -53,9 +68,12 @@ class ASH_EXPORT PowerButtonMenuView : public views::View, ...@@ -53,9 +68,12 @@ class ASH_EXPORT PowerButtonMenuView : public views::View,
PowerButtonMenuItemView* power_off_item_ = nullptr; PowerButtonMenuItemView* power_off_item_ = nullptr;
PowerButtonMenuItemView* sign_out_item_ = nullptr; PowerButtonMenuItemView* sign_out_item_ = nullptr;
// The physical display side of power button in landscape primary.
PowerButtonController::PowerButtonPosition power_button_position_;
DISALLOW_COPY_AND_ASSIGN(PowerButtonMenuView); DISALLOW_COPY_AND_ASSIGN(PowerButtonMenuView);
}; };
} // namespace ash } // namespace ash
#endif // ASH_SYSTEM_POWER_BUTTON_MENU_VIEW_H_ #endif // ASH_SYSTEM_POWER_POWER_BUTTON_MENU_VIEW_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment