Add fluent quad API

Mikayla created

Change summary

crates/collab_ui2/src/collab_panel.rs         |  26 +--
crates/editor2/src/element.rs                 | 104 +++++-----------
crates/gpui2/src/geometry.rs                  |  33 +++++
crates/gpui2/src/style.rs                     |  10 
crates/gpui2/src/text_system/line.rs          |  26 +---
crates/gpui2/src/window.rs                    | 124 ++++++++++++++++----
crates/terminal_view2/src/terminal_element.rs |  24 +---
7 files changed, 196 insertions(+), 151 deletions(-)

Detailed changes

crates/collab_ui2/src/collab_panel.rs 🔗

@@ -175,12 +175,12 @@ use editor::Editor;
 use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
 use fuzzy::{match_strings, StringMatchCandidate};
 use gpui::{
-    actions, canvas, div, img, impl_actions, overlay, point, prelude::*, px, rems, serde_json,
-    size, Action, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div,
-    EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement, IntoElement,
-    Length, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad, Render,
-    RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, View,
-    ViewContext, VisualContext, WeakView,
+    actions, canvas, div, fill, img, impl_actions, overlay, point, prelude::*, px, rems,
+    serde_json, size, Action, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent,
+    Div, EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement,
+    IntoElement, Length, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad,
+    Render, RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task,
+    View, ViewContext, VisualContext, WeakView,
 };
 use project::{Fs, Project};
 use serde_derive::{Deserialize, Serialize};
@@ -2994,7 +2994,7 @@ fn render_tree_branch(is_last: bool, cx: &mut WindowContext) -> impl IntoElement
         let right = bounds.right();
         let top = bounds.top();
 
-        cx.paint_quad(
+        cx.paint_quad(fill(
             Bounds::from_corners(
                 point(start_x, top),
                 point(
@@ -3002,18 +3002,12 @@ fn render_tree_branch(is_last: bool, cx: &mut WindowContext) -> impl IntoElement
                     if is_last { start_y } else { bounds.bottom() },
                 ),
             ),
-            Default::default(),
             color,
-            Default::default(),
-            Hsla::transparent_black(),
-        );
-        cx.paint_quad(
+        ));
+        cx.paint_quad(fill(
             Bounds::from_corners(point(start_x, start_y), point(right, start_y + thickness)),
-            Default::default(),
             color,
-            Default::default(),
-            Hsla::transparent_black(),
-        );
+        ));
     })
     .w(width)
     .h(line_height)

crates/editor2/src/element.rs 🔗

@@ -23,13 +23,14 @@ use anyhow::Result;
 use collections::{BTreeMap, HashMap};
 use git::diff::DiffHunkStatus;
 use gpui::{
-    div, overlay, point, px, relative, size, transparent_black, Action, AnchorCorner, AnyElement,
-    AsyncWindowContext, AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners, CursorStyle,
-    DispatchPhase, Edges, Element, ElementId, ElementInputHandler, Entity, EntityId, Hsla,
-    InteractiveBounds, InteractiveElement, IntoElement, LineLayout, ModifiersChangedEvent,
-    MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, RenderOnce,
-    ScrollWheelEvent, ShapedLine, SharedString, Size, StackingOrder, StatefulInteractiveElement,
-    Style, Styled, TextRun, TextStyle, View, ViewContext, WeakView, WindowContext, WrappedLine,
+    div, fill, outline, overlay, point, px, quad, relative, size, transparent_black, Action,
+    AnchorCorner, AnyElement, AsyncWindowContext, AvailableSpace, BorrowWindow, Bounds,
+    ContentMask, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementId,
+    ElementInputHandler, Entity, EntityId, Hsla, InteractiveBounds, InteractiveElement,
+    IntoElement, LineLayout, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent,
+    MouseUpEvent, ParentElement, Pixels, RenderOnce, ScrollWheelEvent, ShapedLine, SharedString,
+    Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, View,
+    ViewContext, WeakView, WindowContext, WrappedLine,
 };
 use itertools::Itertools;
 use language::{language_settings::ShowWhitespaceSetting, Language};
