Commit d6fbcd08 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

overview: Aspect ratio calculated properly for portrait and dragging.

Before:
https://screenshot.googleplex.com/FJyL5zborbs
https://screenshot.googleplex.com/ADhhbeZN1Ee
After:
https://screenshot.googleplex.com/ef9cyxjNxQQ
https://screenshot.googleplex.com/c6MGGiOOhFv

The real change is from Base -> PS1. After that, most of the change is
moving a function from private to public to expose it.

Test: manual
Bug: 1011973
Change-Id: I7bb2aab1440a8c1e8db16c81ea2b038b1481db6e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1872761
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708238}
parent 267d0adc
...@@ -1490,6 +1490,96 @@ void OverviewGrid::EndScroll() { ...@@ -1490,6 +1490,96 @@ void OverviewGrid::EndScroll() {
PositionWindows(/*animate=*/false); PositionWindows(/*animate=*/false);
} }
int OverviewGrid::CalculateWidthAndMaybeSetUnclippedBounds(OverviewItem* item,
int height) {
const gfx::Size item_size(0, height);
gfx::RectF target_bounds = item->GetTargetBoundsInScreen();
float scale = item->GetItemScale(item_size);
// The drop target, unlike the other windows has its bounds set directly, so
// |GetTargetBoundsInScreen()| won't return the value we want. Instead, get
// the scale from the window it was meant to be a placeholder for.
if (IsDropTargetWindow(item->GetWindow())) {
aura::Window* dragged_window = nullptr;
OverviewItem* item =
overview_session_->window_drag_controller()
? overview_session_->window_drag_controller()->item()
: nullptr;
if (item)
dragged_window = item->GetWindow();
else if (dragged_window_)
dragged_window = dragged_window_;
if (dragged_window && dragged_window->parent()) {
target_bounds = ::ash::GetTargetBoundsInScreen(dragged_window);
const gfx::SizeF inset_size(0, height - 2 * kWindowMargin);
scale = ScopedOverviewTransformWindow::GetItemScale(
target_bounds.size(), inset_size,
dragged_window->GetProperty(aura::client::kTopViewInset),
kHeaderHeightDp);
}
}
int width = std::max(
1, gfx::ToFlooredInt(target_bounds.width() * scale) + 2 * kWindowMargin);
switch (item->GetWindowDimensionsType()) {
case ScopedOverviewTransformWindow::GridWindowFillMode::kLetterBoxed:
width =
ScopedOverviewTransformWindow::kExtremeWindowRatioThreshold * height;
break;
case ScopedOverviewTransformWindow::GridWindowFillMode::kPillarBoxed:
width =
height / ScopedOverviewTransformWindow::kExtremeWindowRatioThreshold;
break;
default:
break;
}
// Get the bounds of the window if there is a snapped window or a window
// about to be snapped.
base::Optional<gfx::RectF> split_view_bounds =
GetSplitviewBoundsMaintainingAspectRatio(item->GetWindow());
if (!split_view_bounds) {
item->set_unclipped_size(base::nullopt);
return width;
}
const bool is_landscape = IsCurrentScreenOrientationLandscape();
gfx::Size unclipped_size;
if (is_landscape) {
unclipped_size.set_width(width - 2 * kWindowMargin);
unclipped_size.set_height(height - 2 * kWindowMargin);
// For landscape mode, shrink |width| so that the aspect ratio matches
// that of |split_view_bounds|.
width = std::max(1, gfx::ToFlooredInt(split_view_bounds->width() * scale) +
2 * kWindowMargin);
} else {
// For portrait mode, we want |height| to stay the same, so calculate
// what the unclipped height would be based on |split_view_bounds|.
// Find the width so that it matches height and matches the aspect ratio of
// |split_view_bounds|. |height| includes the margins and overview header,
// so exclude those from the calculation.
width = (split_view_bounds->width() *
(height - 2 * kWindowMargin - kHeaderHeightDp) /
split_view_bounds->height());
// The unclipped height is the height which matches |width| but keeps the
// aspect ratio of |target_bounds|. Clipping takes the overview header into
// account, so add that back in.
const int unclipped_height =
width * target_bounds.height() / target_bounds.width();
unclipped_size.set_width(width);
unclipped_size.set_height(unclipped_height + kHeaderHeightDp);
// Add some space between this item and the next one (if it exists).
width += (2 * kWindowMargin);
}
DCHECK(!unclipped_size.IsEmpty());
item->set_unclipped_size(base::make_optional(unclipped_size));
return width;
}
void OverviewGrid::MaybeInitDesksWidget() { void OverviewGrid::MaybeInitDesksWidget() {
if (!desks_util::ShouldDesksBarBeCreated() || desks_widget_) if (!desks_util::ShouldDesksBarBeCreated() || desks_widget_)
return; return;
...@@ -1798,82 +1888,4 @@ void OverviewGrid::AddDraggedWindowIntoOverviewOnDragEnd( ...@@ -1798,82 +1888,4 @@ void OverviewGrid::AddDraggedWindowIntoOverviewOnDragEnd(
/*animate=*/false); /*animate=*/false);
} }
int OverviewGrid::CalculateWidthAndMaybeSetUnclippedBounds(OverviewItem* item,
int height) {
const gfx::Size item_size(0, height);
gfx::RectF target_bounds = item->GetTargetBoundsInScreen();
float scale = item->GetItemScale(item_size);
// The drop target, unlike the other windows has its bounds set directly, so
// |GetTargetBoundsInScreen()| won't return the value we want. Instead, get
// the scale from the window it was meant to be a placeholder for.
if (IsDropTargetWindow(item->GetWindow())) {
aura::Window* dragged_window = nullptr;
OverviewItem* item =
overview_session_->window_drag_controller()
? overview_session_->window_drag_controller()->item()
: nullptr;
if (item)
dragged_window = item->GetWindow();
else if (dragged_window_)
dragged_window = dragged_window_;
if (dragged_window && dragged_window->parent()) {
target_bounds = ::ash::GetTargetBoundsInScreen(dragged_window);
const gfx::SizeF inset_size(0, height - 2 * kWindowMargin);
scale = ScopedOverviewTransformWindow::GetItemScale(
target_bounds.size(), inset_size,
dragged_window->GetProperty(aura::client::kTopViewInset),
kHeaderHeightDp);
}
}
int width = std::max(
1, gfx::ToFlooredInt(target_bounds.width() * scale) + 2 * kWindowMargin);
switch (item->GetWindowDimensionsType()) {
case ScopedOverviewTransformWindow::GridWindowFillMode::kLetterBoxed:
width =
ScopedOverviewTransformWindow::kExtremeWindowRatioThreshold * height;
break;
case ScopedOverviewTransformWindow::GridWindowFillMode::kPillarBoxed:
width =
height / ScopedOverviewTransformWindow::kExtremeWindowRatioThreshold;
break;
default:
break;
}
// Get the bounds of the window if there is a snapped window or a window
// about to be snapped.
base::Optional<gfx::RectF> split_view_bounds =
GetSplitviewBoundsMaintainingAspectRatio(item->GetWindow());
if (!split_view_bounds) {
item->set_unclipped_size(base::nullopt);
return width;
}
const bool is_landscape = IsCurrentScreenOrientationLandscape();
gfx::Size unclipped_size;
if (is_landscape) {
unclipped_size.set_width(width - 2 * kWindowMargin);
unclipped_size.set_height(height - 2 * kWindowMargin);
// For landscape mode, shrink |width| so that the aspect ratio matches
// that of |split_view_bounds|.
width = std::max(1, gfx::ToFlooredInt(split_view_bounds->width() * scale) +
2 * kWindowMargin);
} else {
// For portrait mode, we want |height| to stay the same, so calculate
// what the unclipped height would be based on |split_view_bounds|.
width = split_view_bounds->width() * height / split_view_bounds->height();
int unclipped_height =
(target_bounds.height() * width) / target_bounds.width();
unclipped_size.set_width(width);
unclipped_size.set_height(unclipped_height);
}
DCHECK(!unclipped_size.IsEmpty());
item->set_unclipped_size(base::make_optional(unclipped_size));
return width;
}
} // namespace ash } // namespace ash
...@@ -297,6 +297,12 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver, ...@@ -297,6 +297,12 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver,
void EndScroll(); void EndScroll();
// Calculate the width of an item based on |height|. The width tries to keep
// the same aspect ratio as the original window, but may be modified if the
// bounds of the window are considered extreme, or if the window is in
// splitview or entering splitview.
int CalculateWidthAndMaybeSetUnclippedBounds(OverviewItem* item, int height);
// Returns true if the grid has no more windows. // Returns true if the grid has no more windows.
bool empty() const { return window_list_.empty(); } bool empty() const { return window_list_.empty(); }
...@@ -396,12 +402,6 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver, ...@@ -396,12 +402,6 @@ class ASH_EXPORT OverviewGrid : public SplitViewObserver,
// the window's bounds if it has been resized. // the window's bounds if it has been resized.
void AddDraggedWindowIntoOverviewOnDragEnd(aura::Window* dragged_window); void AddDraggedWindowIntoOverviewOnDragEnd(aura::Window* dragged_window);
// Calculate the width of an item based on |height|. The width tries to keep
// the same aspect ratio as the original window, but may be modified if the
// bounds of the window are considered extreme, or if the window is in
// splitview or entering splitview.
int CalculateWidthAndMaybeSetUnclippedBounds(OverviewItem* item, int height);
// Root window the grid is in. // Root window the grid is in.
aura::Window* root_window_; aura::Window* root_window_;
......
...@@ -639,6 +639,17 @@ void OverviewItem::ScaleUpSelectedItem(OverviewAnimationType animation_type) { ...@@ -639,6 +639,17 @@ void OverviewItem::ScaleUpSelectedItem(OverviewAnimationType animation_type) {
gfx::RectF scaled_bounds = target_bounds(); gfx::RectF scaled_bounds = target_bounds();
scaled_bounds.Inset(-scaled_bounds.width() * kDragWindowScale, scaled_bounds.Inset(-scaled_bounds.width() * kDragWindowScale,
-scaled_bounds.height() * kDragWindowScale); -scaled_bounds.height() * kDragWindowScale);
if (unclipped_size_) {
// If a clipped item is scaled up, we need to recalculate the unclipped
// size.
const int height = scaled_bounds.height();
const int width =
overview_grid_->CalculateWidthAndMaybeSetUnclippedBounds(this, height);
DCHECK(unclipped_size_);
const gfx::SizeF new_size(width, height);
scaled_bounds.set_size(new_size);
scaled_bounds.ClampToCenteredSize(new_size);
}
SetBounds(scaled_bounds, animation_type); SetBounds(scaled_bounds, animation_type);
} }
......
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