Commit abd491f7 authored by Thomas Lukaszewicz's avatar Thomas Lukaszewicz Committed by Commit Bot

Views: Small refactoring of rounded corners logic

This CL introduces a GetCornerRadius() helper to the DialogDelegate
and a GetClientCornerRadii() helper to the BubbleFrameView. This will
help when implementing the rounded corners fast path for MD rounded
corners in a follow-up CL.

Bug: 822075
Change-Id: Ia90c56b0ba6d58d682bc9c14bae688c247d612d8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2359022
Commit-Queue: Thomas Lukaszewicz <tluk@chromium.org>
Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798665}
parent 4ba24db2
......@@ -378,12 +378,8 @@ BubbleDialogDelegate::CreateNonClientFrameView(Widget* widget) {
std::unique_ptr<BubbleBorder> border =
std::make_unique<BubbleBorder>(arrow(), GetShadow(), color());
if (CustomShadowsSupported() && GetParams().round_corners) {
border->SetCornerRadius(
base::FeatureList::IsEnabled(features::kEnableMDRoundedCornersOnDialogs)
? provider->GetCornerRadiusMetric(views::EMPHASIS_MEDIUM)
: 2);
}
if (CustomShadowsSupported() && GetParams().round_corners)
border->SetCornerRadius(GetCornerRadius());
frame->SetBubbleBorder(std::move(border));
return frame;
......
......@@ -19,6 +19,7 @@
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/rounded_corners_f.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/skia_util.h"
#include "ui/native_theme/native_theme.h"
......@@ -184,29 +185,19 @@ bool BubbleFrameView::GetClientMask(const gfx::Size& size, SkPath* path) const {
DCHECK_EQ(GetBoundsForClientView().size(), size);
DCHECK_EQ(GetWidget()->client_view()->size(), size);
const int radius = bubble_border_->corner_radius();
const gfx::Insets insets =
GetClientInsetsForFrameWidth(GetContentsBounds().width());
const gfx::RoundedCornersF corner_radii = GetClientCornerRadii();
// A mask is not needed if the content does not overlap the rounded corners.
if ((insets.top() > radius && insets.bottom() > radius) ||
(insets.left() > radius && insets.right() > radius)) {
// If corner radii are all zero we do not need to apply a mask.
if (corner_radii.IsEmpty())
return false;
}
// We want to clip the client view to a rounded rect that's consistent with
// the bubble's rounded border. However, if there is a header, the top of the
// client view should be straight and flush with that. Likewise, if there is
// a footer, the client view should be straight and flush with that. Therefore
// we set the corner radii separately for top and bottom.
const SkRect rect = SkRect::MakeIWH(size.width(), size.height());
const SkScalar top_radius = header_view_ ? 0.0f : radius;
const SkScalar bottom_radius = footnote_container_ ? 0.0f : radius;
// Format is upper-left x, upper-left y, upper-right x, and so forth,
// clockwise around the boundary.
SkScalar radii[]{top_radius, top_radius, top_radius, top_radius,
bottom_radius, bottom_radius, bottom_radius, bottom_radius};
path->addRoundRect(rect, radii);
SkScalar radii[]{corner_radii.upper_left(), corner_radii.upper_left(),
corner_radii.upper_right(), corner_radii.upper_right(),
corner_radii.lower_right(), corner_radii.lower_right(),
corner_radii.lower_left(), corner_radii.lower_left()};
path->addRoundRect(SkRect::MakeIWH(size.width(), size.height()), radii);
return true;
}
......@@ -664,6 +655,34 @@ gfx::Rect BubbleFrameView::GetCloseButtonMirroredBounds() const {
return close_->GetMirroredBounds();
}
gfx::RoundedCornersF BubbleFrameView::GetClientCornerRadii() const {
DCHECK(bubble_border_);
const int radius = bubble_border_->corner_radius();
const gfx::Insets insets =
GetClientInsetsForFrameWidth(GetContentsBounds().width());
// Rounded corners do not need to be applied to the client view if the client
// view is sufficiently inset such that its unclipped bounds will not
// intersect with the corners of the containing bubble frame view.
if ((insets.top() > radius && insets.bottom() > radius) ||
(insets.left() > radius && insets.right() > radius)) {
return gfx::RoundedCornersF();
}
// We want to clip the client view to a rounded rect that's consistent with
// the bubble's rounded border. However, if there is a header, the top of the
// client view should be straight and flush with that. Likewise, if there is
// a footer, the client view should be straight and flush with that. Therefore
// we set the corner radii separately for top and bottom.
gfx::RoundedCornersF corner_radii;
corner_radii.set_upper_left(header_view_ ? 0 : radius);
corner_radii.set_upper_right(header_view_ ? 0 : radius);
corner_radii.set_lower_left(footnote_container_ ? 0 : radius);
corner_radii.set_lower_right(footnote_container_ ? 0 : radius);
return corner_radii;
}
void BubbleFrameView::MirrorArrowIfOutOfBounds(
bool vertical,
const gfx::Rect& anchor_rect,
......
......@@ -20,6 +20,10 @@
#include "ui/views/input_event_activation_protector.h"
#include "ui/views/window/non_client_view.h"
namespace gfx {
class RoundedCornersF;
}
namespace views {
class FootnoteContainerView;
......@@ -179,6 +183,12 @@ class VIEWS_EXPORT BubbleFrameView : public NonClientFrameView,
bool IsCloseButtonVisible() const;
gfx::Rect GetCloseButtonMirroredBounds() const;
// Helper function that gives the corner radius values that should be applied
// to the BubbleFrameView's client view. These values depend on the amount of
// inset present on the client view and the presence of header and footer
// views.
gfx::RoundedCornersF GetClientCornerRadii() const;
BubbleBorder* bubble_border_for_testing() const { return bubble_border_; }
private:
......
......@@ -233,13 +233,8 @@ std::unique_ptr<NonClientFrameView> DialogDelegate::CreateDialogFrameView(
border->set_use_theme_background_color(true);
DialogDelegate* delegate = widget->widget_delegate()->AsDialogDelegate();
if (delegate) {
if (delegate->GetParams().round_corners) {
border->SetCornerRadius(
base::FeatureList::IsEnabled(
features::kEnableMDRoundedCornersOnDialogs)
? provider->GetCornerRadiusMetric(views::EMPHASIS_MEDIUM)
: 2);
}
if (delegate->GetParams().round_corners)
border->SetCornerRadius(delegate->GetCornerRadius());
frame->SetFootnoteView(delegate->DisownFootnoteView());
}
frame->SetBubbleBorder(std::move(border));
......@@ -411,6 +406,14 @@ ax::mojom::Role DialogDelegate::GetAccessibleWindowRole() {
return ax::mojom::Role::kDialog;
}
int DialogDelegate::GetCornerRadius() const {
return base::FeatureList::IsEnabled(
features::kEnableMDRoundedCornersOnDialogs)
? LayoutProvider::Get()->GetCornerRadiusMetric(
views::EMPHASIS_MEDIUM)
: 2;
}
std::unique_ptr<View> DialogDelegate::DisownFootnoteView() {
return std::move(footnote_view_);
}
......
......@@ -285,6 +285,8 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate {
const Params& GetParams() const { return params_; }
int GetCornerRadius() const;
// Return ownership of the footnote view for this dialog. Only use this in
// subclass overrides of CreateNonClientFrameView.
std::unique_ptr<View> DisownFootnoteView();
......
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