@@ -620,20 +621,8 @@ impl EditorElement {
         let scroll_top =
             layout.position_map.snapshot.scroll_position().y * layout.position_map.line_height;
         let gutter_bg = cx.theme().colors().editor_gutter_background;
-        cx.paint_quad(
-            gutter_bounds,
-            Corners::default(),
-            gutter_bg,
-            Edges::default(),
-            transparent_black(),
-        );
-        cx.paint_quad(
-            text_bounds,
-            Corners::default(),
-            self.style.background,
-            Edges::default(),
-            transparent_black(),
-        );
+        cx.paint_quad(fill(gutter_bounds, gutter_bg));
+        cx.paint_quad(fill(text_bounds, self.style.background));
 
         if let EditorMode::Full = layout.mode {
             let mut active_rows = layout.active_rows.iter().peekable();
@@ -657,13 +646,7 @@ impl EditorElement {
                         layout.position_map.line_height * (end_row - start_row + 1) as f32,
                     );
                     let active_line_bg = cx.theme().colors().editor_active_line_background;
-                    cx.paint_quad(
-                        Bounds { origin, size },
-                        Corners::default(),
-                        active_line_bg,
-                        Edges::default(),
-                        transparent_black(),
-                    );
+                    cx.paint_quad(fill(Bounds { origin, size }, active_line_bg));
                 }
             }
 
@@ -679,13 +662,7 @@ impl EditorElement {
                     layout.position_map.line_height * highlighted_rows.len() as f32,
                 );
                 let highlighted_line_bg = cx.theme().colors().editor_highlighted_line_background;
-                cx.paint_quad(
-                    Bounds { origin, size },
-                    Corners::default(),
-                    highlighted_line_bg,
-                    Edges::default(),
-                    transparent_black(),
-                );
+                cx.paint_quad(fill(Bounds { origin, size }, highlighted_line_bg));
             }
 
             let scroll_left =
@@ -706,16 +683,13 @@ impl EditorElement {
                 } else {
                     cx.theme().colors().editor_wrap_guide
                 };
-                cx.paint_quad(
+                cx.paint_quad(fill(
                     Bounds {
                         origin: point(x, text_bounds.origin.y),
                         size: size(px(1.), text_bounds.size.height),
                     },
-                    Corners::default(),
                     color,
-                    Edges::default(),
-                    transparent_black(),
-                );
+                ));
             }
         }
     }
@@ -812,13 +786,13 @@ impl EditorElement {
                     let highlight_origin = bounds.origin + point(-width, start_y);
                     let highlight_size = size(width * 2., end_y - start_y);
                     let highlight_bounds = Bounds::new(highlight_origin, highlight_size);
-                    cx.paint_quad(
+                    cx.paint_quad(quad(
                         highlight_bounds,
                         Corners::all(1. * line_height),
                         gpui::yellow(), // todo!("use the right color")
                         Edges::default(),
                         transparent_black(),
-                    );
+                    ));
 
                     continue;
                 }
@@ -845,13 +819,13 @@ impl EditorElement {
                     let highlight_origin = bounds.origin + point(-width, start_y);
                     let highlight_size = size(width * 2., end_y - start_y);
                     let highlight_bounds = Bounds::new(highlight_origin, highlight_size);
-                    cx.paint_quad(
+                    cx.paint_quad(quad(
                         highlight_bounds,
                         Corners::all(1. * line_height),
                         cx.theme().status().deleted,
                         Edges::default(),
                         transparent_black(),
-                    );
+                    ));
 
                     continue;
                 }
@@ -867,13 +841,13 @@ impl EditorElement {
             let highlight_origin = bounds.origin + point(-width, start_y);
             let highlight_size = size(width * 2., end_y - start_y);
             let highlight_bounds = Bounds::new(highlight_origin, highlight_size);
-            cx.paint_quad(
+            cx.paint_quad(quad(
                 highlight_bounds,
                 Corners::all(0.05 * line_height),
                 color, // todo!("use the right color")
                 Edges::default(),
                 transparent_black(),
-            );
+            ));
         }
     }
 
