Commit 6179c3db authored by Yuwei Huang's avatar Yuwei Huang Committed by Commit Bot

[Fullscreen Control] Finish up the fullscreen control UI and add the animation class

This CL finishes up the fullscreen control UI. It is a transparent-black
circular button with a close (X) icon on the middle. It is used both as an
indicator for exiting fullscreen when the keyboard lock reserves the ESC
key and an actual button to exit fullscreen for touch devices.

This CL also implements a FullscreenControlPopup class to show the
indicator with a dropdown animation in replacement of the DropdownBarHost
implementation.

This is the UX spec (Google internal):
https://docs.google.com/presentation/d/11D86S87NZK5sAMLhc8WSV9pk_VWkjMAjvnN08uUD5po/edit#slide=id.g23756e43b7_3_0

Bug: 758456
Change-Id: I44dc2d0944386f5f6f5e607831c5ea4e38364357
Reviewed-on: https://chromium-review.googlesource.com/647950
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatarRobert Liao <robliao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504816}
parent 861713c2
...@@ -1666,6 +1666,8 @@ split_static_library("ui") { ...@@ -1666,6 +1666,8 @@ split_static_library("ui") {
"views/frame/native_widget_mac_frameless_nswindow.mm", "views/frame/native_widget_mac_frameless_nswindow.mm",
"views/fullscreen_control/fullscreen_control_host.cc", "views/fullscreen_control/fullscreen_control_host.cc",
"views/fullscreen_control/fullscreen_control_host.h", "views/fullscreen_control/fullscreen_control_host.h",
"views/fullscreen_control/fullscreen_control_popup.cc",
"views/fullscreen_control/fullscreen_control_popup.h",
"views/fullscreen_control/fullscreen_control_view.cc", "views/fullscreen_control/fullscreen_control_view.cc",
"views/fullscreen_control/fullscreen_control_view.h", "views/fullscreen_control/fullscreen_control_view.h",
"views/global_error_bubble_view.cc", "views/global_error_bubble_view.cc",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h" #include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h"
#include "base/i18n/rtl.h" #include "base/bind.h"
#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_view.h" #include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_view.h"
#include "ui/events/event.h" #include "ui/events/event.h"
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
namespace { namespace {
// +----------------------------+ // +----------------------------+
// | | Control | | // | +-------+ |
// | | | | // | |Control| |
// | +-----------+ | <-- Height // | +-------+ |
// | | <-- Height * kExitHeightScaleFactor // | | <-- Control.bottom * kExitHeightScaleFactor
// | Screen | Buffer for mouse moves or pointer events // | Screen | Buffer for mouse moves or pointer events
// | | before closing the fullscreen exit // | | before closing the fullscreen exit
// | | control. // | | control.
...@@ -40,37 +40,13 @@ constexpr float kShowFullscreenExitControlHeight = 3.f; ...@@ -40,37 +40,13 @@ constexpr float kShowFullscreenExitControlHeight = 3.f;
FullscreenControlHost::FullscreenControlHost(BrowserView* browser_view, FullscreenControlHost::FullscreenControlHost(BrowserView* browser_view,
views::View* host_view) views::View* host_view)
: DropdownBarHost(browser_view), : browser_view_(browser_view),
browser_view_(browser_view), fullscreen_control_popup_(browser_view->GetBubbleParentView(),
fullscreen_control_view_(new FullscreenControlView(browser_view)) { base::Bind(&BrowserView::ExitFullscreen,
Init(host_view, fullscreen_control_view_, fullscreen_control_view_); base::Unretained(browser_view))) {}
}
FullscreenControlHost::~FullscreenControlHost() = default; FullscreenControlHost::~FullscreenControlHost() = default;
bool FullscreenControlHost::AcceleratorPressed(
const ui::Accelerator& accelerator) {
return false;
}
bool FullscreenControlHost::CanHandleAccelerators() const {
return false;
}
gfx::Rect FullscreenControlHost::GetDialogPosition(
gfx::Rect avoid_overlapping_rect) {
gfx::Rect bounds;
GetWidgetBounds(&bounds);
if (bounds.IsEmpty())
return gfx::Rect();
// Place the view horizontally centered at the top of the widget.
int original_y = bounds.y();
bounds.ClampToCenteredSize(view()->GetPreferredSize());
bounds.set_y(original_y);
return bounds;
}
void FullscreenControlHost::OnMouseEvent(ui::MouseEvent* event) { void FullscreenControlHost::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() == ui::ET_MOUSE_MOVED) if (event->type() == ui::ET_MOUSE_MOVED)
HandleFullScreenControlVisibility(event, InputEntryMethod::MOUSE); HandleFullScreenControlVisibility(event, InputEntryMethod::MOUSE);
...@@ -86,23 +62,28 @@ void FullscreenControlHost::OnGestureEvent(ui::GestureEvent* event) { ...@@ -86,23 +62,28 @@ void FullscreenControlHost::OnGestureEvent(ui::GestureEvent* event) {
HandleFullScreenControlVisibility(event, InputEntryMethod::TOUCH); HandleFullScreenControlVisibility(event, InputEntryMethod::TOUCH);
} }
void FullscreenControlHost::OnVisibilityChanged() { void FullscreenControlHost::Hide(bool animate) {
if (!IsVisible()) fullscreen_control_popup_.Hide(animate);
input_entry_method_ = InputEntryMethod::NOT_ACTIVE; }
bool FullscreenControlHost::IsVisible() const {
return fullscreen_control_popup_.IsVisible();
} }
void FullscreenControlHost::HandleFullScreenControlVisibility( void FullscreenControlHost::HandleFullScreenControlVisibility(
const ui::LocatedEvent* event, const ui::LocatedEvent* event,
InputEntryMethod input_entry_method) { InputEntryMethod input_entry_method) {
if (IsAnimating() || (input_entry_method_ != InputEntryMethod::NOT_ACTIVE && if (fullscreen_control_popup_.IsAnimating() ||
input_entry_method_ != input_entry_method)) { (input_entry_method_ != InputEntryMethod::NOT_ACTIVE &&
input_entry_method_ != input_entry_method)) {
return; return;
} }
if (browser_view_->IsFullscreen()) { if (browser_view_->IsFullscreen()) {
if (IsVisible()) { if (IsVisible()) {
float control_height = static_cast<float>(view()->height()); float control_bottom = static_cast<float>(
float y_limit = control_height * kExitHeightScaleFactor; fullscreen_control_popup_.GetFinalBounds().bottom());
float y_limit = control_bottom * kExitHeightScaleFactor;
if (event->y() >= y_limit) if (event->y() >= y_limit)
Hide(true); Hide(true);
} else { } else {
...@@ -119,5 +100,5 @@ void FullscreenControlHost::HandleFullScreenControlVisibility( ...@@ -119,5 +100,5 @@ void FullscreenControlHost::HandleFullScreenControlVisibility(
void FullscreenControlHost::ShowForInputEntryMethod( void FullscreenControlHost::ShowForInputEntryMethod(
InputEntryMethod input_entry_method) { InputEntryMethod input_entry_method) {
input_entry_method_ = input_entry_method; input_entry_method_ = input_entry_method;
Show(true); fullscreen_control_popup_.Show(browser_view_->GetClientAreaBoundsInScreen());
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_HOST_H_ #define CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_HOST_H_
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/ui/views/dropdown_bar_host.h" #include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h"
#include "ui/events/event_handler.h" #include "ui/events/event_handler.h"
class BrowserView; class BrowserView;
...@@ -23,25 +23,24 @@ namespace views { ...@@ -23,25 +23,24 @@ namespace views {
class View; class View;
} // namespace views } // namespace views
class FullscreenControlHost : public DropdownBarHost, public ui::EventHandler { class FullscreenControlHost : public ui::EventHandler {
public: public:
// |host_view| allows the host to control the z-order of the underlying view. // |host_view| allows the host to control the z-order of the underlying view.
explicit FullscreenControlHost(BrowserView* browser_view, explicit FullscreenControlHost(BrowserView* browser_view,
views::View* host_view); views::View* host_view);
~FullscreenControlHost() override; ~FullscreenControlHost() override;
// DropdownBarHost:
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
bool CanHandleAccelerators() const override;
gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect) override;
// ui::EventHandler: // ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override; void OnMouseEvent(ui::MouseEvent* event) override;
void OnTouchEvent(ui::TouchEvent* event) override; void OnTouchEvent(ui::TouchEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
void Hide(bool animate);
bool IsVisible() const;
FullscreenControlView* fullscreen_control_view() { FullscreenControlView* fullscreen_control_view() {
return fullscreen_control_view_; return fullscreen_control_popup_.control_view();
} }
private: private:
...@@ -53,9 +52,6 @@ class FullscreenControlHost : public DropdownBarHost, public ui::EventHandler { ...@@ -53,9 +52,6 @@ class FullscreenControlHost : public DropdownBarHost, public ui::EventHandler {
TOUCH, // A touch event caused the view to show. TOUCH, // A touch event caused the view to show.
}; };
// DropdownBarHost:
void OnVisibilityChanged() override;
void HandleFullScreenControlVisibility(const ui::LocatedEvent* event, void HandleFullScreenControlVisibility(const ui::LocatedEvent* event,
InputEntryMethod input_entry_method); InputEntryMethod input_entry_method);
void ShowForInputEntryMethod(InputEntryMethod input_entry_method); void ShowForInputEntryMethod(InputEntryMethod input_entry_method);
...@@ -64,8 +60,7 @@ class FullscreenControlHost : public DropdownBarHost, public ui::EventHandler { ...@@ -64,8 +60,7 @@ class FullscreenControlHost : public DropdownBarHost, public ui::EventHandler {
BrowserView* const browser_view_; BrowserView* const browser_view_;
// Owned by DropdownBarHost. FullscreenControlPopup fullscreen_control_popup_;
FullscreenControlView* const fullscreen_control_view_;
DISALLOW_COPY_AND_ASSIGN(FullscreenControlHost); DISALLOW_COPY_AND_ASSIGN(FullscreenControlHost);
}; };
......
// Copyright 2017 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 "chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h"
#include "base/bind.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_view.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/views/widget/widget.h"
namespace {
// Offsets with respect to the top y coordinate of the parent widget.
constexpr int kFinalOffset = 45;
constexpr float kInitialOpacity = 0.1f;
constexpr float kFinalOpacity = 1.f;
constexpr int kSlideInDurationMs = 300;
constexpr int kSlideOutDurationMs = 150;
// Creates a Widget containing an FullscreenControlView.
std::unique_ptr<views::Widget> CreatePopupWidget(gfx::NativeView parent_view,
FullscreenControlView* view) {
// Initialize the popup.
std::unique_ptr<views::Widget> popup = std::make_unique<views::Widget>();
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.parent = parent_view;
popup->Init(params);
popup->SetContentsView(view);
return popup;
}
} // namespace
FullscreenControlPopup::FullscreenControlPopup(
gfx::NativeView parent_view,
const base::RepeatingClosure& on_button_pressed)
: control_view_(new FullscreenControlView(on_button_pressed)),
popup_(CreatePopupWidget(parent_view, control_view_)),
animation_(std::make_unique<gfx::SlideAnimation>(this)) {
animation_->Reset(0);
}
FullscreenControlPopup::~FullscreenControlPopup() {}
void FullscreenControlPopup::Show(const gfx::Rect& parent_bounds_in_screen) {
if (IsVisible())
return;
parent_bounds_in_screen_ = parent_bounds_in_screen;
animation_->SetSlideDuration(kSlideInDurationMs);
animation_->Show();
// The default animation progress is 0. Call it once here then show the popup
// to prevent potential flickering.
AnimationProgressed(animation_.get());
popup_->Show();
}
void FullscreenControlPopup::Hide(bool animated) {
if (!IsVisible())
return;
if (animated) {
animation_->SetSlideDuration(kSlideOutDurationMs);
animation_->Hide();
return;
}
animation_->Reset(0);
AnimationEnded(animation_.get());
}
gfx::Rect FullscreenControlPopup::GetFinalBounds() const {
return CalculateBounds(kFinalOffset);
}
views::Widget* FullscreenControlPopup::GetPopupWidget() {
return popup_.get();
}
gfx::SlideAnimation* FullscreenControlPopup::GetAnimationForTesting() {
return animation_.get();
}
bool FullscreenControlPopup::IsAnimating() const {
return animation_->is_animating();
}
bool FullscreenControlPopup::IsVisible() const {
return popup_->IsVisible();
}
void FullscreenControlPopup::AnimationProgressed(
const gfx::Animation* animation) {
float opacity = static_cast<float>(
animation_->CurrentValueBetween(kInitialOpacity, kFinalOpacity));
popup_->SetOpacity(opacity);
int initial_offset = -control_view_->GetPreferredSize().height();
popup_->SetBounds(CalculateBounds(
animation_->CurrentValueBetween(initial_offset, kFinalOffset)));
}
void FullscreenControlPopup::AnimationEnded(const gfx::Animation* animation) {
if (animation_->GetCurrentValue() == 0.0) {
// It's the end of the reversed animation. Just hide the popup in this case.
parent_bounds_in_screen_ = gfx::Rect();
popup_->Hide();
return;
}
AnimationProgressed(animation);
}
gfx::Rect FullscreenControlPopup::CalculateBounds(int y_offset) const {
if (parent_bounds_in_screen_.IsEmpty())
return gfx::Rect();
gfx::Point origin(parent_bounds_in_screen_.CenterPoint().x() -
control_view_->GetPreferredSize().width() / 2,
parent_bounds_in_screen_.y() + y_offset);
return {origin, control_view_->GetPreferredSize()};
}
// Copyright 2017 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 CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_POPUP_H_
#define CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_POPUP_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
namespace views {
class Widget;
} // namespace views
class FullscreenControlView;
// FullscreenControlPopup is a helper class that holds a FullscreenControlView
// and allows showing and hiding the view with a drop down animation.
class FullscreenControlPopup : public gfx::AnimationDelegate {
public:
FullscreenControlPopup(gfx::NativeView parent_view,
const base::RepeatingClosure& on_button_pressed);
~FullscreenControlPopup() override;
// Shows the indicator with an animation that drops it off the top of
// |parent_view|.
// |parent_bounds_in_screen| holds the bounds of |parent_view| in the screen
// coordinate system.
void Show(const gfx::Rect& parent_bounds_in_screen);
// Hides the indicator. If |animated| is true, the indicator will be hidden by
// the reversed animation of Show(), i.e. the indicator flies to the top of
// |parent_widget|.
void Hide(bool animated);
// Returns the final bounds of the control view when it is fully shown.
// Returns empty bounds if the popup is not visible.
gfx::Rect GetFinalBounds() const;
views::Widget* GetPopupWidget();
gfx::SlideAnimation* GetAnimationForTesting();
bool IsAnimating() const;
// Returns true if the popup is visible on the screen, i.e. Show() has been
// called and Hide() has never been called since then.
bool IsVisible() const;
FullscreenControlView* control_view() { return control_view_; }
private:
// gfx::AnimationDelegate:
void AnimationProgressed(const gfx::Animation* animation) override;
void AnimationEnded(const gfx::Animation* animation) override;
gfx::Rect CalculateBounds(int y_offset) const;
FullscreenControlView* const control_view_;
const std::unique_ptr<views::Widget> popup_;
const std::unique_ptr<gfx::SlideAnimation> animation_;
// The bounds is empty when the popup is not showing.
gfx::Rect parent_bounds_in_screen_;
DISALLOW_COPY_AND_ASSIGN(FullscreenControlPopup);
};
#endif // CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_POPUP_H_
// Copyright 2017 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 "ui/views/widget/widget.h"
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/animation/animation_test_api.h"
#include "ui/views/test/widget_test.h"
class FullscreenControlPopupTest : public views::test::WidgetTest {
public:
FullscreenControlPopupTest() {}
~FullscreenControlPopupTest() override {}
// views::test::WidgetTest:
void SetUp() override {
views::test::WidgetTest::SetUp();
parent_widget_ = CreateTopLevelNativeWidget();
parent_widget_->SetBounds(gfx::Rect(100, 100, 640, 480));
parent_widget_->Show();
popup_ = std::make_unique<FullscreenControlPopup>(
parent_widget_->GetNativeView(), base::BindRepeating(&base::DoNothing));
animation_api_ = std::make_unique<gfx::AnimationTestApi>(
popup_->GetAnimationForTesting());
}
void TearDown() override {
parent_widget_->CloseNow();
views::test::WidgetTest::TearDown();
}
protected:
void RunAnimationFor(base::TimeDelta duration) {
base::TimeTicks now = base::TimeTicks::Now();
animation_api_->SetStartTime(now);
animation_api_->Step(now + duration);
}
void CompleteAnimation() {
RunAnimationFor(base::TimeDelta::FromMilliseconds(5000));
}
gfx::Rect GetParentBounds() const {
return parent_widget_->GetClientAreaBoundsInScreen();
}
gfx::Rect GetPopupBounds() const {
return popup_->GetPopupWidget()->GetClientAreaBoundsInScreen();
}
std::unique_ptr<FullscreenControlPopup> popup_;
private:
std::unique_ptr<gfx::AnimationTestApi> animation_api_;
views::Widget* parent_widget_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FullscreenControlPopupTest);
};
TEST_F(FullscreenControlPopupTest, ShowPopupAnimated) {
EXPECT_FALSE(popup_->IsAnimating());
EXPECT_FALSE(popup_->IsVisible());
popup_->Show(GetParentBounds());
EXPECT_TRUE(popup_->IsAnimating());
EXPECT_TRUE(popup_->IsVisible());
// The popup should be above the parent bounds when the animation is just
// started.
EXPECT_GT(GetParentBounds().y(), GetPopupBounds().y());
gfx::Rect final_bounds = popup_->GetFinalBounds();
EXPECT_LT(GetParentBounds().y(), final_bounds.y());
CompleteAnimation();
EXPECT_FALSE(popup_->IsAnimating());
EXPECT_TRUE(popup_->IsVisible());
EXPECT_EQ(final_bounds, GetPopupBounds());
}
TEST_F(FullscreenControlPopupTest, HidePopupWhileStillShowing) {
popup_->Show(GetParentBounds());
RunAnimationFor(base::TimeDelta::FromMilliseconds(50));
EXPECT_TRUE(popup_->IsAnimating());
EXPECT_TRUE(popup_->IsVisible());
// The popup is partially shown.
EXPECT_LT(GetParentBounds().y(), GetPopupBounds().bottom());
popup_->Hide(true);
EXPECT_TRUE(popup_->IsAnimating());
EXPECT_TRUE(popup_->IsVisible());
EXPECT_LT(GetParentBounds().y(), GetPopupBounds().bottom());
CompleteAnimation();
EXPECT_FALSE(popup_->IsAnimating());
EXPECT_FALSE(popup_->IsVisible());
EXPECT_GT(GetParentBounds().y(), GetPopupBounds().y());
}
TEST_F(FullscreenControlPopupTest, HidePopupWithoutAnimation) {
popup_->Show(GetParentBounds());
CompleteAnimation();
popup_->Hide(false);
EXPECT_FALSE(popup_->IsAnimating());
EXPECT_FALSE(popup_->IsVisible());
}
...@@ -6,34 +6,46 @@ ...@@ -6,34 +6,46 @@
#include <memory> #include <memory>
#include "base/callback.h"
#include "cc/paint/paint_flags.h" #include "cc/paint/paint_flags.h"
#include "components/vector_icons/vector_icons.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/background.h" #include "ui/views/background.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/controls/image_view.h"
#include "ui/views/layout/fill_layout.h"
namespace { namespace {
constexpr int kCircleButtonDiameter = 48; // Partially-transparent background color.
const SkColor kBackgroundColor = SkColorSetARGB(0xcc, 0x28, 0x2c, 0x32);
// Spacing applied to all sides of the border of the control. constexpr int kCloseIconSize = 24;
constexpr int kSpacingInsetsAllSides = 45; constexpr int kCircleButtonDiameter = 48;
class CloseFullscreenButton : public views::Button { class CloseFullscreenButton : public views::Button {
public: public:
explicit CloseFullscreenButton(views::ButtonListener* listener) explicit CloseFullscreenButton(views::ButtonListener* listener)
: views::Button(listener) {} : views::Button(listener) {
std::unique_ptr<views::ImageView> close_image_view =
std::make_unique<views::ImageView>();
close_image_view->SetImage(gfx::CreateVectorIcon(
vector_icons::kCloseIcon, kCloseIconSize, SK_ColorWHITE));
AddChildView(close_image_view.release());
SetLayoutManager(new views::FillLayout());
}
private: private:
void PaintButtonContents(gfx::Canvas* canvas) override { void PaintButtonContents(gfx::Canvas* canvas) override {
// TODO(robliao): If we decide to move forward with this, use themes. // TODO(robliao): If we decide to move forward with this, use themes.
cc::PaintFlags flags; cc::PaintFlags flags;
flags.setAntiAlias(true); flags.setAntiAlias(true);
flags.setColor(SK_ColorDKGRAY); flags.setColor(kBackgroundColor);
flags.setStyle(cc::PaintFlags::kFill_Style); flags.setStyle(cc::PaintFlags::kFill_Style);
float radius = kCircleButtonDiameter / 2.0f; float radius = kCircleButtonDiameter / 2.0f;
canvas->DrawCircle(gfx::PointF(radius, radius), radius, flags); canvas->DrawCircle(gfx::PointF(radius, radius), radius, flags);
...@@ -44,22 +56,20 @@ class CloseFullscreenButton : public views::Button { ...@@ -44,22 +56,20 @@ class CloseFullscreenButton : public views::Button {
} // namespace } // namespace
FullscreenControlView::FullscreenControlView(BrowserView* browser_view) FullscreenControlView::FullscreenControlView(
: browser_view_(browser_view), const base::RepeatingClosure& on_button_pressed)
: on_button_pressed_(on_button_pressed),
exit_fullscreen_button_(new CloseFullscreenButton(this)) { exit_fullscreen_button_(new CloseFullscreenButton(this)) {
AddChildView(exit_fullscreen_button_); AddChildView(exit_fullscreen_button_);
SetLayoutManager(new views::BoxLayout( SetLayoutManager(new views::FillLayout());
views::BoxLayout::kHorizontal, gfx::Insets(kSpacingInsetsAllSides), 0));
exit_fullscreen_button_->SetPreferredSize( exit_fullscreen_button_->SetPreferredSize(
gfx::Size(kCircleButtonDiameter, kCircleButtonDiameter)); gfx::Size(kCircleButtonDiameter, kCircleButtonDiameter));
} }
FullscreenControlView::~FullscreenControlView() = default; FullscreenControlView::~FullscreenControlView() = default;
void FullscreenControlView::SetFocusAndSelection(bool select_all) {}
void FullscreenControlView::ButtonPressed(views::Button* sender, void FullscreenControlView::ButtonPressed(views::Button* sender,
const ui::Event& event) { const ui::Event& event) {
if (sender == exit_fullscreen_button_) if (sender == exit_fullscreen_button_ && on_button_pressed_)
browser_view_->ExitFullscreen(); on_button_pressed_.Run();
} }
...@@ -5,30 +5,29 @@ ...@@ -5,30 +5,29 @@
#ifndef CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_VIEW_H_ #ifndef CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_VIEW_H_
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h"
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
#include "ui/views/view.h" #include "ui/views/view.h"
// FullscreenControlView shows a FAB (floating action button from the material
// design spec) with close icon (i.e. a partially-transparent black circular
// button with a "X" icon in the middle).
// |on_button_pressed| will be called when the user taps the button.
class FullscreenControlView : public views::View, class FullscreenControlView : public views::View,
public DropdownBarHostDelegate,
public views::ButtonListener { public views::ButtonListener {
public: public:
explicit FullscreenControlView(BrowserView* browser_view); explicit FullscreenControlView(
const base::RepeatingClosure& on_button_pressed);
~FullscreenControlView() override; ~FullscreenControlView() override;
// DropdownBarHostDelegate:
void SetFocusAndSelection(bool select_all) override;
// views::ButtonListener: // views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override;
views::Button* exit_fullscreen_button() { return exit_fullscreen_button_; } views::Button* exit_fullscreen_button() { return exit_fullscreen_button_; }
private: private:
BrowserView* const browser_view_; const base::RepeatingClosure on_button_pressed_;
views::Button* const exit_fullscreen_button_; views::Button* const exit_fullscreen_button_;
DISALLOW_COPY_AND_ASSIGN(FullscreenControlView); DISALLOW_COPY_AND_ASSIGN(FullscreenControlView);
......
...@@ -4895,6 +4895,7 @@ test("unit_tests") { ...@@ -4895,6 +4895,7 @@ test("unit_tests") {
"../browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc", "../browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc",
"../browser/ui/views/confirm_bubble_views_unittest.cc", "../browser/ui/views/confirm_bubble_views_unittest.cc",
"../browser/ui/views/first_run_bubble_unittest.cc", "../browser/ui/views/first_run_bubble_unittest.cc",
"../browser/ui/views/fullscreen_control/fullscreen_control_popup_unittest.cc",
"../browser/ui/views/global_error_bubble_view_unittest.cc", "../browser/ui/views/global_error_bubble_view_unittest.cc",
"../browser/ui/views/harmony/layout_provider_unittest.cc", "../browser/ui/views/harmony/layout_provider_unittest.cc",
"../browser/ui/views/page_info/page_info_bubble_view_unittest.cc", "../browser/ui/views/page_info/page_info_bubble_view_unittest.cc",
......
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