Commit 7044fb57 authored by Jennifer Apacible's avatar Jennifer Apacible Committed by Commit Bot

[Widget] Implement SetAspectRatio for CrOS.

For ChromeOS, ash (window manager), will handle adjusting the window
size to adhere to the specified aspect ratio.

This change adds a new aura constant to keep track of the window's
aspect ratio, if any. This is used in WindowResizer to determine the new
window bounds.

Bug: 853276
Change-Id: I4c7eaa6252e26ffccf3ac10a4dafd635a3b556d1
Reviewed-on: https://chromium-review.googlesource.com/1164483
Commit-Queue: apacible <apacible@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582010}
parent 36fcc8ac
......@@ -1913,6 +1913,7 @@ test("ash_unittests") {
"wm/ash_focus_rules_unittest.cc",
"wm/client_controlled_state_unittest.cc",
"wm/container_finder_unittest.cc",
"wm/default_window_resizer_unittest.cc",
"wm/drag_window_resizer_unittest.cc",
"wm/fullscreen_window_finder_unittest.cc",
"wm/gestures/overview_gesture_handler_unittest.cc",
......
// 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/wm/default_window_resizer.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_types.h"
namespace ash {
class DefaultWindowResizerTest : public AshTestBase {
public:
DefaultWindowResizerTest() = default;
~DefaultWindowResizerTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
UpdateDisplay("1000x1000");
delegate_.set_minimum_size(gfx::Size(10, 10));
delegate_.set_maximum_size(gfx::Size(500, 500));
aspect_ratio_window_ = std::make_unique<aura::Window>(&delegate_);
aspect_ratio_window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
aspect_ratio_window_->Init(ui::LAYER_NOT_DRAWN);
ParentWindowInPrimaryRootWindow(aspect_ratio_window_.get());
}
void TearDown() override {
aspect_ratio_window_.reset();
AshTestBase::TearDown();
}
protected:
static WindowResizer* CreateDefaultWindowResizer(
aura::Window* window,
const gfx::Point& point_in_parent,
int window_component) {
return CreateWindowResizer(window, point_in_parent, window_component,
::wm::WINDOW_MOVE_SOURCE_MOUSE)
.release();
}
aura::test::TestWindowDelegate delegate_;
std::unique_ptr<aura::Window> aspect_ratio_window_;
private:
DISALLOW_COPY_AND_ASSIGN(DefaultWindowResizerTest);
};
// Tests window dragging with a square aspect ratio.
TEST_F(DefaultWindowResizerTest, WindowResizeWithAspectRatioSquare) {
aspect_ratio_window_->SetProperty(aura::client::kAspectRatio,
new gfx::SizeF(1.0, 1.0));
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
ASSERT_EQ(1U, root_windows.size());
EXPECT_EQ(root_windows[0], aspect_ratio_window_->GetRootWindow());
aspect_ratio_window_->SetBoundsInScreen(
gfx::Rect(200, 200, 200, 200),
display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]));
EXPECT_EQ("200,200 200x200", aspect_ratio_window_->bounds().ToString());
std::unique_ptr<WindowResizer> resizer(CreateDefaultWindowResizer(
aspect_ratio_window_.get(), gfx::Point(), HTTOPLEFT));
ASSERT_TRUE(resizer.get());
// Move the mouse near the top left edge.
resizer->Drag(gfx::Point(50, 50), 0);
resizer->CompleteDrag();
EXPECT_EQ(root_windows[0], aspect_ratio_window_->GetRootWindow());
EXPECT_EQ("250,250 150x150", aspect_ratio_window_->bounds().ToString());
}
// Tests window dragging with a horizontal orientation aspect ratio.
TEST_F(DefaultWindowResizerTest, WindowResizeWithAspectRatioHorizontal) {
aspect_ratio_window_->SetProperty(aura::client::kAspectRatio,
new gfx::SizeF(2.0, 1.0));
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
ASSERT_EQ(1U, root_windows.size());
EXPECT_EQ(root_windows[0], aspect_ratio_window_->GetRootWindow());
aspect_ratio_window_->SetBoundsInScreen(
gfx::Rect(200, 200, 400, 200),
display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]));
EXPECT_EQ("200,200 400x200", aspect_ratio_window_->bounds().ToString());
std::unique_ptr<WindowResizer> resizer(CreateDefaultWindowResizer(
aspect_ratio_window_.get(), gfx::Point(), HTBOTTOMRIGHT));
ASSERT_TRUE(resizer.get());
// Move the mouse near the top left edge.
resizer->Drag(gfx::Point(50, 50), 0);
resizer->CompleteDrag();
EXPECT_EQ(root_windows[0], aspect_ratio_window_->GetRootWindow());
EXPECT_EQ("200,200 500x250", aspect_ratio_window_->bounds().ToString());
}
// Tests window dragging with a vertical orientation aspect ratio.
TEST_F(DefaultWindowResizerTest, WindowResizeWithAspectRatioVertical) {
aspect_ratio_window_->SetProperty(aura::client::kAspectRatio,
new gfx::SizeF(1.0, 2.0));
aura::Window::Windows root_windows = Shell::GetAllRootWindows();
ASSERT_EQ(1U, root_windows.size());
EXPECT_EQ(root_windows[0], aspect_ratio_window_->GetRootWindow());
aspect_ratio_window_->SetBoundsInScreen(
gfx::Rect(200, 200, 200, 400),
display::Screen::GetScreen()->GetDisplayNearestWindow(root_windows[0]));
EXPECT_EQ("200,200 200x400", aspect_ratio_window_->bounds().ToString());
std::unique_ptr<WindowResizer> resizer(CreateDefaultWindowResizer(
aspect_ratio_window_.get(), gfx::Point(), HTBOTTOM));
ASSERT_TRUE(resizer.get());
// Move the mouse near the top left edge.
resizer->Drag(gfx::Point(50, 50), 0);
resizer->CompleteDrag();
EXPECT_EQ(root_windows[0], aspect_ratio_window_->GetRootWindow());
EXPECT_EQ("200,200 225x450", aspect_ratio_window_->bounds().ToString());
}
} // namespace ash
......@@ -7,6 +7,7 @@
#include "ash/wm/root_window_finder.h"
#include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_state.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
......@@ -14,6 +15,7 @@
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/window/window_resize_utils.h"
#include "ui/wm/core/coordinate_conversion.h"
namespace ash {
......@@ -27,6 +29,31 @@ bool IsRightEdge(int window_component) {
window_component == HTBOTTOMRIGHT || window_component == HTGROWBOX;
}
// Convert |window_component| to the HitTest used in views::WindowResizeUtils.
views::HitTest GetWindowResizeHitTest(int window_component) {
switch (window_component) {
case HTBOTTOM:
return views::HitTest::kBottom;
case HTTOP:
return views::HitTest::kTop;
case HTLEFT:
return views::HitTest::kLeft;
case HTRIGHT:
return views::HitTest::kRight;
case HTTOPLEFT:
return views::HitTest::kTopLeft;
case HTTOPRIGHT:
return views::HitTest::kTopRight;
case HTBOTTOMLEFT:
return views::HitTest::kBottomLeft;
case HTBOTTOMRIGHT:
return views::HitTest::kBottomRight;
default:
NOTREACHED();
return views::HitTest::kBottomRight;
}
}
} // namespace
// static
......@@ -127,6 +154,16 @@ gfx::Rect WindowResizer::CalculateBoundsForDrag(
gfx::Point origin = GetOriginForDrag(delta_x, delta_y);
gfx::Rect new_bounds(origin, size);
gfx::SizeF* aspect_ratio_size =
GetTarget()->GetProperty(aura::client::kAspectRatio);
float aspect_ratio = aspect_ratio_size ? aspect_ratio_size->width() /
aspect_ratio_size->height()
: 0.0;
if (aspect_ratio > 0.0) {
CalculateBoundsWithAspectRatio(aspect_ratio, &new_bounds);
return new_bounds;
}
// Sizing has to keep the result on the screen. Note that this correction
// has to come first since it might have an impact on the origin as well as
// on the size.
......@@ -339,4 +376,22 @@ int WindowResizer::GetHeightForDrag(int min_height, int* delta_y) {
return height;
}
void WindowResizer::CalculateBoundsWithAspectRatio(float aspect_ratio,
gfx::Rect* new_bounds) {
gfx::Size min_size = GetTarget()->delegate()
? GetTarget()->delegate()->GetMinimumSize()
: gfx::Size();
gfx::Size max_size = GetTarget()->delegate()
? GetTarget()->delegate()->GetMaximumSize()
: gfx::Size();
DCHECK(!min_size.IsEmpty());
DCHECK(!max_size.IsEmpty());
views::WindowResizeUtils::SizeMinMaxToAspectRatio(aspect_ratio, &min_size,
&max_size);
views::WindowResizeUtils::SizeRectToAspectRatio(
GetWindowResizeHitTest(details().window_component), aspect_ratio,
min_size, max_size, new_bounds);
}
} // namespace ash
......@@ -95,6 +95,10 @@ class ASH_EXPORT WindowResizer {
// Returns the height of the drag.
int GetHeightForDrag(int min_height, int* delta_y);
// Updates |new_bounds| to adhere to the aspect ratio.
void CalculateBoundsWithAspectRatio(float aspect_ratio,
gfx::Rect* new_bounds);
DISALLOW_COPY_AND_ASSIGN(WindowResizer);
};
......
......@@ -16,6 +16,7 @@ DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, ui::ModalType)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, gfx::ImageSkia*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, gfx::Rect*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, gfx::Size*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, gfx::SizeF*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, std::string*)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, ui::WindowShowState)
DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AURA_EXPORT, ui::mojom::WindowType);
......@@ -43,6 +44,7 @@ DEFINE_UI_CLASS_PROPERTY_KEY(bool, kAlwaysOnTopKey, false);
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kAnimationsDisabledKey, false);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::ImageSkia, kAppIconKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(int, kAppType, 0);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::SizeF, kAspectRatio, nullptr);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::ImageSkia, kAvatarIconKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kConstrainedWindowKey, false);
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kCreatedByUserGesture, false);
......
......@@ -59,6 +59,9 @@ AURA_EXPORT extern const WindowProperty<gfx::ImageSkia*>* const kAppIconKey;
// pointer metrics. See AppType in ash/public/cpp/app_types.h for more details.
AURA_EXPORT extern const WindowProperty<int>* const kAppType;
// A property key to store the aspect ratio of the window.
AURA_EXPORT extern const WindowProperty<gfx::SizeF*>* const kAspectRatio;
// A property key to store the avatar icon that will be displayed on the window
// frame to indicate the owner of the window when needed.
AURA_EXPORT extern const WindowProperty<gfx::ImageSkia*>* const kAvatarIconKey;
......
......@@ -673,6 +673,16 @@ void NativeWidgetAura::SetOpacity(float opacity) {
window_->layer()->SetOpacity(opacity);
}
void NativeWidgetAura::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
DCHECK(!aspect_ratio.IsEmpty());
if (window_) {
// aura::client::kAspectRatio is owned, which allows for passing in this
// raw pointer.
window_->SetProperty(aura::client::kAspectRatio,
new gfx::SizeF(aspect_ratio));
}
}
void NativeWidgetAura::FlashFrame(bool flash) {
if (window_)
window_->SetProperty(aura::client::kDrawAttentionKey, flash);
......
......@@ -125,7 +125,7 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
void SetFullscreen(bool fullscreen) override;
bool IsFullscreen() const override;
void SetOpacity(float opacity) override;
void SetAspectRatio(const gfx::SizeF& aspect_ratio) override {}
void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
void FlashFrame(bool flash_frame) override;
void RunShellDrag(View* view,
const ui::OSExchangeData& data,
......
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