@@ -1278,7 +1252,7 @@ impl EditorElement {
         let thumb_bounds = Bounds::from_corners(point(left, thumb_top), point(right, thumb_bottom));
 
         if layout.show_scrollbars {
-            cx.paint_quad(
+            cx.paint_quad(quad(
                 track_bounds,
                 Corners::default(),
                 cx.theme().colors().scrollbar_track_background,
@@ -1289,7 +1263,7 @@ impl EditorElement {
                     left: px(1.),
                 },
                 cx.theme().colors().scrollbar_track_border,
-            );
+            ));
             let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
             if layout.is_singleton && scrollbar_settings.selections {
                 let start_anchor = Anchor::min();
@@ -1309,7 +1283,7 @@ impl EditorElement {
                         end_y = start_y + px(1.);
                     }
                     let bounds = Bounds::from_corners(point(left, start_y), point(right, end_y));
-                    cx.paint_quad(
+                    cx.paint_quad(quad(
                         bounds,
                         Corners::default(),
                         cx.theme().status().info,
@@ -1320,7 +1294,7 @@ impl EditorElement {
                             left: px(1.),
                         },
                         cx.theme().colors().scrollbar_thumb_border,
-                    );
+                    ));
                 }
             }
 
@@ -1352,7 +1326,7 @@ impl EditorElement {
                         DiffHunkStatus::Modified => cx.theme().status().modified,
                         DiffHunkStatus::Removed => cx.theme().status().deleted,
                     };
-                    cx.paint_quad(
+                    cx.paint_quad(quad(
                         bounds,
                         Corners::default(),
                         color,
@@ -1363,11 +1337,11 @@ impl EditorElement {
                             left: px(1.),
                         },
                         cx.theme().colors().scrollbar_thumb_border,
-                    );
+                    ));
                 }
             }
 
-            cx.paint_quad(
+            cx.paint_quad(quad(
                 thumb_bounds,
                 Corners::default(),
                 cx.theme().colors().scrollbar_thumb_background,
@@ -1378,7 +1352,7 @@ impl EditorElement {
                     left: px(1.),
                 },
                 cx.theme().colors().scrollbar_thumb_border,
-            );
+            ));
         }
 
         let mouse_position = cx.mouse_position();
@@ -3085,23 +3059,13 @@ impl Cursor {
         };
 
         //Draw background or border quad
-        if matches!(self.shape, CursorShape::Hollow) {
-            cx.paint_quad(
-                bounds,
-                Corners::default(),
-                transparent_black(),
-                Edges::all(px(1.)),
-                self.color,
-            );
+        let cursor = if matches!(self.shape, CursorShape::Hollow) {
+            outline(bounds, self.color)
         } else {
-            cx.paint_quad(
-                bounds,
-                Corners::default(),
-                self.color,
-                Edges::default(),
-                transparent_black(),
-            );
-        }
+            fill(bounds, self.color)
+        };
+
+        cx.paint_quad(cursor);
 
         if let Some(block_text) = &self.block_text {
             block_text.paint(self.origin + origin, self.line_height, cx);

crates/gpui2/src/geometry.rs 🔗

@@ -1592,6 +1592,17 @@ impl Edges<Pixels> {
     }
 }
 
+impl Into<Edges<Pixels>> for f32 {
+    fn into(self) -> Edges<Pixels> {
+        Edges {
+            top: self.into(),
+            right: self.into(),
+            bottom: self.into(),
+            left: self.into(),
+        }
+    }
+}
+
 /// Represents the corners of a box in a 2D space, such as border radius.
 ///
 /// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
@@ -1808,6 +1819,28 @@ where
 
 impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
 
+impl Into<Corners<Pixels>> for f32 {
+    fn into(self) -> Corners<Pixels> {
+        Corners {
+            top_left: self.into(),
+            top_right: self.into(),
+            bottom_right: self.into(),
+            bottom_left: self.into(),
+        }
+    }
+}
+
+impl Into<Corners<Pixels>> for Pixels {
+    fn into(self) -> Corners<Pixels> {
+        Corners {
+            top_left: self,
+            top_right: self,
+            bottom_right: self,
+            bottom_left: self,
+        }
+    }
+}
+
 /// Represents a length in pixels, the base unit of measurement in the UI framework.
 ///
 /// `Pixels` is a value type that represents an absolute length in pixels, which is used

crates/gpui2/src/style.rs 🔗

@@ -1,9 +1,9 @@
 use std::{iter, mem, ops::Range};
 
 use crate::{
-    black, phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask,
-    Corners, CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font,
-    FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba,
+    black, phi, point, quad, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds,
+    ContentMask, Corners, CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement,
+    Font, FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba,
     SharedString, Size, SizeRefinement, Styled, TextRun, WindowContext,
 };
 use collections::HashSet;
