Commit 7a789e59 authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Add WideFrameView class

This is reland of crrebu.com/c/990203 with ASH_EXPORT

This will be used for ARC++ windows. This
a) is always placed at the topof the display and covered full width.
b) supports immersive mode
c) is resized when the display metrics changes.

TBR=mukai@chromium.org
BUG=b/33693796
TEST=covered by unittest

Reviewed-on: https://chromium-review.googlesource.com/990203Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#550278}
Change-Id: Ib60a03017c724c62d5912a472fa6e32dd9a02e99
Reviewed-on: https://chromium-review.googlesource.com/1011323Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550443}
parent 12b708c7
...@@ -212,6 +212,8 @@ component("ash") { ...@@ -212,6 +212,8 @@ component("ash") {
"frame/frame_header_util.h", "frame/frame_header_util.h",
"frame/header_view.cc", "frame/header_view.cc",
"frame/header_view.h", "frame/header_view.h",
"frame/wide_frame_view.cc",
"frame/wide_frame_view.h",
"high_contrast/high_contrast_controller.cc", "high_contrast/high_contrast_controller.cc",
"high_contrast/high_contrast_controller.h", "high_contrast/high_contrast_controller.h",
"highlighter/highlighter_controller.cc", "highlighter/highlighter_controller.cc",
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "ash/frame/caption_buttons/frame_caption_button.h" #include "ash/frame/caption_buttons/frame_caption_button.h"
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h" #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/header_view.h" #include "ash/frame/header_view.h"
#include "ash/frame/wide_frame_view.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h"
#include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/public/cpp/vector_icons/vector_icons.h"
#include "ash/public/cpp/window_properties.h" #include "ash/public/cpp/window_properties.h"
#include "ash/resources/vector_icons/vector_icons.h" #include "ash/resources/vector_icons/vector_icons.h"
...@@ -622,6 +624,57 @@ TEST_F(CustomFrameViewAshTest, CustomButtonModel) { ...@@ -622,6 +624,57 @@ TEST_F(CustomFrameViewAshTest, CustomButtonModel) {
#endif #endif
} }
TEST_F(CustomFrameViewAshTest, WideFrame) {
auto* delegate = new CustomFrameTestWidgetDelegate();
std::unique_ptr<views::Widget> widget = CreateTestWidget(delegate);
CustomFrameViewAsh* custom_frame_view = delegate->custom_frame_view();
HeaderView* header_view =
static_cast<HeaderView*>(custom_frame_view->GetHeaderView());
WideFrameView* wide_frame_view = WideFrameView::Create(widget.get());
HeaderView* wide_header_view = wide_frame_view->header_view();
display::Screen* screen = display::Screen::GetScreen();
const gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
gfx::Rect frame_bounds =
wide_frame_view->GetWidget()->GetWindowBoundsInScreen();
EXPECT_EQ(work_area.width(), frame_bounds.width());
EXPECT_EQ(work_area.origin(), frame_bounds.origin());
EXPECT_FALSE(header_view->should_paint());
EXPECT_TRUE(wide_header_view->should_paint());
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_FALSE(wide_header_view->should_paint());
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_TRUE(wide_header_view->should_paint());
// Test immersive.
ImmersiveFullscreenController controller;
wide_frame_view->Init(&controller);
EXPECT_FALSE(wide_header_view->in_immersive_mode());
EXPECT_FALSE(header_view->in_immersive_mode());
controller.SetEnabled(ImmersiveFullscreenController::WINDOW_TYPE_OTHER, true);
EXPECT_TRUE(header_view->in_immersive_mode());
EXPECT_TRUE(wide_header_view->in_immersive_mode());
// The height should be ~(33 *.5)
wide_header_view->SetVisibleFraction(0.5);
EXPECT_NEAR(16, wide_header_view->GetPreferredOnScreenHeight(), 1);
controller.SetEnabled(ImmersiveFullscreenController::WINDOW_TYPE_OTHER,
false);
EXPECT_FALSE(header_view->in_immersive_mode());
EXPECT_FALSE(wide_header_view->in_immersive_mode());
// visible fraction should be ignored in non immersive.
wide_header_view->SetVisibleFraction(0.5);
EXPECT_EQ(33, wide_header_view->GetPreferredOnScreenHeight());
UpdateDisplay("1234x800");
EXPECT_EQ(1234,
wide_frame_view->GetWidget()->GetWindowBoundsInScreen().width());
}
namespace { namespace {
class CustomFrameViewAshFrameColorTest class CustomFrameViewAshFrameColorTest
......
...@@ -102,7 +102,6 @@ class ASH_EXPORT HeaderView : public views::View, ...@@ -102,7 +102,6 @@ class ASH_EXPORT HeaderView : public views::View,
FrameCaptionButton* GetBackButton(); FrameCaptionButton* GetBackButton();
private:
// ImmersiveFullscreenControllerDelegate: // ImmersiveFullscreenControllerDelegate:
void OnImmersiveRevealStarted() override; void OnImmersiveRevealStarted() override;
void OnImmersiveRevealEnded() override; void OnImmersiveRevealEnded() override;
...@@ -111,6 +110,7 @@ class ASH_EXPORT HeaderView : public views::View, ...@@ -111,6 +110,7 @@ class ASH_EXPORT HeaderView : public views::View,
void SetVisibleFraction(double visible_fraction) override; void SetVisibleFraction(double visible_fraction) override;
std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override; std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override;
private:
// The widget that the caption buttons act on. // The widget that the caption buttons act on.
views::Widget* target_widget_; views::Widget* target_widget_;
......
// Copyright 2018 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 "ash/frame/wide_frame_view.h"
#include "ash/ash_layout_constants.h"
#include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
#include "ash/frame/custom_frame_view_ash.h"
#include "ash/frame/header_view.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller.h"
#include "ash/public/cpp/window_properties.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/widget/widget.h"
namespace ash {
// static
WideFrameView* WideFrameView::Create(views::Widget* target) {
auto* widget = new views::Widget;
WideFrameView* frame_view = new WideFrameView(target, widget);
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_POPUP;
params.delegate = frame_view;
params.bounds = GetFrameBounds(target);
params.name = "WideFrameView";
params.parent = target->GetNativeWindow();
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
widget->Init(params);
return frame_view;
}
// static
gfx::Rect WideFrameView::GetFrameBounds(views::Widget* target) {
static const int kFrameHeight =
GetAshLayoutSize(AshLayoutSize::kNonBrowserCaption).height();
display::Screen* screen = display::Screen::GetScreen();
aura::Window* target_window = target->GetNativeWindow();
gfx::Rect bounds =
target->IsFullscreen()
? screen->GetDisplayNearestWindow(target_window).bounds()
: screen->GetDisplayNearestWindow(target_window).work_area();
bounds.set_height(kFrameHeight);
return bounds;
}
void WideFrameView::Init(ImmersiveFullscreenController* controller) {
DCHECK(target_);
controller->Init(this, target_, header_view_);
}
void WideFrameView::Show() {
widget_->Show();
}
void WideFrameView::Close() {
widget_->Close();
}
void WideFrameView::SetCaptionButtonModel(
std::unique_ptr<CaptionButtonModel> model) {
header_view_->caption_button_container()->SetModel(std::move(model));
header_view_->UpdateCaptionButtons();
}
WideFrameView::WideFrameView(views::Widget* target, views::Widget* widget)
: target_(target), widget_(widget) {
Shell::Get()->AddShellObserver(this);
display::Screen::GetScreen()->AddObserver(this);
aura::Window* target_window = target->GetNativeWindow();
target_window->AddObserver(this);
SkColor active = target_window->GetProperty(kFrameActiveColorKey);
SkColor inactive = target_window->GetProperty(kFrameInactiveColorKey);
header_view_ = new HeaderView(target);
AddChildView(header_view_);
header_view_->SetFrameColors(active, inactive);
GetTargetHeaderView()->SetShouldPaintHeader(false);
}
WideFrameView::~WideFrameView() {
Shell::Get()->RemoveShellObserver(this);
display::Screen::GetScreen()->RemoveObserver(this);
if (target_) {
GetTargetHeaderView()->SetShouldPaintHeader(true);
target_->GetNativeWindow()->RemoveObserver(this);
}
}
void WideFrameView::Layout() {
int onscreen_height = header_view_->GetPreferredOnScreenHeight();
if (onscreen_height == 0 || !visible()) {
header_view_->SetVisible(false);
} else {
const int height = header_view_->GetPreferredHeight();
header_view_->SetBounds(0, onscreen_height - height, width(), height);
header_view_->SetVisible(true);
}
}
void WideFrameView::OnWindowDestroying(aura::Window* window) {
window->RemoveObserver(this);
target_ = nullptr;
}
void WideFrameView::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) {
display::Screen* screen = display::Screen::GetScreen();
if (screen->GetDisplayNearestWindow(target_->GetNativeWindow()).id() !=
display.id()) {
return;
}
DCHECK(target_);
GetWidget()->SetBounds(GetFrameBounds(target_));
}
void WideFrameView::OnImmersiveRevealStarted() {
header_view_->OnImmersiveRevealStarted();
}
void WideFrameView::OnImmersiveRevealEnded() {
header_view_->OnImmersiveRevealEnded();
}
void WideFrameView::OnImmersiveFullscreenEntered() {
header_view_->OnImmersiveFullscreenEntered();
if (target_)
GetTargetHeaderView()->OnImmersiveFullscreenEntered();
}
void WideFrameView::OnImmersiveFullscreenExited() {
header_view_->OnImmersiveFullscreenExited();
if (target_)
GetTargetHeaderView()->OnImmersiveFullscreenExited();
}
void WideFrameView::SetVisibleFraction(double visible_fraction) {
header_view_->SetVisibleFraction(visible_fraction);
}
std::vector<gfx::Rect> WideFrameView::GetVisibleBoundsInScreen() const {
return header_view_->GetVisibleBoundsInScreen();
}
void WideFrameView::OnOverviewModeStarting() {
header_view_->SetShouldPaintHeader(false);
}
void WideFrameView::OnOverviewModeEnded() {
header_view_->SetShouldPaintHeader(true);
}
HeaderView* WideFrameView::GetTargetHeaderView() {
auto* frame_view = static_cast<CustomFrameViewAsh*>(
target_->non_client_view()->frame_view());
return static_cast<HeaderView*>(frame_view->GetHeaderView());
}
} // namespace ash
// Copyright 2018 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 ASH_FRAME_WIDE_FRAME_VIEW_H_
#define ASH_FRAME_WIDE_FRAME_VIEW_H_
#include "ash/ash_export.h"
#include "ash/frame/caption_buttons/caption_button_model.h"
#include "ash/public/cpp/immersive/immersive_fullscreen_controller_delegate.h"
#include "ash/shell.h"
#include "ash/shell_observer.h"
#include "ui/aura/window_observer.h"
#include "ui/display/display_observer.h"
#include "ui/views/widget/widget_delegate.h"
namespace views {
class Widget;
}
namespace ash {
class HeaderView;
class ImmersiveFullscreenController;
// WideFrameView is used for the case where the widget's
// maximzed/fullscreen doesn't cover the entire workarea/display area
// but the caption frame should occupy the full width and placed at the top
// of the display.
// TODO(oshima): Currently client is responsible for hooking this up to
// the target widget because ImmersiveFullscreenController is not owned by
// CustomFrameViewAsh. Investigate if we integrate this into
// CustomFrameViewAsh.
class ASH_EXPORT WideFrameView
: public views::WidgetDelegateView,
public aura::WindowObserver,
public display::DisplayObserver,
public ash::ImmersiveFullscreenControllerDelegate,
public ash::ShellObserver {
public:
// Creates wide frame for |target| widget. It's caller's responsibility
// to Close when the wide frame is no longer necessary.
static WideFrameView* Create(views::Widget* target);
// Initialize |immersive_fullscreen_controller| so that the controller reveals
// and |hides_header_| in immersive mode.
void Init(ash::ImmersiveFullscreenController* controller);
// Show/Closes the frame.
void Show();
void Close();
// Set the caption model for caption buttions on this frame.
void SetCaptionButtonModel(std::unique_ptr<ash::CaptionButtonModel> mode);
ash::HeaderView* header_view() { return header_view_; }
private:
static gfx::Rect GetFrameBounds(views::Widget* target);
WideFrameView(views::Widget* target, views::Widget* frame_widget);
~WideFrameView() override;
// views::View:
void Layout() override;
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
// display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
// ash::ImmersiveFullscreenControllerDelegate:
void OnImmersiveRevealStarted() override;
void OnImmersiveRevealEnded() override;
void OnImmersiveFullscreenEntered() override;
void OnImmersiveFullscreenExited() override;
void SetVisibleFraction(double visible_fraction) override;
std::vector<gfx::Rect> GetVisibleBoundsInScreen() const override;
// ash::ShellObserver:
void OnOverviewModeStarting() override;
void OnOverviewModeEnded() override;
ash::HeaderView* GetTargetHeaderView();
// The target widget this frame will control.
views::Widget* target_;
// The widget that hosts the wide frame.
views::Widget* widget_;
ash::HeaderView* header_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(WideFrameView);
};
} // namespace ash
#endif // ASH_FRAME_WIDE_FRAME_VIEW_H_
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "ash/public/cpp/immersive/immersive_gesture_handler.h" #include "ash/public/cpp/immersive/immersive_gesture_handler.h"
#include "ash/public/cpp/immersive/immersive_handler_factory.h" #include "ash/public/cpp/immersive/immersive_handler_factory.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "ui/aura/window.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/events/base_event_utils.h" #include "ui/events/base_event_utils.h"
...@@ -326,6 +327,11 @@ void ImmersiveFullscreenController::EnableWindowObservers(bool enable) { ...@@ -326,6 +327,11 @@ void ImmersiveFullscreenController::EnableWindowObservers(bool enable) {
} }
} }
bool ImmersiveFullscreenController::IsTargetForWidget(
views::Widget* target) const {
return target == widget_ || target == top_container_->GetWidget();
}
void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer( void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer(
const ui::MouseEvent& event, const ui::MouseEvent& event,
const gfx::Point& location_in_screen, const gfx::Point& location_in_screen,
...@@ -337,9 +343,8 @@ void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer( ...@@ -337,9 +343,8 @@ void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer(
// activation. This allows the timer to be started when |widget_| is inactive // activation. This allows the timer to be started when |widget_| is inactive
// but prevents starting the timer if the mouse is over a portion of the top // but prevents starting the timer if the mouse is over a portion of the top
// edge obscured by an unrelated widget. // edge obscured by an unrelated widget.
if (!top_edge_hover_timer_.IsRunning() && target != widget_) { if (!top_edge_hover_timer_.IsRunning() && !IsTargetForWidget(target))
return; return;
}
// Mouse hover should not initiate revealing the top-of-window views while a // Mouse hover should not initiate revealing the top-of-window views while a
// window has mouse capture. // window has mouse capture.
......
...@@ -222,6 +222,9 @@ class ASH_PUBLIC_EXPORT ImmersiveFullscreenController ...@@ -222,6 +222,9 @@ class ASH_PUBLIC_EXPORT ImmersiveFullscreenController
// Returns the display bounds of the screen |widget_| is on. // Returns the display bounds of the screen |widget_| is on.
gfx::Rect GetDisplayBoundsInScreen() const; gfx::Rect GetDisplayBoundsInScreen() const;
// Test if the |widget| is the event target to control reveal state.
bool IsTargetForWidget(views::Widget* widget) const;
// Not owned. // Not owned.
ImmersiveFullscreenControllerDelegate* delegate_; ImmersiveFullscreenControllerDelegate* delegate_;
views::View* top_container_; views::View* top_container_;
......
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