Update metal view example

Nate Butler created

Change summary

crates/gpui/examples/metal_view.rs        | 291 ++++++++-----------
crates/gpui/examples/metal_view_quad.rs   | 355 -------------------------
crates/gpui/examples/metal_view_simple.rs | 198 -------------
3 files changed, 127 insertions(+), 717 deletions(-)

Detailed changes

crates/gpui/examples/metal_view.rs 🔗

@@ -1,4 +1,4 @@
-use gpui::{Application, *};
+use gpui::{prelude::*, *};
 use std::sync::Arc;
 
 #[cfg(target_os = "macos")]
@@ -9,6 +9,7 @@ struct MetalViewExample {
     pipeline_state: Option<RenderPipelineState>,
     #[cfg(target_os = "macos")]
     device: Option<Device>,
+    epoch: u64,
 }
 
 impl MetalViewExample {
@@ -18,46 +19,68 @@ impl MetalViewExample {
             pipeline_state: None,
             #[cfg(target_os = "macos")]
             device: None,
+            epoch: 0,
         }
     }
 
+    fn update_epoch(&mut self, cx: &mut Context<Self>) {
+        const MAX_EPOCH: u64 = 1024;
+        self.epoch = (self.epoch + 1) % MAX_EPOCH;
+        cx.notify();
+    }
+
     #[cfg(target_os = "macos")]
     fn setup_metal(&mut self) {
-        // Create Metal device
         let device = Device::system_default().expect("no Metal device");
 
-        // Create shader library from source
+        // Shader that properly handles viewport transformation
         let shader_source = r#"
             #include <metal_stdlib>
             using namespace metal;
 
+            struct Uniforms {
+                float2 viewport_size;
+                float epoch;
+            };
+
             struct VertexOut {
                 float4 position [[position]];
                 float4 color;
             };
 
-            vertex VertexOut vertex_main(uint vid [[vertex_id]]) {
+            vertex VertexOut vertex_main(
+                uint vid [[vertex_id]],
+                constant Uniforms& uniforms [[buffer(0)]]
+            ) {
                 VertexOut out;
 
-                // Create a rectangle using two triangles
-                // Triangle 1: top-left, top-right, bottom-left
-                // Triangle 2: top-right, bottom-right, bottom-left
+                // Define a quad in pixel coordinates (0,0 to viewport_size)
                 float2 positions[6] = {
-                    float2(-1.0,  1.0), // top-left
-                    float2( 1.0,  1.0), // top-right
-                    float2(-1.0, -1.0), // bottom-left
-                    float2( 1.0,  1.0), // top-right
-                    float2( 1.0, -1.0), // bottom-right
-                    float2(-1.0, -1.0), // bottom-left
+                    float2(0.0, 0.0),                                      // top-left
+                    float2(uniforms.viewport_size.x, 0.0),                // top-right
+                    float2(0.0, uniforms.viewport_size.y),                // bottom-left
+                    float2(uniforms.viewport_size.x, 0.0),                // top-right
+                    float2(uniforms.viewport_size.x, uniforms.viewport_size.y), // bottom-right
+                    float2(0.0, uniforms.viewport_size.y),                // bottom-left
                 };
 
-                out.position = float4(positions[vid], 0.0, 1.0);
-                // Create a gradient color based on position
+                // Transform from pixel coordinates to normalized device coordinates
+                float2 pos = positions[vid];
+                float2 ndc = (pos / uniforms.viewport_size) * 2.0 - 1.0;
+                ndc.y = -ndc.y; // Flip Y axis to match screen coordinates
+
+                out.position = float4(ndc, 0.0, 1.0);
+
+                // Create an animated gradient using epoch
+                float2 uv = pos / uniforms.viewport_size;
+                float time = uniforms.epoch * 0.01;
+
+                // Animate the gradient with some trigonometric functions
                 out.color = float4(
-                    (positions[vid].x + 1.0) * 0.5,  // Red based on X
-                    (positions[vid].y + 1.0) * 0.5,  // Green based on Y
-                    0.7,                              // Blue constant
-                    1.0                               // Alpha
+                    0.5 + 0.5 * sin(uv.x * 3.14159 + time),          // Red
+                    0.5 + 0.5 * sin(uv.y * 3.14159 + time * 1.3),    // Green
+                    0.5 + 0.5 * sin((uv.x + uv.y) * 3.14159 - time * 0.7), // Blue
+                    1.0                                                // Full opacity
                 );
 
                 return out;
@@ -80,14 +103,13 @@ impl MetalViewExample {
         pipeline_descriptor.set_vertex_function(Some(&vertex_function));
         pipeline_descriptor.set_fragment_function(Some(&fragment_function));
 
-        // Configure color attachment
         let color_attachment = pipeline_descriptor
             .color_attachments()
             .object_at(0)
             .unwrap();
         color_attachment.set_pixel_format(metal::MTLPixelFormat::BGRA8Unorm);
 
-        // Enable blending to work with GPUI's existing content
+        // Enable blending
         color_attachment.set_blending_enabled(true);
         color_attachment.set_source_rgb_blend_factor(metal::MTLBlendFactor::SourceAlpha);
         color_attachment
@@ -105,7 +127,7 @@ impl MetalViewExample {
     }
 
     #[cfg(target_os = "macos")]
-    fn create_render_callback(&self) -> MetalRenderCallback {
+    fn create_render_callback(&self, epoch: u64) -> MetalRenderCallback {
         let pipeline_state = self.pipeline_state.clone().unwrap();
 
         Arc::new(
@@ -127,7 +149,37 @@ impl MetalViewExample {
                 };
                 encoder.set_viewport(viewport);
 
-                // Draw the rectangle (6 vertices for 2 triangles)
+                // Set scissor rectangle to clip to bounds
+                let scissor_rect = metal::MTLScissorRect {
+                    x: (bounds.origin.x.0 * scale_factor) as u64,
+                    y: (bounds.origin.y.0 * scale_factor) as u64,
+                    width: (bounds.size.width.0 * scale_factor) as u64,
+                    height: (bounds.size.height.0 * scale_factor) as u64,
+                };
+                encoder.set_scissor_rect(scissor_rect);
+
+                // Pass viewport size as uniform
+                #[repr(C)]
+                struct Uniforms {
+                    viewport_size: [f32; 2],
+                    epoch: f32,
+                }
+
+                let uniforms = Uniforms {
+                    viewport_size: [
+                        bounds.size.width.0 * scale_factor,
+                        bounds.size.height.0 * scale_factor,
+                    ],
+                    epoch: epoch as f32,
+                };
+
+                encoder.set_vertex_bytes(
+                    0,
+                    std::mem::size_of::<Uniforms>() as u64,
+                    &uniforms as *const Uniforms as *const _,
+                );
+
+                // Draw the quad
                 encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 6);
             },
         )
@@ -135,75 +187,63 @@ impl MetalViewExample {
 }
 
 impl Render for MetalViewExample {
-    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
+    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
         // Initialize Metal on first render if on macOS
         #[cfg(target_os = "macos")]
         if self.pipeline_state.is_none() {
             self.setup_metal();
         }
 
+        // Update epoch and request animation frame
+        self.update_epoch(cx);
+        window.request_animation_frame();
+
         div()
             .flex()
+            .flex_col()
             .bg(rgb(0x1e1e1e))
             .size_full()
-            .justify_center()
-            .items_center()
+            .p_8()
+            .gap_6()
+            .child(
+                div()
+                    .child("Metal View Element")
+                    .text_2xl()
+                    .text_color(rgb(0xffffff)),
+            )
             .child(
                 div()
-                    .flex_col()
-                    .gap_4()
-                    .child(
-                        div().flex().justify_center().child(
-                            div()
-                                .child("Metal View Example")
-                                .text_xl()
-                                .text_color(rgb(0xffffff)),
-                        ),
-                    )
-                    .child(
-                        div()
-                            .border_1()
-                            .border_color(rgb(0x444444))
-                            .rounded_md()
-                            .overflow_hidden()
-                            .child(
-                                // The Metal view
-                                #[cfg(target_os = "macos")]
-                                {
-                                    let callback = self.create_render_callback();
-                                    metal_view()
-                                        .render_with_shared(callback)
-                                        .w(px(400.0))
-                                        .h(px(300.0))
-                                        .bg(rgb(0x000000))
-                                },
-                                #[cfg(not(target_os = "macos"))]
-                                {
-                                    // Fallback for non-macOS platforms
-                                    div()
-                                        .w(px(400.0))
-                                        .h(px(300.0))
-                                        .bg(rgb(0x222222))
-                                        .flex()
-                                        .justify_center()
-                                        .items_center()
-                                        .child(
-                                            div()
-                                                .child("Metal rendering is only available on macOS")
-                                                .text_color(rgb(0x888888)),
-                                        )
-                                },
-                            ),
-                    )
-                    .child(
-                        div().flex().justify_center().child(
-                            div()
-                                .child("A gradient rectangle rendered with custom Metal shaders")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        ),
-                    ),
+                    .child("While GPUI normally handles all Metal rendering for you, the metal_view() element gives you direct access to write custom Metal shaders and GPU drawing commands")
+                    .text_color(rgb(0xaaaaaa)),
             )
+            .child(
+                div()
+                    .child("This is useful for special effects, custom visualizations, or when you need GPU performance that GPUI's standard elements can't provide")
+                    .text_sm()
+                    .text_color(rgb(0x888888)),
+            )
+            .child(div().overflow_hidden().child(
+                #[cfg(target_os = "macos")]
+                {
+                    let callback = self.create_render_callback(self.epoch);
+                    metal_view()
+                        .render_with_shared(callback)
+                        .w(px(600.0))
+                        .h(px(400.0))
+                        .bg(rgb(0x000000))
+                },
+                #[cfg(not(target_os = "macos"))]
+                {
+                    div()
+                        .w(px(600.0))
+                        .h(px(400.0))
+                        .bg(rgb(0x222222))
+                        .flex()
+                        .items_center()
+                        .justify_center()
+                        .child(div().child("Metal (macOS only)").text_color(rgb(0x666666)))
+                },
+            ))
     }
 }
 
@@ -211,97 +251,20 @@ fn main() {
     Application::new().run(|cx: &mut App| {
         let _ = cx.open_window(
             WindowOptions {
-                window_bounds: Some(WindowBounds::Windowed(Bounds {
-                    origin: Point::new(px(100.0), px(100.0)),
-                    size: Size {
-                        width: px(600.0),
-                        height: px(500.0),
-                    },
-                })),
+                window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
+                    None,
+                    size(px(900.0), px(600.0)),
+                    cx,
+                ))),
                 titlebar: Some(TitlebarOptions {
-                    title: Some("Metal View Example".into()),
+                    title: Some("Metal View Element".into()),
                     ..Default::default()
                 }),
                 ..Default::default()
             },
             |_window, cx| cx.new(|_cx| MetalViewExample::new()),
         );
-    });
-}
-
-// Additional example: Using MetalView for more complex rendering
-#[cfg(target_os = "macos")]
-#[allow(dead_code)]
-mod advanced_example {
-    use super::*;
-    use std::sync::Mutex;
-
-    /// Example of a MetalView that renders an animated scene
-    pub struct AnimatedMetalView {
-        device: Device,
-        pipeline_state: RenderPipelineState,
-        frame_count: Arc<Mutex<f32>>,
-    }
 
-    impl AnimatedMetalView {
-        pub fn create_animated_renderer(&self) -> MetalRenderCallback {
-            let pipeline_state = self.pipeline_state.clone();
-            let frame_count = self.frame_count.clone();
-
-            Arc::new(
-                move |encoder: &RenderCommandEncoderRef,
-                      _target: &TextureRef,
-                      bounds: Bounds<Pixels>,
-                      scale_factor: f32| {
-                    // Update animation state
-                    let mut count = frame_count.lock().unwrap();
-                    *count += 0.01;
-                    let time = *count;
-
-                    // Set pipeline and viewport
-                    encoder.set_render_pipeline_state(&pipeline_state);
-
-                    let viewport = metal::MTLViewport {
-                        originX: bounds.origin.x.0 as f64 * scale_factor as f64,
-                        originY: bounds.origin.y.0 as f64 * scale_factor as f64,
-                        width: bounds.size.width.0 as f64 * scale_factor as f64,
-                        height: bounds.size.height.0 as f64 * scale_factor as f64,
-                        znear: 0.0,
-                        zfar: 1.0,
-                    };
-                    encoder.set_viewport(viewport);
-
-                    // Pass time as a uniform
-                    encoder.set_vertex_bytes(
-                        0,
-                        std::mem::size_of::<f32>() as u64,
-                        &time as *const f32 as *const _,
-                    );
-
-                    // Draw animated geometry
-                    encoder.draw_primitives(MTLPrimitiveType::TriangleStrip, 0, 4);
-                },
-            )
-        }
-    }
+        cx.activate(false);
+    });
 }