@@ -348,13 +348,13 @@ impl Style {
         let background_color = self.background.as_ref().and_then(Fill::color);
         if background_color.is_some() || self.is_border_visible() {
             cx.with_z_index(1, |cx| {
-                cx.paint_quad(
+                cx.paint_quad(quad(
                     bounds,
                     self.corner_radii.to_pixels(bounds.size, rem_size),
                     background_color.unwrap_or_default(),
                     self.border_widths.to_pixels(rem_size),
                     self.border_color.unwrap_or_default(),
-                );
+                ));
             });
         }
     }

crates/gpui2/src/text_system/line.rs 🔗

@@ -1,7 +1,6 @@
 use crate::{
-    black, point, px, size, transparent_black, BorrowWindow, Bounds, Corners, Edges, Hsla,
-    LineLayout, Pixels, Point, Result, SharedString, UnderlineStyle, WindowContext, WrapBoundary,
-    WrappedLineLayout,
+    black, fill, point, px, size, BorrowWindow, Bounds, Hsla, LineLayout, Pixels, Point, Result,
+    SharedString, UnderlineStyle, WindowContext, WrapBoundary, WrappedLineLayout,
 };
 use derive_more::{Deref, DerefMut};
 use smallvec::SmallVec;
@@ -109,16 +108,13 @@ fn paint_line(
             if wraps.peek() == Some(&&WrapBoundary { run_ix, glyph_ix }) {
                 wraps.next();
                 if let Some((background_origin, background_color)) = current_background.as_mut() {
-                    cx.paint_quad(
+                    cx.paint_quad(fill(
                         Bounds {
                             origin: *background_origin,
                             size: size(glyph_origin.x - background_origin.x, line_height),
                         },
-                        Corners::default(),
                         *background_color,
-                        Edges::default(),
-                        transparent_black(),
-                    );
+                    ));
                     background_origin.x = origin.x;
                     background_origin.y += line_height;
                 }
@@ -180,16 +176,13 @@ fn paint_line(
             }
 
             if let Some((background_origin, background_color)) = finished_background {
-                cx.paint_quad(
+                cx.paint_quad(fill(
                     Bounds {
                         origin: background_origin,
                         size: size(glyph_origin.x - background_origin.x, line_height),
                     },
-                    Corners::default(),
                     background_color,
-                    Edges::default(),
-                    transparent_black(),
-                );
+                ));
             }
 
             if let Some((underline_origin, underline_style)) = finished_underline {
@@ -235,16 +228,13 @@ fn paint_line(
     }
 
     if let Some((background_origin, background_color)) = current_background.take() {
-        cx.paint_quad(
+        cx.paint_quad(fill(
             Bounds {
                 origin: background_origin,
                 size: size(last_line_end_x - background_origin.x, line_height),
             },
-            Corners::default(),
             background_color,
-            Edges::default(),
-            transparent_black(),
-        );
+        ));
     }
 
     if let Some((underline_start, underline_style)) = current_underline.take() {

crates/gpui2/src/window.rs 🔗

@@ -1,15 +1,15 @@
 use crate::{
-    key_dispatch::DispatchActionListener, px, size, Action, AnyDrag, AnyView, AppContext,
-    AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle,
-    DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
-    EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
-    ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId,
-    Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent,
-    Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
-    PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
-    RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString, Size, Style,
-    SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View,
-    VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
+    key_dispatch::DispatchActionListener, px, size, transparent_black, Action, AnyDrag, AnyView,
+    AppContext, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow, Context, Corners,
+    CursorStyle, DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity,
+    EntityId, EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId,
+    Hsla, ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent,
+    LayoutId, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent,
+    MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
+    PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
+    RenderImageParams, RenderSvgParams, ScaledPixels, Scene, SceneBuilder, Shadow, SharedString,
+    Size, Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline,
+    UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
 };
 use anyhow::{anyhow, Context as _, Result};
 use collections::HashMap;
@@ -963,14 +963,8 @@ impl<'a> WindowContext<'a> {
 
     /// Paint one or more quads into the scene for the next frame at the current stacking context.
     /// Quads are colored rectangular regions with an optional background, border, and corner radius.
-    pub fn paint_quad(
-        &mut self,
-        bounds: Bounds<Pixels>,
-        corner_radii: Corners<Pixels>,
-        background: impl Into<Hsla>,
-        border_widths: Edges<Pixels>,
-        border_color: impl Into<Hsla>,
-    ) {
+    /// see [`fill`], [`outline`], and [`quad`] to construct this type.
+    pub fn paint_quad(&mut self, quad: PaintQuad) {
         let scale_factor = self.scale_factor();
         let content_mask = self.content_mask();
 
@@ -979,12 +973,12 @@ impl<'a> WindowContext<'a> {
             &window.next_frame.z_index_stack,
             Quad {
                 order: 0,
-                bounds: bounds.scale(scale_factor),
+                bounds: quad.bounds.scale(scale_factor),
                 content_mask: content_mask.scale(scale_factor),
-                background: background.into(),
-                border_color: border_color.into(),
-                corner_radii: corner_radii.scale(scale_factor),
-                border_widths: border_widths.scale(scale_factor),
+                background: quad.background,
+                border_color: quad.border_color,
+                corner_radii: quad.corner_radii.scale(scale_factor),
+                border_widths: quad.border_widths.scale(scale_factor),
             },
         );
     }
@@ -2962,3 +2956,85 @@ impl From<(&'static str, u64)> for ElementId {
         ElementId::NamedInteger(name.into(), id as usize)
     }
 }
+
+/// A rectangle, to be rendered on the screen by GPUI at the given position and size.
+pub struct PaintQuad {
+    bounds: Bounds<Pixels>,
+    corner_radii: Corners<Pixels>,
+    background: Hsla,
+    border_widths: Edges<Pixels>,
+    border_color: Hsla,
+}
+
+impl PaintQuad {
+    /// Set the corner radii of the quad.
+    pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
+        PaintQuad {
+            corner_radii: corner_radii.into(),
+            ..self
+        }
+    }
+
+    /// Set the border widths of the quad.
+    pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
+        PaintQuad {
+            border_widths: border_widths.into(),
+            ..self
+        }
+    }
+
+    /// Set the border color of the quad.
+    pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
+        PaintQuad {
+            border_color: border_color.into(),
+            ..self
+        }
+    }
+
+    /// Set the background color of the quad.
+    pub fn background(self, background: impl Into<Hsla>) -> Self {
+        PaintQuad {
+            background: background.into(),
+            ..self
+        }
+    }
+}
+
+/// Create a quad with the given parameters.
+pub fn quad(
+    bounds: Bounds<Pixels>,
+    corner_radii: impl Into<Corners<Pixels>>,
+    background: impl Into<Hsla>,
+    border_widths: impl Into<Edges<Pixels>>,
+    border_color: impl Into<Hsla>,
+) -> PaintQuad {
+    PaintQuad {
+        bounds,
+        corner_radii: corner_radii.into(),
+        background: background.into(),
+        border_widths: border_widths.into(),
+        border_color: border_color.into(),
+    }
+}
+
+/// Create a filled quad with the given bounds and background color.
+pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
+    PaintQuad {
+        bounds: bounds.into(),
+        corner_radii: (0.).into(),
+        background: background.into(),
+        border_widths: (0.).into(),
+        border_color: transparent_black(),
+    }
+}
+
+/// Create a rectangle outline with the given bounds, border color, and a 1px border width
+pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>) -> PaintQuad {
+    PaintQuad {
+        bounds: bounds.into(),
+        corner_radii: (0.).into(),
+        background: transparent_black(),
+        border_widths: (1.).into(),
+        border_color: border_color.into(),
+    }
+}

