-
Notifications
You must be signed in to change notification settings - Fork 16.5k
feat: customize border radius of Views #42320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8ef03a3
c21bd9d
b816f1d
e7f2f42
81801f6
ce97b90
f31cb08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
#include <string> | ||
#include <utility> | ||
|
||
#include "ash/style/rounded_rect_cutout_path_builder.h" | ||
#include "gin/data_object_builder.h" | ||
#include "gin/wrappable.h" | ||
#include "shell/browser/javascript_environment.h" | ||
|
@@ -338,13 +339,46 @@ void View::SetBackgroundColor(std::optional<WrappedSkColor> color) { | |
view_->SetBackground(color ? views::CreateSolidBackground(*color) : nullptr); | ||
} | ||
|
||
void View::SetBorderRadius(int radius) { | ||
border_radius_ = radius; | ||
ApplyBorderRadius(); | ||
} | ||
|
||
void View::ApplyBorderRadius() { | ||
if (!border_radius_.has_value() || !view_) | ||
return; | ||
|
||
auto size = view_->bounds().size(); | ||
|
||
// Restrict border radius to the constraints set in the path builder class. | ||
// If the constraints are exceeded, the builder will crash. | ||
int radius; | ||
{ | ||
float r = border_radius_.value() * 1.f; | ||
r = std::min(r, size.width() / 2.f); | ||
r = std::min(r, size.height() / 2.f); | ||
r = std::max(r, 0.f); | ||
radius = std::floor(r); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to upstream a CL to make |
||
|
||
// RoundedRectCutoutPathBuilder has a minimum size of 32 x 32. | ||
if (radius > 0 && size.width() >= 32 && size.height() >= 32) { | ||
auto builder = ash::RoundedRectCutoutPathBuilder(gfx::SizeF(size)); | ||
builder.CornerRadius(radius); | ||
view_->SetClipPath(builder.Build()); | ||
} else { | ||
view_->SetClipPath(SkPath()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any chance we could expose SetClipPath more directly? I'd generally like to err on the side of power over ease of use in the Views API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The difficulty here is that the native views use a different code path for faster clipping Arguably the WebContentsView border radius is the dominant use case. The clipping for the underlying View allows us to also clip the background color. edit: to elaborate, this fast path goes down to the renderer level which has special masking for rounded corners. See skia_renderer.cc and search for "rounded" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, afaict this code here doesn't use the fast path, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This results in two implementations of
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we feel strongly about exposing a more powerful Are we comfortable unblocking this? @nornagon @electron/wg-api There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough! I'll unblock this. |
||
} | ||
} | ||
|
||
void View::SetVisible(bool visible) { | ||
if (!view_) | ||
return; | ||
view_->SetVisible(visible); | ||
} | ||
|
||
void View::OnViewBoundsChanged(views::View* observed_view) { | ||
ApplyBorderRadius(); | ||
Emit("bounds-changed"); | ||
} | ||
|
||
|
@@ -393,6 +427,7 @@ void View::BuildPrototype(v8::Isolate* isolate, | |
.SetMethod("setBounds", &View::SetBounds) | ||
.SetMethod("getBounds", &View::GetBounds) | ||
.SetMethod("setBackgroundColor", &View::SetBackgroundColor) | ||
.SetMethod("setBorderRadius", &View::SetBorderRadius) | ||
.SetMethod("setLayout", &View::SetLayout) | ||
.SetMethod("setVisible", &View::SetVisible); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't imagine this would be too difficult to fix, but I'd rather do this in a future PR if a need arises.