-
-// Example usage in a component:
-// ```rust
-// struct MyApp {
-//     metal_renderer: Option<MetalRenderCallback>,
-// }
-//
-// impl Render for MyApp {
-//     fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-//         div()
-//             .child(
-//                 metal_view()
-//                     .render_with(|encoder, target, bounds, scale_factor| {
-//                         // Your custom Metal rendering code here
-//                     })
-//                     .size_full()
-//             )
-//     }
-// }
-// ```

crates/gpui/examples/metal_view_quad.rs 🔗

@@ -1,355 +0,0 @@
-use gpui::{prelude::*, *};
-use std::sync::Arc;
-
-#[cfg(target_os = "macos")]
-use metal::{Device, MTLPrimitiveType, RenderCommandEncoderRef, RenderPipelineState, TextureRef};
-
-struct MetalQuadExample {
-    #[cfg(target_os = "macos")]
-    pipeline_state: Option<RenderPipelineState>,
-    #[cfg(target_os = "macos")]
-    device: Option<Device>,
-}
-
-impl MetalQuadExample {
-    fn new() -> Self {
-        Self {
-            #[cfg(target_os = "macos")]
-            pipeline_state: None,
-            #[cfg(target_os = "macos")]
-            device: None,
-        }
-    }
-
-    #[cfg(target_os = "macos")]
-    fn setup_metal(&mut self) {
-        let device = Device::system_default().expect("no Metal device");
-
-        // Shader that properly handles viewport transformation
-        let shader_source = r#"
-            #include <metal_stdlib>
-            using namespace metal;
-
-            struct Uniforms {
-                float2 viewport_size;
-            };
-
-            struct VertexOut {
-                float4 position [[position]];
-                float4 color;
-            };
-
-            vertex VertexOut vertex_main(
-                uint vid [[vertex_id]],
-                constant Uniforms& uniforms [[buffer(0)]]
-            ) {
-                VertexOut out;
-
-                // Define a quad in pixel coordinates (0,0 to viewport_size)
-                float2 positions[6] = {
-                    float2(0.0, 0.0),                                      // top-left
-                    float2(uniforms.viewport_size.x, 0.0),                // top-right
-                    float2(0.0, uniforms.viewport_size.y),                // bottom-left
-                    float2(uniforms.viewport_size.x, 0.0),                // top-right
-                    float2(uniforms.viewport_size.x, uniforms.viewport_size.y), // bottom-right
-                    float2(0.0, uniforms.viewport_size.y),                // bottom-left
-                };
-
-                // Transform from pixel coordinates to normalized device coordinates
-                float2 pos = positions[vid];
-                float2 ndc = (pos / uniforms.viewport_size) * 2.0 - 1.0;
-                ndc.y = -ndc.y; // Flip Y axis to match screen coordinates
-
-                out.position = float4(ndc, 0.0, 1.0);
-
-                // Create a nice gradient
-                float2 uv = pos / uniforms.viewport_size;
-                out.color = float4(
-                    uv.x,           // Red increases left to right
-                    uv.y,           // Green increases top to bottom
-                    1.0 - uv.x,     // Blue decreases left to right
-                    1.0             // Full opacity
-                );
-
-                return out;
-            }
-
-            fragment float4 fragment_main(VertexOut in [[stage_in]]) {
-                return in.color;
-            }
-        "#;
-
-        let library = device
-            .new_library_with_source(shader_source, &metal::CompileOptions::new())
-            .expect("Failed to create shader library");
-
-        let vertex_function = library.get_function("vertex_main", None).unwrap();
-        let fragment_function = library.get_function("fragment_main", None).unwrap();
-
-        // Create pipeline state
-        let pipeline_descriptor = metal::RenderPipelineDescriptor::new();
-        pipeline_descriptor.set_vertex_function(Some(&vertex_function));
-        pipeline_descriptor.set_fragment_function(Some(&fragment_function));
-
-        let color_attachment = pipeline_descriptor
-            .color_attachments()
-            .object_at(0)
-            .unwrap();
-        color_attachment.set_pixel_format(metal::MTLPixelFormat::BGRA8Unorm);
-
-        // Enable blending
-        color_attachment.set_blending_enabled(true);
-        color_attachment.set_source_rgb_blend_factor(metal::MTLBlendFactor::SourceAlpha);
-        color_attachment
-            .set_destination_rgb_blend_factor(metal::MTLBlendFactor::OneMinusSourceAlpha);
-        color_attachment.set_source_alpha_blend_factor(metal::MTLBlendFactor::One);
-        color_attachment
-            .set_destination_alpha_blend_factor(metal::MTLBlendFactor::OneMinusSourceAlpha);
-
-        let pipeline_state = device
-            .new_render_pipeline_state(&pipeline_descriptor)
-            .expect("Failed to create pipeline state");
-
-        self.device = Some(device);
-        self.pipeline_state = Some(pipeline_state);
-    }
-
-    #[cfg(target_os = "macos")]
-    fn create_render_callback(&self) -> MetalRenderCallback {
-        let pipeline_state = self.pipeline_state.clone().unwrap();
-
-        Arc::new(
-            move |encoder: &RenderCommandEncoderRef,
-                  _target: &TextureRef,
-                  bounds: Bounds<Pixels>,
-                  scale_factor: f32| {
-                // Set the pipeline state
-                encoder.set_render_pipeline_state(&pipeline_state);
-
-                // Set viewport to match element bounds
-                let viewport = metal::MTLViewport {
-                    originX: bounds.origin.x.0 as f64 * scale_factor as f64,
-                    originY: bounds.origin.y.0 as f64 * scale_factor as f64,
-                    width: bounds.size.width.0 as f64 * scale_factor as f64,
-                    height: bounds.size.height.0 as f64 * scale_factor as f64,
-                    znear: 0.0,
-                    zfar: 1.0,
-                };
-                encoder.set_viewport(viewport);
-
-                // Set scissor rectangle to clip to bounds
-                let scissor_rect = metal::MTLScissorRect {
-                    x: (bounds.origin.x.0 * scale_factor) as u64,
-                    y: (bounds.origin.y.0 * scale_factor) as u64,
-                    width: (bounds.size.width.0 * scale_factor) as u64,
-                    height: (bounds.size.height.0 * scale_factor) as u64,
-                };
-                encoder.set_scissor_rect(scissor_rect);
-
-                // Pass viewport size as uniform
-                #[repr(C)]
-                struct Uniforms {
-                    viewport_size: [f32; 2],
-                }
-
-                let uniforms = Uniforms {
-                    viewport_size: [
-                        bounds.size.width.0 * scale_factor,
-                        bounds.size.height.0 * scale_factor,
-                    ],
-                };
-
-                encoder.set_vertex_bytes(
-                    0,
-                    std::mem::size_of::<Uniforms>() as u64,
-                    &uniforms as *const Uniforms as *const _,
-                );
-
-                // Draw the quad
-                encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 6);
-            },
-        )
-    }
-}
-
-impl Render for MetalQuadExample {
-    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
-        #[cfg(target_os = "macos")]
-        if self.pipeline_state.is_none() {
-            self.setup_metal();
-        }
-
-        div()
-            .flex()
-            .flex_col()
-            .bg(rgb(0x1e1e1e))
-            .size_full()
-            .p_8()
-            .gap_6()
-            .child(
-                div()
-                    .child("Metal Quad Example")
-                    .text_2xl()
-                    .text_color(rgb(0xffffff)),
-            )
-            .child(
-                div()
-                    .child("This example demonstrates proper coordinate handling in MetalView")
-                    .text_color(rgb(0xaaaaaa)),
-            )
-            .child(
-                div()
-                    .flex()
-                    .gap_4()
-                    .child(
-                        div()
-                            .flex_col()
-                            .gap_2()
-                            .flex_1()
-                            .child(
-                                div()
-                                    .child("Small MetalView (200x150)")
-                                    .text_sm()
-                                    .text_color(rgb(0xcccccc)),
-                            )
-                            .child(
-                                div()
-                                    .border_1()
-                                    .border_color(rgb(0x444444))
-                                    .rounded_md()
-                                    .overflow_hidden()
-                                    .child(
-                                        #[cfg(target_os = "macos")]
-                                        {
-                                            let callback = self.create_render_callback();
-                                            metal_view()
-                                                .render_with_shared(callback)
-                                                .w(px(200.0))
-                                                .h(px(150.0))
-                                                .bg(rgb(0x000000))
-                                        },
-                                        #[cfg(not(target_os = "macos"))]
-                                        {
-                                            div()
-                                                .w(px(200.0))
-                                                .h(px(150.0))
-                                                .bg(rgb(0x222222))
-                                                .flex()
-                                                .items_center()
-                                                .justify_center()
-                                                .child(
-                                                    div()
-                                                        .child("Metal (macOS only)")
-                                                        .text_color(rgb(0x666666)),
-                                                )
-                                        },
-                                    ),
-                            ),
-                    )
-                    .child(
-                        div()
-                            .flex_col()
-                            .gap_2()
-                            .flex_1()
-                            .child(
-                                div()
-                                    .child("Large MetalView (400x300)")
-                                    .text_sm()
-                                    .text_color(rgb(0xcccccc)),
-                            )
-                            .child(
-                                div()
-                                    .border_1()
-                                    .border_color(rgb(0x444444))
-                                    .rounded_md()
-                                    .overflow_hidden()
-                                    .child(
-                                        #[cfg(target_os = "macos")]
-                                        {
-                                            let callback = self.create_render_callback();
-                                            metal_view()
-                                                .render_with_shared(callback)
-                                                .w(px(400.0))
-                                                .h(px(300.0))
-                                                .bg(rgb(0x000000))
-                                        },
-                                        #[cfg(not(target_os = "macos"))]
-                                        {
-                                            div()
-                                                .w(px(400.0))
-                                                .h(px(300.0))
-                                                .bg(rgb(0x222222))
-                                                .flex()
-                                                .items_center()
-                                                .justify_center()
-                                                .child(
-                                                    div()
-                                                        .child("Metal (macOS only)")
-                                                        .text_color(rgb(0x666666)),
-                                                )
-                                        },
-                                    ),
-                            ),
-                    ),
-            )
-            .child(
-                div().p_4().bg(rgb(0x2a2a2a)).rounded_md().child(
-                    div()
-                        .flex()
-                        .flex_col()
-                        .gap_2()
-                        .child(
-                            div()
-                                .child("Key Features:")
-                                .text_base()
-                                .font_weight(FontWeight::SEMIBOLD)
-                                .text_color(rgb(0xffffff)),
-                        )
-                        .child(
-                            div()
-                                .child("• Proper coordinate transformation from pixels to NDC")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        )
-                        .child(
-                            div()
-                                .child("• Scissor rectangle to clip content to bounds")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        )
-                        .child(
-                            div()
-                                .child("• Viewport size passed as uniform to shader")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        )
-                        .child(
-                            div()
-                                .child("• Gradient fills entire MetalView bounds")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        ),
-                ),
-            )
-    }
-}
-
-fn main() {
-    Application::new().run(|cx: &mut App| {
-        let _ = cx.open_window(
-            WindowOptions {
-                window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
-                    None,
-                    size(px(900.0), px(600.0)),
-                    cx,
-                ))),
-                titlebar: Some(TitlebarOptions {
-                    title: Some("Metal Quad Example".into()),
-                    ..Default::default()
-                }),
-                ..Default::default()
-            },
-            |_window, cx| cx.new(|_cx| MetalQuadExample::new()),
-        );
-    });
-}

