blob: 59accb8573a52159f81e7bba825207f8db641793 [file] [log] [blame]
// 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 "components/fullscreen_control/fullscreen_control_popup.h"
#include <memory>
#include "base/bind.h"
#include "components/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;
// Creates a Widget containing an FullscreenControlView.
std::unique_ptr<views::Widget> CreatePopupWidget(
gfx::NativeView parent_view,
std::unique_ptr<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::WindowOpacity::kTranslucent;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.parent = parent_view;
popup->Init(std::move(params));
popup->SetContentsView(std::move(view));
return popup;
}
} // namespace
FullscreenControlPopup::FullscreenControlPopup(
gfx::NativeView parent_view,
const base::RepeatingClosure& on_button_pressed,
const base::RepeatingClosure& on_visibility_changed)
: FullscreenControlPopup(
CreatePopupWidget(
parent_view,
std::make_unique<FullscreenControlView>(on_button_pressed)),
on_visibility_changed) {}
FullscreenControlPopup::~FullscreenControlPopup() {}
// static
int FullscreenControlPopup::GetButtonBottomOffset() {
return kFinalOffset + FullscreenControlView::kCircleButtonDiameter;
}
void FullscreenControlPopup::Show(const gfx::Rect& parent_bounds_in_screen) {
if (IsVisible())
return;
parent_bounds_in_screen_ = parent_bounds_in_screen;
animation_->SetSlideDuration(base::Milliseconds(300));
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(base::Milliseconds(150));
animation_->Hide();
return;
}
animation_->Reset(0);
AnimationEnded(animation_.get());
}
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();
}
FullscreenControlPopup::FullscreenControlPopup(
std::unique_ptr<views::Widget> popup,
const base::RepeatingClosure& on_visibility_changed)
: AnimationDelegateViews(popup->GetRootView()),
control_view_(
static_cast<FullscreenControlView*>(popup->GetContentsView())),
popup_(std::move(popup)),
animation_(std::make_unique<gfx::SlideAnimation>(this)),
on_visibility_changed_(on_visibility_changed) {
DCHECK(on_visibility_changed_);
animation_->Reset(0);
}
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();
} else {
AnimationProgressed(animation);
}
OnVisibilityChanged();
}
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()};
}
void FullscreenControlPopup::OnVisibilityChanged() {
on_visibility_changed_.Run();
}