crates/terminal_view2/src/terminal_element.rs 🔗

@@ -1,9 +1,9 @@
 use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
 use gpui::{
-    black, div, point, px, red, relative, transparent_black, AnyElement, AsyncWindowContext,
-    AvailableSpace, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font,
-    FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
-    IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
+    black, div, fill, point, px, red, relative, AnyElement, AsyncWindowContext, AvailableSpace,
+    Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font, FontStyle,
+    FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, IntoElement,
+    LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
     PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
     TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext,
 };
@@ -133,13 +133,7 @@ impl LayoutRect {
         )
         .into();
 
-        cx.paint_quad(
-            Bounds::new(position, size),
-            Default::default(),
-            self.color,
-            Default::default(),
-            transparent_black(),
-        );
+        cx.paint_quad(fill(Bounds::new(position, size), self.color));
     }
 }
 
@@ -775,13 +769,7 @@ impl Element for TerminalElement {
 
         let theme = cx.theme();
 
-        cx.paint_quad(
-            bounds,
-            Default::default(),
-            layout.background_color,
-            Default::default(),
-            Hsla::default(),
-        );
+        cx.paint_quad(fill(bounds, layout.background_color));
         let origin = bounds.origin + Point::new(layout.gutter, px(0.));
 
         let terminal_input_handler = TerminalInputHandler {