Commit 07eb80b1 authored by Jennifer Apacible's avatar Jennifer Apacible Committed by Commit Bot

[Picture in Picture] Support tabbing through window.

This change adds support for tabbing through the controls in the window.
Previously, the user can only utilise mouse clicks to interact with the
controls.

ControlButton will likely be updated to accommodate the addition of a
non-constant number of custom actions in the future.

UI affordances for the currently focused control will be added in a
separate patch.

BUG: 836389
Change-Id: Ic25524cfab9ceeba1d17ef00975347f6e3d562e6
Reviewed-on: https://chromium-review.googlesource.com/1072516
Commit-Queue: apacible <apacible@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#562034}
parent 44376080
......@@ -140,6 +140,8 @@ OverlayWindowViews::OverlayWindowViews(
Init(params);
SetUpViews();
is_initialized_ = true;
}
OverlayWindowViews::~OverlayWindowViews() = default;
......@@ -273,9 +275,7 @@ void OverlayWindowViews::SetUpViews() {
play_pause_controls_view_->SetPaintToLayer(ui::LAYER_TEXTURED);
// Don't show the controls until the mouse hovers over the window.
GetControlsBackgroundLayer()->SetVisible(false);
GetCloseControlsLayer()->SetVisible(false);
GetPlayPauseControlsLayer()->SetVisible(false);
UpdateControlsVisibility(false);
}
void OverlayWindowViews::UpdateCurrentSizeWithAspectRatio(gfx::Size new_size) {
......@@ -307,6 +307,12 @@ void OverlayWindowViews::UpdateCurrentSizeWithAspectRatio(gfx::Size new_size) {
}
}
void OverlayWindowViews::UpdateControlsVisibility(bool is_visible) {
GetControlsBackgroundLayer()->SetVisible(is_visible);
GetCloseControlsLayer()->SetVisible(is_visible);
GetPlayPauseControlsLayer()->SetVisible(is_visible);
}
bool OverlayWindowViews::IsActive() const {
return views::Widget::IsActive();
}
......@@ -392,21 +398,50 @@ void OverlayWindowViews::OnNativeWidgetWorkspaceChanged() {
// does not trigger this function. http://crbug.com/819673
}
void OverlayWindowViews::OnKeyEvent(ui::KeyEvent* event) {
if (event->type() != ui::ET_KEY_RELEASED)
return;
if (event->key_code() == ui::VKEY_TAB) {
// Switch the control that is currently focused. When the window
// is focused, |focused_control_button_| resets to CONTROL_PLAY_PAUSE.
if (focused_control_button_ == CONTROL_PLAY_PAUSE)
focused_control_button_ = CONTROL_CLOSE;
else
focused_control_button_ = CONTROL_PLAY_PAUSE;
// The controls may be hidden after the window is already in focus, e.g.
// mouse exits the window space. If they are already shown, this is a
// no-op.
UpdateControlsVisibility(true);
event->SetHandled();
} else if (event->key_code() == ui::VKEY_RETURN) {
if (focused_control_button_ == CONTROL_PLAY_PAUSE) {
// Retrieve expected active state based on what command was sent in
// TogglePlayPause() since the IPC message may not have been propogated
// the media player yet.
bool is_active = controller_->TogglePlayPause();
play_pause_controls_view_->SetToggled(is_active);
} else /* CONTROL_CLOSE */ {
controller_->Close();
}
event->SetHandled();
}
}
void OverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) {
// TODO(apacible): Handle tab focusing and touch screen events.
// TODO(apacible): Handle touch screen events.
// http://crbug.com/836389
switch (event->type()) {
// Only show the media controls when the mouse is hovering over the window.
case ui::ET_MOUSE_ENTERED:
GetControlsBackgroundLayer()->SetVisible(true);
GetCloseControlsLayer()->SetVisible(true);
GetPlayPauseControlsLayer()->SetVisible(true);
UpdateControlsVisibility(true);
break;
case ui::ET_MOUSE_EXITED:
GetControlsBackgroundLayer()->SetVisible(false);
GetCloseControlsLayer()->SetVisible(false);
GetPlayPauseControlsLayer()->SetVisible(false);
UpdateControlsVisibility(false);
break;
case ui::ET_MOUSE_RELEASED:
......@@ -433,6 +468,29 @@ void OverlayWindowViews::OnMouseEvent(ui::MouseEvent* event) {
}
}
void OverlayWindowViews::OnNativeFocus() {
// Show the controls when the window takes focus. This is used for tab and
// touch interactions. If initialisation happens after the window takes
// focus, any tabbing or touch gesture will show the controls.
if (is_initialized_)
UpdateControlsVisibility(true);
// Reset the first focused control to the play/pause button. This will
// always be called before key events can be handled.
focused_control_button_ = CONTROL_PLAY_PAUSE;
views::Widget::OnNativeFocus();
}
void OverlayWindowViews::OnNativeBlur() {
// Controls should be hidden when there is no more focus on the window. This
// is used for tabbing and touch interactions. For mouse interactions, the
// window cannot be blurred before the ui::ET_MOUSE_EXITED event is handled.
if (is_initialized_)
UpdateControlsVisibility(false);
views::Widget::OnNativeBlur();
}
void OverlayWindowViews::OnNativeWidgetMove() {
// If the sizes are the same, |this| was moved. Otherwise, this can be also
// called when the window resizes. Let OnNativeWidgetSizeChanged() handle
......
......@@ -19,6 +19,12 @@ class ToggleImageButton;
// implemented in views, which will support all desktop platforms.
class OverlayWindowViews : public content::OverlayWindow, public views::Widget {
public:
// The list of control buttons that appear on the window.
enum ControlButton {
CONTROL_PLAY_PAUSE,
CONTROL_CLOSE,
};
explicit OverlayWindowViews(
content::PictureInPictureWindowController* controller);
~OverlayWindowViews() override;
......@@ -44,9 +50,12 @@ class OverlayWindowViews : public content::OverlayWindow, public views::Widget {
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
void OnNativeWidgetWorkspaceChanged() override;
void OnKeyEvent(ui::KeyEvent* event) override;
void OnMouseEvent(ui::MouseEvent* event) override;
// views::internal::NativeWidgetDelegate:
void OnNativeFocus() override;
void OnNativeBlur() override;
void OnNativeWidgetMove() override;
void OnNativeWidgetSizeChanged(const gfx::Size& new_size) override;
......@@ -64,9 +73,17 @@ class OverlayWindowViews : public content::OverlayWindow, public views::Widget {
// aspect ratio of the video, which is retrieved from |natural_size_|.
void UpdateCurrentSizeWithAspectRatio(gfx::Size new_size);
// Updates the controls view::Views to reflect |is_visible|.
void UpdateControlsVisibility(bool is_visible);
// Not owned; |controller_| owns |this|.
content::PictureInPictureWindowController* controller_;
// Whether or not the components of the window has been set up. This is used
// as a check as some event handlers (e.g. focus) is propogated to the window
// before its contents is initialized. This is only set once.
bool is_initialized_ = false;
// The upper and lower bounds of |current_size_|. These are determined by the
// size of the primary display work area when Picture-in-Picture is initiated.
// TODO(apacible): Update these bounds when the display the window is on
......@@ -81,6 +98,10 @@ class OverlayWindowViews : public content::OverlayWindow, public views::Widget {
// ensuring factors such as aspect ratio is maintained.
gfx::Size natural_size_;
// The currently focused button on the window. This is used for keeping
// track of focus on the window while tabbing.
ControlButton focused_control_button_;
// Views to be shown.
std::unique_ptr<views::View> video_view_;
std::unique_ptr<views::View> controls_background_view_;
......
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