gpui: Add linear gradient support to fill background (#20812)

Release Notes:

- gpui: Add linear gradient support to fill background

Run example:

```
cargo run -p gpui --example gradient
cargo run -p gpui --example gradient --features macos-blade
```

## Demo

In GPUI (sRGB):

<img width="761" alt="image"
src="https://github.com/user-attachments/assets/568c02e8-3065-43c2-b5c2-5618d553dd6e">

In GPUI (Oklab):

<img width="761" alt="image"
src="https://github.com/user-attachments/assets/b008b0de-2705-4f99-831d-998ce48eed42">

In CSS (sRGB): 

https://codepen.io/huacnlee/pen/rNXgxBY

<img width="505" alt="image"
src="https://github.com/user-attachments/assets/239f4b65-24b3-4797-9491-a13eea420158">

In CSS (Oklab):

https://codepen.io/huacnlee/pen/wBwBKOp

<img width="658" alt="image"
src="https://github.com/user-attachments/assets/56fdd55f-d219-45de-922f-7227f535b210">


---

Currently only support 2 color stops with linear-gradient. I think this
is we first introduce the gradient feature in GPUI, and the
linear-gradient is most popular for use. So we can just add this first
and then to add more other supports.
This commit is contained in:
Jason Lee 2024-12-12 03:52:52 +08:00 committed by GitHub
parent c594ccb0af
commit de89f8cf83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 902 additions and 73 deletions

View file

@ -1,7 +1,7 @@
use crate::{
point, prelude::*, px, size, transparent_black, Action, AnyDrag, AnyElement, AnyTooltip,
AnyView, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow,
Context, Corners, CursorStyle, Decorations, DevicePixels, DispatchActionListener,
AnyView, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Background, Bounds,
BoxShadow, Context, Corners, CursorStyle, Decorations, DevicePixels, DispatchActionListener,
DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter,
FileDropEvent, Flatten, FontId, GPUSpecs, Global, GlobalElementId, GlyphId, Hsla, InputHandler,
IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke, KeystrokeEvent,
@ -2325,7 +2325,7 @@ impl<'a> WindowContext<'a> {
/// Paint the given `Path` into the scene for the next frame at the current z-index.
///
/// This method should only be called as part of the paint phase of element drawing.
pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Background>) {
debug_assert_eq!(
self.window.draw_phase,
DrawPhase::Paint,
@ -2336,7 +2336,8 @@ impl<'a> WindowContext<'a> {
let content_mask = self.content_mask();
let opacity = self.element_opacity();
path.content_mask = content_mask;
path.color = color.into().opacity(opacity);
let color: Background = color.into();
path.color = color.opacity(opacity);
self.window
.next_frame
.scene
@ -4980,7 +4981,7 @@ pub struct PaintQuad {
/// The radii of the quad's corners.
pub corner_radii: Corners<Pixels>,
/// The background color of the quad.
pub background: Hsla,
pub background: Background,
/// The widths of the quad's borders.
pub border_widths: Edges<Pixels>,
/// The color of the quad's borders.
@ -5013,7 +5014,7 @@ impl PaintQuad {
}
/// Sets the background color of the quad.
pub fn background(self, background: impl Into<Hsla>) -> Self {
pub fn background(self, background: impl Into<Background>) -> Self {
PaintQuad {
background: background.into(),
..self
@ -5025,7 +5026,7 @@ impl PaintQuad {
pub fn quad(
bounds: Bounds<Pixels>,
corner_radii: impl Into<Corners<Pixels>>,
background: impl Into<Hsla>,
background: impl Into<Background>,
border_widths: impl Into<Edges<Pixels>>,
border_color: impl Into<Hsla>,
) -> PaintQuad {
@ -5039,7 +5040,7 @@ pub fn quad(
}
/// Creates a filled quad with the given bounds and background color.
pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Background>) -> PaintQuad {
PaintQuad {
bounds: bounds.into(),
corner_radii: (0.).into(),
@ -5054,7 +5055,7 @@ pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>)
PaintQuad {
bounds: bounds.into(),
corner_radii: (0.).into(),
background: transparent_black(),
background: transparent_black().into(),
border_widths: (1.).into(),
border_color: border_color.into(),
}