crates/gpui/examples/metal_view_simple.rs 🔗

@@ -1,198 +0,0 @@
-use gpui::{prelude::*, *};
-
-struct MetalViewSimpleExample {
-    show_metal_view: bool,
-}
-
-impl MetalViewSimpleExample {
-    fn new() -> Self {
-        Self {
-            show_metal_view: true,
-        }
-    }
-}
-
-impl Render for MetalViewSimpleExample {
-    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        div()
-            .flex()
-            .flex_col()
-            .bg(rgb(0x1e1e1e))
-            .size_full()
-            .p_8()
-            .gap_4()
-            .child(
-                div()
-                    .child("MetalView Simple Example")
-                    .text_2xl()
-                    .text_color(rgb(0xffffff)),
-            )
-            .child(
-                div()
-                    .flex()
-                    .gap_2()
-                    .items_center()
-                    .child(
-                        div()
-                            .id("toggle-button")
-                            .px_3()
-                            .py_1()
-                            .bg(rgb(0x3b82f6))
-                            .hover(|style| style.bg(rgb(0x2563eb)))
-                            .rounded_md()
-                            .cursor_pointer()
-                            .on_click(cx.listener(|this, _event, _window, cx| {
-                                this.show_metal_view = !this.show_metal_view;
-                                cx.notify();
-                            }))
-                            .child(div().child("Toggle MetalView").text_color(rgb(0xffffff))),
-                    )
-                    .child(
-                        div()
-                            .child(format!(
-                                "MetalView is: {}",
-                                if self.show_metal_view {
-                                    "visible"
-                                } else {
-                                    "hidden"
-                                }
-                            ))
-                            .text_color(rgb(0xaaaaaa)),
-                    ),
-            )
-            .child(
-                div()
-                    .flex()
-                    .flex_col()
-                    .gap_4()
-                    .p_4()
-                    .bg(rgb(0x2a2a2a))
-                    .rounded_md()
-                    .child(
-                        div()
-                            .child("Container with MetalView")
-                            .text_lg()
-                            .text_color(rgb(0xffffff)),
-                    )
-                    .when(self.show_metal_view, |parent| {
-                        parent.child(
-                            div()
-                                .border_2()
-                                .border_color(rgb(0x444444))
-                                .rounded_md()
-                                .overflow_hidden()
-                                .child(
-                                    #[cfg(target_os = "macos")]
-                                    {
-                                        metal_view()
-                                            .w_full()
-                                            .h(px(200.0))
-                                            .bg(rgb(0x1a1a1a))
-                                            .render_with(
-                                                |_encoder, _target, _bounds, _scale_factor| {
-                                                    // This callback would contain custom Metal rendering code
-                                                    // For now, it's just a placeholder
-                                                },
-                                            )
-                                    },
-                                    #[cfg(not(target_os = "macos"))]
-                                    {
-                                        div()
-                                            .w_full()
-                                            .h(px(200.0))
-                                            .bg(rgb(0x1a1a1a))
-                                            .flex()
-                                            .items_center()
-                                            .justify_center()
-                                            .child(
-                                                div()
-                                                    .child("MetalView (macOS only)")
-                                                    .text_color(rgb(0x666666)),
-                                            )
-                                    },
-                                ),
-                        )
-                    })
-                    .child(
-                        div()
-                            .flex()
-                            .gap_4()
-                            .child(
-                                div().flex_1().p_3().bg(rgb(0x333333)).rounded_md().child(
-                                    div()
-                                        .child("Regular GPUI content")
-                                        .text_sm()
-                                        .text_color(rgb(0xcccccc)),
-                                ),
-                            )
-                            .child(
-                                div().flex_1().p_3().bg(rgb(0x333333)).rounded_md().child(
-                                    div()
-                                        .child("Can be mixed with MetalView")
-                                        .text_sm()
-                                        .text_color(rgb(0xcccccc)),
-                                ),
-                            ),
-                    ),
-            )
-            .child(
-                div().mt_4().p_4().bg(rgb(0x2a2a2a)).rounded_md().child(
-                    div()
-                        .flex()
-                        .flex_col()
-                        .gap_2()
-                        .child(
-                            div()
-                                .child("Notes:")
-                                .text_base()
-                                .font_weight(FontWeight::SEMIBOLD)
-                                .text_color(rgb(0xffffff)),
-                        )
-                        .child(
-                            div()
-                                .child("• MetalView integrates with GPUI's layout system")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        )
-                        .child(
-                            div()
-                                .child("• It can be styled with the same methods as other elements")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        )
-                        .child(
-                            div()
-                                .child("• On macOS, it would render custom Metal content")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        )
-                        .child(
-                            div()
-                                .child("• On other platforms, a fallback can be provided")
-                                .text_sm()
-                                .text_color(rgb(0xaaaaaa)),
-                        ),
-                ),
-            )
-    }
-}
-
-fn main() {
-    Application::new().run(|cx: &mut App| {
-        let _ = cx.open_window(
-            WindowOptions {
-                window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
-                    None,
-                    size(px(800.0), px(600.0)),
-                    cx,
-                ))),
-                titlebar: Some(TitlebarOptions {
-                    title: Some("MetalView Simple Example".into()),
-                    ..Default::default()
-                }),
-                ..Default::default()
-            },
-            |_window, cx| cx.new(|_cx| MetalViewSimpleExample::new()),
-        );
-    });
-}