blob: a4e9221a3aed819709b6f08e418a5cfc0c01386a [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 "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h"
#include "base/bind.h"
#include "chrome/browser/ui/views/exclusive_access_bubble_views.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_view.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/view.h"
namespace {
// +----------------------------+
// | +-------+ |
// | |Control| |
// | +-------+ |
// | | <-- Control.bottom * kExitHeightScaleFactor
// | Screen | Buffer for mouse moves or pointer events
// | | before closing the fullscreen exit
// | | control.
// +----------------------------+
constexpr float kExitHeightScaleFactor = 1.5f;
// +----------------------------+
// | |
// | |
// | | <-- kShowFullscreenExitControlHeight
// | Screen | If a mouse move or pointer event is
// | | above this line, show the fullscreen
// | | exit control.
// | |
// +----------------------------+
constexpr float kShowFullscreenExitControlHeight = 3.f;
// Time to wait to hide the popup when it is triggered by touch input.
constexpr int kTouchPopupTimeoutMs = 5000;
} // namespace
FullscreenControlHost::FullscreenControlHost(BrowserView* browser_view,
views::View* host_view)
: browser_view_(browser_view),
fullscreen_control_popup_(
browser_view->GetBubbleParentView(),
base::Bind(&BrowserView::ExitFullscreen,
base::Unretained(browser_view)),
base::Bind(&FullscreenControlHost::OnVisibilityChanged,
base::Unretained(this))) {}
FullscreenControlHost::~FullscreenControlHost() = default;
void FullscreenControlHost::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() != ui::ET_MOUSE_MOVED ||
fullscreen_control_popup_.IsAnimating() ||
(input_entry_method_ != InputEntryMethod::NOT_ACTIVE &&
input_entry_method_ != InputEntryMethod::MOUSE)) {
return;
}
if (IsExitUiNeeded()) {
if (IsVisible()) {
float control_bottom = static_cast<float>(
fullscreen_control_popup_.GetFinalBounds().bottom());
float y_limit = control_bottom * kExitHeightScaleFactor;
if (event->y() >= y_limit)
Hide(true);
} else {
if (event->y() <= kShowFullscreenExitControlHeight)
ShowForInputEntryMethod(InputEntryMethod::MOUSE);
}
} else if (IsVisible()) {
Hide(true);
}
}
void FullscreenControlHost::OnTouchEvent(ui::TouchEvent* event) {
if (input_entry_method_ != InputEntryMethod::TOUCH)
return;
DCHECK(IsVisible());
// Hide the popup if the popup is showing and the user touches outside of the
// popup.
if (event->type() == ui::ET_TOUCH_PRESSED &&
!fullscreen_control_popup_.IsAnimating()) {
Hide(true);
} else if (event->type() == ui::ET_TOUCH_RELEASED) {
touch_timeout_timer_.Start(
FROM_HERE, base::TimeDelta::FromMilliseconds(kTouchPopupTimeoutMs),
base::Bind(&FullscreenControlHost::OnTouchPopupTimeout,
base::Unretained(this)));
}
}
void FullscreenControlHost::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_LONG_PRESS && IsExitUiNeeded() &&
!IsVisible()) {
ShowForInputEntryMethod(InputEntryMethod::TOUCH);
}
}
void FullscreenControlHost::Hide(bool animate) {
fullscreen_control_popup_.Hide(animate);
}
bool FullscreenControlHost::IsVisible() const {
return fullscreen_control_popup_.IsVisible();
}
void FullscreenControlHost::ShowForInputEntryMethod(
InputEntryMethod input_entry_method) {
input_entry_method_ = input_entry_method;
auto* bubble = browser_view_->exclusive_access_bubble();
if (bubble)
bubble->HideImmediately();
fullscreen_control_popup_.Show(browser_view_->GetClientAreaBoundsInScreen());
}
void FullscreenControlHost::OnVisibilityChanged() {
if (!IsVisible())
input_entry_method_ = InputEntryMethod::NOT_ACTIVE;
}
void FullscreenControlHost::OnTouchPopupTimeout() {
if (IsVisible() && !fullscreen_control_popup_.IsAnimating() &&
input_entry_method_ == InputEntryMethod::TOUCH) {
Hide(true);
}
}
bool FullscreenControlHost::IsExitUiNeeded() {
return browser_view_->IsFullscreen() &&
browser_view_->ShouldHideUIForFullscreen();
}