From a03b7624f1142f20c25c0ae90727656c2c579bb3 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Wed, 29 Jan 2025 14:19:20 -0500 Subject: [PATCH] Revert "gpui & ui: Use shader for dashed dividers" (#23850) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverts zed-industries/zed#23839 getting some reports of linux crashes – will investigate later today Release Notes: - N/A --- .zed/settings.json | 1 - crates/gpui/examples/pattern.rs | 57 +------ crates/gpui/src/color.rs | 44 ----- crates/gpui/src/platform/blade/shaders.wgsl | 16 -- crates/gpui/src/platform/mac/shaders.metal | 25 +-- crates/gpui/src/style.rs | 1 - crates/ui/src/components/divider.rs | 170 +++++++++++--------- crates/workspace/src/theme_preview.rs | 2 +- 8 files changed, 106 insertions(+), 210 deletions(-) diff --git a/.zed/settings.json b/.zed/settings.json index 68b9ef5d70..41adfdbf59 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -39,7 +39,6 @@ } }, "file_types": { - "C": ["metal"], "Dockerfile": ["Dockerfile*[!dockerignore]"], "Git Ignore": ["dockerignore"] }, diff --git a/crates/gpui/examples/pattern.rs b/crates/gpui/examples/pattern.rs index f4c3cf9b67..b872d6b6ad 100644 --- a/crates/gpui/examples/pattern.rs +++ b/crates/gpui/examples/pattern.rs @@ -1,7 +1,6 @@ use gpui::{ - div, linear_color_stop, linear_gradient, pattern_horizontal_dash, pattern_slash, - pattern_vertical_dash, prelude::*, px, rgb, size, App, AppContext, Application, Bounds, - Context, Window, WindowBounds, WindowOptions, + div, linear_color_stop, linear_gradient, pattern_slash, prelude::*, px, rgb, size, App, + AppContext, Application, Bounds, Context, Window, WindowBounds, WindowOptions, }; struct PatternExample; @@ -20,58 +19,6 @@ impl Render for PatternExample { .text_xl() .text_color(rgb(0x000000)) .child("Pattern Example") - .child( - div() - .flex() - .gap_4() - .child( - div() - .flex() - .flex_col() - .gap_1() - .child( - div() - .w(px(160.0)) - .h(px(1.0)) - .bg(pattern_horizontal_dash(gpui::red())), - ) - .child( - div() - .w(px(160.0)) - .h(px(4.0)) - .bg(pattern_horizontal_dash(gpui::red())), - ) - .child( - div() - .w(px(160.0)) - .h(px(8.0)) - .bg(pattern_horizontal_dash(gpui::red())), - ), - ) - .child( - div() - .flex() - .gap_1() - .child( - div() - .w(px(1.0)) - .h(px(160.0)) - .bg(pattern_vertical_dash(gpui::blue())), - ) - .child( - div() - .w(px(4.0)) - .h(px(160.0)) - .bg(pattern_vertical_dash(gpui::blue())), - ) - .child( - div() - .w(px(8.0)) - .h(px(160.0)) - .bg(pattern_vertical_dash(gpui::blue())), - ), - ), - ) .child( div() .flex() diff --git a/crates/gpui/src/color.rs b/crates/gpui/src/color.rs index afade1bd02..230eca3e6b 100644 --- a/crates/gpui/src/color.rs +++ b/crates/gpui/src/color.rs @@ -548,33 +548,12 @@ impl<'de> Deserialize<'de> for Hsla { } } -/// The orientation of a background. -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] -#[repr(C)] -pub enum BackgroundOrientation { - /// The background is oriented horizontally. - #[default] - Horizontal = 0, - /// The background is oriented vertically. - Vertical = 1, -} - -impl Display for BackgroundOrientation { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - BackgroundOrientation::Horizontal => write!(f, "Horizontal"), - BackgroundOrientation::Vertical => write!(f, "Vertical"), - } - } -} - #[derive(Debug, Clone, Copy, PartialEq)] #[repr(C)] pub(crate) enum BackgroundTag { Solid = 0, LinearGradient = 1, PatternSlash = 2, - PatternDash = 3, } /// A color space for color interpolation. @@ -610,7 +589,6 @@ pub struct Background { pub(crate) solid: Hsla, pub(crate) angle: f32, pub(crate) colors: [LinearColorStop; 2], - pub(crate) orientation: BackgroundOrientation, /// Padding for alignment for repr(C) layout. pad: u32, } @@ -624,7 +602,6 @@ impl Default for Background { color_space: ColorSpace::default(), angle: 0.0, colors: [LinearColorStop::default(), LinearColorStop::default()], - orientation: BackgroundOrientation::default(), pad: 0, } } @@ -639,26 +616,6 @@ pub fn pattern_slash(color: Hsla) -> Background { } } -/// Creates a dash pattern background -pub fn pattern_horizontal_dash(color: Hsla) -> Background { - Background { - tag: BackgroundTag::PatternDash, - orientation: BackgroundOrientation::Horizontal, - solid: color, - ..Default::default() - } -} - -/// Creates a vertical dash pattern background -pub fn pattern_vertical_dash(color: Hsla) -> Background { - Background { - tag: BackgroundTag::PatternDash, - solid: color, - orientation: BackgroundOrientation::Vertical, - ..Default::default() - } -} - /// Creates a LinearGradient background color. /// /// The gradient line's angle of direction. A value of `0.` is equivalent to to top; increasing values rotate clockwise from there. @@ -737,7 +694,6 @@ impl Background { BackgroundTag::Solid => self.solid.is_transparent(), BackgroundTag::LinearGradient => self.colors.iter().all(|c| c.color.is_transparent()), BackgroundTag::PatternSlash => self.solid.is_transparent(), - BackgroundTag::PatternDash => self.solid.is_transparent(), } } } diff --git a/crates/gpui/src/platform/blade/shaders.wgsl b/crates/gpui/src/platform/blade/shaders.wgsl index 32f386d231..b41ffb26ef 100644 --- a/crates/gpui/src/platform/blade/shaders.wgsl +++ b/crates/gpui/src/platform/blade/shaders.wgsl @@ -359,7 +359,6 @@ fn gradient_color(background: Background, position: vec2, bounds: Bounds, } } case 2u: { - // Slash pattern let base_pattern_size = bounds.size.y / 5.0; let width = base_pattern_size * 0.5; let slash_spacing = 0.89; @@ -375,21 +374,6 @@ fn gradient_color(background: Background, position: vec2, bounds: Bounds, background_color = sold_color; background_color.a *= saturate(0.5 - distance); } - case 3u: { - // Dash pattern - let dash_width = 8.0; - let gap_width = 8.0; - let pattern_width = dash_width + gap_width; - let relative_position = position - bounds.origin; - - // Use a dot product to select x or y based on orientation - let orientation_vector = vec2(1.0 - f32(background.angle != 0.0), f32(background.angle != 0.0)); - let pattern_position = fmod(dot(relative_position, orientation_vector), pattern_width); - - let distance = pattern_position - dash_width; - background_color = sold_color; - background_color.a *= step(-distance, 0.0); - } } return background_color; diff --git a/crates/gpui/src/platform/mac/shaders.metal b/crates/gpui/src/platform/mac/shaders.metal index c2bdeb2d11..941c20c33d 100644 --- a/crates/gpui/src/platform/mac/shaders.metal +++ b/crates/gpui/src/platform/mac/shaders.metal @@ -797,7 +797,7 @@ float4 over(float4 below, float4 above) { GradientColor prepare_fill_color(uint tag, uint color_space, Hsla solid, Hsla color0, Hsla color1) { GradientColor out; - if (tag == 0 || tag == 2 || tag == 3) { + if (tag == 0 || tag == 2) { out.solid = hsla_to_rgba(solid); } else if (tag == 1) { out.color0 = hsla_to_rgba(color0); @@ -874,10 +874,13 @@ float4 fill_color(Background background, break; } case 2: { - // Slash pattern + // This pattern is full of magic numbers to make it line up perfectly + // when vertically stacked. Make sure you know what you are doing + // if you change this! + float base_pattern_size = bounds.size.height / 5; float width = base_pattern_size * 0.5; - float slash_spacing = .89; // exact number to make vertical elements line up + float slash_spacing = .89; float radians = M_PI_F / 4.0; float2x2 rotation = rotate2d(radians); float2 relative_position = position - float2(bounds.origin.x, bounds.origin.y); @@ -888,22 +891,6 @@ float4 fill_color(Background background, color.a *= saturate(0.5 - distance); break; } - case 3: { - // Dash pattern - float dash_width = 8.0; - float gap_width = 8.0; - float pattern_width = dash_width + gap_width; - float2 relative_position = position - float2(bounds.origin.x, bounds.origin.y); - - // Use a dot product to select x or y based on orientation - float2 orientation_vector = float2(1.0 - background.orientation, background.orientation); - float pattern_position = fmod(dot(relative_position, orientation_vector), pattern_width); - - float distance = pattern_position - dash_width; - color = solid_color; - color.a *= step(-distance, 0.0); - break; - } } return color; diff --git a/crates/gpui/src/style.rs b/crates/gpui/src/style.rs index f9541b8ec7..39175b44c5 100644 --- a/crates/gpui/src/style.rs +++ b/crates/gpui/src/style.rs @@ -583,7 +583,6 @@ impl Style { .map(|stop| stop.color) .unwrap_or_default(), BackgroundTag::PatternSlash => color.solid, - BackgroundTag::PatternDash => color.solid, }, None => Hsla::default(), }; diff --git a/crates/ui/src/components/divider.rs b/crates/ui/src/components/divider.rs index f3c9c94134..2a0f87a610 100644 --- a/crates/ui/src/components/divider.rs +++ b/crates/ui/src/components/divider.rs @@ -1,7 +1,14 @@ -use gpui::{pattern_horizontal_dash, pattern_vertical_dash, Background, Hsla, IntoElement}; +#![allow(missing_docs)] +use gpui::{Hsla, IntoElement}; use crate::prelude::*; +#[derive(Clone, Copy, PartialEq)] +enum DividerStyle { + Solid, + Dashed, +} + #[derive(Clone, Copy, PartialEq)] enum DividerDirection { Horizontal, @@ -11,15 +18,12 @@ enum DividerDirection { /// The color of a [`Divider`]. #[derive(Default)] pub enum DividerColor { - /// The default border color. - #[default] Border, - /// Usually a de-emphasized border color. + #[default] BorderVariant, } impl DividerColor { - /// Returns the divider's HSLA color. pub fn hsla(self, cx: &mut App) -> Hsla { match self { DividerColor::Border => cx.theme().colors().border, @@ -28,29 +32,71 @@ impl DividerColor { } } -/// A component that can be used to separate sections of content. -/// -/// Can be rendered horizontally or vertically. #[derive(IntoElement)] pub struct Divider { + style: DividerStyle, direction: DividerDirection, color: DividerColor, inset: bool, - is_dashed: bool, } impl RenderOnce for Divider { fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { - let color = self.color.hsla(cx); - let background = if self.is_dashed { - match self.direction { - DividerDirection::Horizontal => pattern_horizontal_dash(color), - DividerDirection::Vertical => pattern_vertical_dash(color), - } - } else { - Background::from(color) - }; + match self.style { + DividerStyle::Solid => self.render_solid(cx).into_any_element(), + DividerStyle::Dashed => self.render_dashed(cx).into_any_element(), + } + } +} +impl Divider { + pub fn horizontal() -> Self { + Self { + style: DividerStyle::Solid, + direction: DividerDirection::Horizontal, + color: DividerColor::default(), + inset: false, + } + } + + pub fn vertical() -> Self { + Self { + style: DividerStyle::Solid, + direction: DividerDirection::Vertical, + color: DividerColor::default(), + inset: false, + } + } + + pub fn horizontal_dashed() -> Self { + Self { + style: DividerStyle::Dashed, + direction: DividerDirection::Horizontal, + color: DividerColor::default(), + inset: false, + } + } + + pub fn vertical_dashed() -> Self { + Self { + style: DividerStyle::Dashed, + direction: DividerDirection::Vertical, + color: DividerColor::default(), + inset: false, + } + } + + pub fn inset(mut self) -> Self { + self.inset = true; + self + } + + pub fn color(mut self, color: DividerColor) -> Self { + self.color = color; + self + } + + pub fn render_solid(self, cx: &mut App) -> impl IntoElement { div() .map(|this| match self.direction { DividerDirection::Horizontal => { @@ -60,60 +106,38 @@ impl RenderOnce for Divider { this.w_px().h_full().when(self.inset, |this| this.my_1p5()) } }) - .bg(background) - } -} - -impl Divider { - /// Creates a solid horizontal divider. - pub fn horizontal() -> Self { - Self { - direction: DividerDirection::Horizontal, - color: DividerColor::default(), - inset: false, - is_dashed: false, - } - } - - /// Creates a solid vertical divider. - pub fn vertical() -> Self { - Self { - direction: DividerDirection::Vertical, - color: DividerColor::default(), - inset: false, - is_dashed: false, - } - } - - /// Creates a dashed horizontal divider. - pub fn horizontal_dashed() -> Self { - Self { - direction: DividerDirection::Horizontal, - color: DividerColor::default(), - inset: false, - is_dashed: true, - } - } - - /// Creates a dashed vertical divider. - pub fn vertical_dashed() -> Self { - Self { - direction: DividerDirection::Vertical, - color: DividerColor::default(), - inset: false, - is_dashed: true, - } - } - - /// Pads the divider with a margin. - pub fn inset(mut self) -> Self { - self.inset = true; - self - } - - /// Sets the color of the divider. - pub fn color(mut self, color: DividerColor) -> Self { - self.color = color; - self + .bg(self.color.hsla(cx)) + } + + // TODO: Use canvas or a shader here + // This obviously is a short term approach + pub fn render_dashed(self, cx: &mut App) -> impl IntoElement { + let segment_count = 128; + let segment_count_f = segment_count as f32; + let segment_min_w = 6.; + let base = match self.direction { + DividerDirection::Horizontal => h_flex(), + DividerDirection::Vertical => v_flex(), + }; + let (w, h) = match self.direction { + DividerDirection::Horizontal => (px(segment_min_w), px(1.)), + DividerDirection::Vertical => (px(1.), px(segment_min_w)), + }; + let color = self.color.hsla(cx); + let total_min_w = segment_min_w * segment_count_f * 2.; // * 2 because of the gap + + base.min_w(px(total_min_w)) + .map(|this| { + if self.direction == DividerDirection::Horizontal { + this.w_full().h_px() + } else { + this.w_px().h_full() + } + }) + .gap(px(segment_min_w)) + .overflow_hidden() + .children( + (0..segment_count).map(|_| div().flex_grow().flex_shrink_0().w(w).h(h).bg(color)), + ) } } diff --git a/crates/workspace/src/theme_preview.rs b/crates/workspace/src/theme_preview.rs index a4df48f958..5062446fe5 100644 --- a/crates/workspace/src/theme_preview.rs +++ b/crates/workspace/src/theme_preview.rs @@ -5,7 +5,7 @@ use theme::all_theme_colors; use ui::{ element_cell, prelude::*, string_cell, utils::calculate_contrast_ratio, AudioStatus, Availability, Avatar, AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike, - Checkbox, CheckboxWithLabel, ContentGroup, DecoratedIcon, Divider, ElevationIndex, Facepile, + Checkbox, CheckboxWithLabel, ContentGroup, DecoratedIcon, ElevationIndex, Facepile, IconDecoration, Indicator, Switch, Table, TintColor, Tooltip, };