From d80959d64e7e2b13cc33e3ec6114fc568982c0fc Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 23 Jan 2024 21:29:12 -0800 Subject: [PATCH 1/5] Add module documentation to GPUI and make gpui.rs example compile --- crates/gpui/src/color.rs | 5 ++- crates/gpui/src/elements/div.rs | 7 ---- crates/gpui/src/elements/text.rs | 12 +++++++ crates/gpui/src/gpui.rs | 62 +++++++++++++++++++++++--------- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/crates/gpui/src/color.rs b/crates/gpui/src/color.rs index dadc3d5ad301ba3cd2145215bb7909701fd9ed27..caf7cddf69a09c314096e56115de00f60be7aac5 100644 --- a/crates/gpui/src/color.rs +++ b/crates/gpui/src/color.rs @@ -3,11 +3,11 @@ use serde::de::{self, Deserialize, Deserializer, Visitor}; use std::fmt; /// Convert an RGB hex color code number to a color type -pub fn rgb>(hex: u32) -> C { +pub fn rgb(hex: u32) -> Rgba { let r = ((hex >> 16) & 0xFF) as f32 / 255.0; let g = ((hex >> 8) & 0xFF) as f32 / 255.0; let b = (hex & 0xFF) as f32 / 255.0; - Rgba { r, g, b, a: 1.0 }.into() + Rgba { r, g, b, a: 1.0 } } /// Convert an RGBA hex color code number to [`Rgba`] @@ -40,7 +40,6 @@ impl fmt::Debug for Rgba { impl Rgba { /// Create a new [`Rgba`] color by blending this and another color together - /// TODO!(docs): find the source for this algorithm pub fn blend(&self, other: Rgba) -> Self { if other.a >= 1.0 { other diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index 4a951fb48dddabab7ae42a22a78fa8d6354a6f5f..a0bbf6fc7948095adcc175f9cfb81ef3c1c88743 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -14,13 +14,6 @@ //! as several associated traits. Together, these provide the full suite of Dom-like events //! and Tailwind-like styling that you can use to build your own custom elements. Div is //! constructed by combining these two systems into an all-in-one element. -//! -//! # Capturing and bubbling -//! -//! Note that while event dispatch in GPUI uses similar names and concepts to the web -//! even API, the details are very different. See the documentation in [TODO!(docs) -//! DOCUMENT EVENT DISPATCH SOMEWHERE IN WINDOW CONTEXT] for more details -//! use crate::{ point, px, size, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, Bounds, diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 13fc6200766edc068af5f23defc3d9c2e73c4214..2b5bf9166ef2182dca7cae92f93a3e7a91af5925 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -46,6 +46,18 @@ impl IntoElement for &'static str { } } +impl IntoElement for String { + type Element = SharedString; + + fn element_id(&self) -> Option { + None + } + + fn into_element(self) -> Self::Element { + self.into() + } +} + impl Element for SharedString { type State = TextState; diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 8ecfd8ad6d834ac8c6577e2f724e22719e15e36e..5e5618721b97ac100365d24e48af44d6803f9e4d 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -1,30 +1,60 @@ //! # Welcome to GPUI! //! //! GPUI is a hybrid immediate and retained mode, GPU accelerated, UI framework -//! for Rust, designed to support a wide variety of applications. GPUI is currently -//! being actively developed and improved for the [Zed code editor](https://zed.dev/), and new versions -//! will have breaking changes. You'll probably need to use the latest stable version -//! of rust to use GPUI. +//! for Rust, designed to support a wide variety of applications. //! -//! # Getting started with GPUI +//! ## Getting Started //! -//! TODO!(docs): Write a code sample showing how to create a window and render a simple -//! div +//! GPUI is still in active development as we work on the Zed code editor and isn't yet on crates.io. +//! You'll also need to use the latest version of stable rust. Add the following to your Cargo.toml: //! -//! # Drawing interesting things +//! gpui = { git = "https://github.com/zed-industries/zed" } //! -//! TODO!(docs): Expand demo to show how to draw a more interesting scene, with -//! a counter to store state and a button to increment it. +//! Everything in GPUI starts with an [`App`]. You can create one with [`App::new`], and +//! kick off your application by passing a callback to [`App::run`]. Inside this callback, +//! you can create a new window with [`AppContext::open_window`], and register your first root +//! view. See [gpui.rs](https://www.gpui.rs/) for a complete example. //! -//! # Interacting with your application state +//! ## The Big Picture //! -//! TODO!(docs): Expand demo to show GPUI entity interactions, like subscriptions and entities -//! maybe make a network request to show async stuff? +//! GPUI offers three different [registers](https://en.wikipedia.org/wiki/Register_(sociolinguistics)) depending on your needs: //! -//! # Conclusion +//! - State management and communication with Models. Whenever you need to store application state +//! that communicates between different parts of your application, you'll want to use GPUI's +//! models. Models are owned by GPUI and are only accessible through an owned smart pointer +//! similar to an [`Rc`]. See the [`app::model_context`] module for more information. //! -//! TODO!(docs): Wrap up with a conclusion and links to other places? Zed / GPUI website? -//! Discord for chatting about it? Other tutorials or references? +//! - High level, declarative UI with Views. All UI in GPUI starts with a View. A view is simply +//! a model that can be rendered, via the [`Render`] trait. At the start of each frame, GPUI +//! will call this render method on the root view of a given window. Views build a tree of +//! `elements`, lay them out and style them with a tailwind-style API, and then give them to +//! GPUI to turn into pixels. See the [`div`] element for an all purpose swiss-army knife of +//! rendering. +//! +//! - Low level, imperative UI with Elements. Elements are the building blocks of UI in GPUI, and they +//! provide a nice wrapper around an imperative API that provides as much flexibility and control as +//! you need. Elements have total control over how they and their child elements are rendered and and +//! can be used for making efficient views into large lists, implement custom layouting for a code editor, +//! and anything else you can think of. See the [`element`] module for more information. +//! +//! Each of these registers has one or more corresponding contexts that can be accessed from all GPUI services. +//! This context is your main interface to GPUI, and is used extensively throughout the framework. +//! +//! ## Other Resources +//! +//! In addition to the systems above, GPUI provides a range of smaller services that are useful for building +//! complex applications: +//! +//! - Actions are user-defined structs that are used for converting keystrokes into logical operations in your UI. +//! Use this for implementing keyboard shortcuts, such as cmd-q. See the [`action`] module for more information. +//! - Platform services, such as `quit the app` or `open a URL` are available as methods on the [`app::AppContext`]. +//! - An async executor that is integrated with the platform's event loop. See the [`executor`] module for more information., +//! - The [gpui::test] macro provides a convenient way to write tests for your GPUI applications. Tests also have their +//! own kind of context, a [`TestAppContext`] which provides ways of simulating common platform input. See [`app::test_context`] +//! and [`test`] modules for more details. +//! +//! Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack. +//! We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). #![deny(missing_docs)] #![allow(clippy::type_complexity)] From ce7cd5a077e4cadedae6e3c889035a61566539cf Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 23 Jan 2024 21:35:01 -0800 Subject: [PATCH 2/5] Copy GPUI documentation to README --- crates/gpui/README.md | 42 +++++++++++++++++++++++++++++++++++++++-- crates/gpui/src/gpui.rs | 9 ++++++--- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/crates/gpui/README.md b/crates/gpui/README.md index e145946024d0a7a2c84eb1ce3a2d2129ab0ee591..cb275eb9445c541d684e1bb35d0a1cf710a36e8c 100644 --- a/crates/gpui/README.md +++ b/crates/gpui/README.md @@ -1,3 +1,41 @@ -# GPUI +# Welcome to GPUI! + +GPUI is a hybrid immediate and retained mode, GPU accelerated, UI framework +for Rust, designed to support a wide variety of applications. + +## Getting Started + +GPUI is still in active development as we work on the Zed code editor and isn't yet on crates.io. You'll also need to use the latest version of stable rust and be on macOS. Add the following to your Cargo.toml: + +``` +gpui = { git = "https://github.com/zed-industries/zed" } +``` + +Everything in GPUI starts with an `App`. You can create one with `App::new()`, and kick off your application by passing a callback to `App::run()`. Inside this callback, you can create a new window with `AppContext::open_window()`, and register your first root view. See [gpui.rs](https://www.gpui.rs/) for a complete example. + +## The Big Picture + +GPUI offers three different registers(https://en.wikipedia.org/wiki/Register_(sociolinguistics)) depending on your needs: + +- State management and communication with Models. Whenever you need to store application state that communicates between different parts of your application, you'll want to use GPUI's models. Models are owned by GPUI and are only accessible through an owned smart pointer similar to an `Rc`. See the `app::model_context` module for more information. + +- High level, declarative UI with Views. All UI in GPUI starts with a View. A view is simply a model that can be rendered, via the `Render` trait. At the start of each frame, GPUI will call this render method on the root view of a given window. Views build a tree of `elements`, lay them out and style them with a tailwind-style API, and then give them to GPUI to turn into pixels. See the `div` element for an all purpose swiss-army knife of rendering. + +- Low level, imperative UI with Elements. Elements are the building blocks of UI in GPUI, and they provide a nice wrapper around an imperative API that provides as much flexibility and control as you need. Elements have total control over how they and their child elements are rendered and and can be used for making efficient views into large lists, implement custom layouting for a code editor, and anything else you can think of. See the `element` module for more information. + +Each of these registers has one or more corresponding contexts that can be accessed from all GPUI services. This context is your main interface to GPUI, and is used extensively throughout the framework. + +## Other Resources + +In addition to the systems above, GPUI provides a range of smaller services that are useful for building complex applications: + +- Actions are user-defined structs that are used for converting keystrokes into logical operations in your UI. Use this for implementing keyboard shortcuts, such as cmd-q. See the `action` module for more information. + +- Platform services, such as `quit the app` or `open a URL` are available as methods on the `app::AppContext`. + +- An async executor that is integrated with the platform's event loop. See the `executor` module for more information., + +- The `[gpui::test]` macro provides a convenient way to write tests for your GPUI applications. Tests also have their own kind of context, a `TestAppContext` which provides ways of simulating common platform input. See `app::test_context` and `test` modules for more details. + +Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack. We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). -A fast, productive UI framework from the creators of [https://zed.dev]. diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 5e5618721b97ac100365d24e48af44d6803f9e4d..f821ba34ef735ce3e867791953c909313742c47c 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -6,9 +6,12 @@ //! ## Getting Started //! //! GPUI is still in active development as we work on the Zed code editor and isn't yet on crates.io. -//! You'll also need to use the latest version of stable rust. Add the following to your Cargo.toml: +//! You'll also need to use the latest version of stable rust and be on macOS. Add the following to your +//! Cargo.toml: //! +//! ``` //! gpui = { git = "https://github.com/zed-industries/zed" } +//! ``` //! //! Everything in GPUI starts with an [`App`]. You can create one with [`App::new`], and //! kick off your application by passing a callback to [`App::run`]. Inside this callback, @@ -28,8 +31,8 @@ //! a model that can be rendered, via the [`Render`] trait. At the start of each frame, GPUI //! will call this render method on the root view of a given window. Views build a tree of //! `elements`, lay them out and style them with a tailwind-style API, and then give them to -//! GPUI to turn into pixels. See the [`div`] element for an all purpose swiss-army knife of -//! rendering. +//! GPUI to turn into pixels. See the [`elements::Div`] element for an all purpose swiss-army +//! knife for UI. //! //! - Low level, imperative UI with Elements. Elements are the building blocks of UI in GPUI, and they //! provide a nice wrapper around an imperative API that provides as much flexibility and control as From 1facc9fc116e3aeeacfb7ce2b3ef252eb79554cc Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 23 Jan 2024 21:38:16 -0800 Subject: [PATCH 3/5] Fix test error --- crates/theme/src/styles/colors.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/theme/src/styles/colors.rs b/crates/theme/src/styles/colors.rs index a01e73f5ef3e47820c2aa58ae07db842584e3767..b830d19fee1faeaa6ce01b79850a72277a309a01 100644 --- a/crates/theme/src/styles/colors.rs +++ b/crates/theme/src/styles/colors.rs @@ -261,7 +261,7 @@ mod tests { fn override_a_single_theme_color() { let mut colors = ThemeColors::light(); - let magenta: Hsla = gpui::rgb(0xff00ff); + let magenta: Hsla = gpui::rgb(0xff00ff).into(); assert_ne!(colors.text, magenta); @@ -279,8 +279,8 @@ mod tests { fn override_multiple_theme_colors() { let mut colors = ThemeColors::light(); - let magenta: Hsla = gpui::rgb(0xff00ff); - let green: Hsla = gpui::rgb(0x00ff00); + let magenta: Hsla = gpui::rgb(0xff00ff).into(); + let green: Hsla = gpui::rgb(0x00ff00).into(); assert_ne!(colors.text, magenta); assert_ne!(colors.background, green); @@ -305,7 +305,7 @@ mod tests { })) .unwrap(); - assert_eq!(colors.background, Some(gpui::rgb(0xff00ff))); - assert_eq!(colors.text, Some(gpui::rgb(0xff0000))); + assert_eq!(colors.background, Some(gpui::rgb(0xff00ff).into())); + assert_eq!(colors.text, Some(gpui::rgb(0xff0000).into())); } } From fa6acc385f619371c4d8c0faad86ce77094aa44a Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 23 Jan 2024 21:41:06 -0800 Subject: [PATCH 4/5] Add note about discord --- crates/gpui/README.md | 2 +- crates/gpui/src/gpui.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/gpui/README.md b/crates/gpui/README.md index cb275eb9445c541d684e1bb35d0a1cf710a36e8c..1ced6979863c2244e93cbde526dacc30dc563afe 100644 --- a/crates/gpui/README.md +++ b/crates/gpui/README.md @@ -37,5 +37,5 @@ In addition to the systems above, GPUI provides a range of smaller services that - The `[gpui::test]` macro provides a convenient way to write tests for your GPUI applications. Tests also have their own kind of context, a `TestAppContext` which provides ways of simulating common platform input. See `app::test_context` and `test` modules for more details. -Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack. We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). +Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack or in the [Zed Discord](https://discord.gg/U4qhCEhMXP). We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index f821ba34ef735ce3e867791953c909313742c47c..4a1cf4119328c581b5263d3b05896a760cc07d61 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -56,7 +56,7 @@ //! own kind of context, a [`TestAppContext`] which provides ways of simulating common platform input. See [`app::test_context`] //! and [`test`] modules for more details. //! -//! Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack. +//! Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack or in the [Zed Discord](https://discord.gg/U4qhCEhMXP). //! We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). #![deny(missing_docs)] From ce0ff819f915531d16a319845fd5e01b54062087 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 23 Jan 2024 21:47:44 -0800 Subject: [PATCH 5/5] Fix more tests --- crates/gpui/README.md | 3 +-- crates/gpui/src/gpui.rs | 5 +++-- crates/storybook/src/stories/z_index.rs | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/crates/gpui/README.md b/crates/gpui/README.md index 1ced6979863c2244e93cbde526dacc30dc563afe..9b087a9752a05586b97a67962b20e86c953672ec 100644 --- a/crates/gpui/README.md +++ b/crates/gpui/README.md @@ -37,5 +37,4 @@ In addition to the systems above, GPUI provides a range of smaller services that - The `[gpui::test]` macro provides a convenient way to write tests for your GPUI applications. Tests also have their own kind of context, a `TestAppContext` which provides ways of simulating common platform input. See `app::test_context` and `test` modules for more details. -Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack or in the [Zed Discord](https://discord.gg/U4qhCEhMXP). We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). - +Currently, the best way to learn about these APIs is to read the Zed source code, ask us about it at a fireside hack, or drop a question in the [Zed Discord](https://discord.gg/U4qhCEhMXP). We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). diff --git a/crates/gpui/src/gpui.rs b/crates/gpui/src/gpui.rs index 4a1cf4119328c581b5263d3b05896a760cc07d61..638e94de3969360f94b5594f06e45710cace1495 100644 --- a/crates/gpui/src/gpui.rs +++ b/crates/gpui/src/gpui.rs @@ -56,8 +56,9 @@ //! own kind of context, a [`TestAppContext`] which provides ways of simulating common platform input. See [`app::test_context`] //! and [`test`] modules for more details. //! -//! Currently, the best way to learn about these APIs is to read the Zed source code or to ask us about it at a fireside hack or in the [Zed Discord](https://discord.gg/U4qhCEhMXP). -//! We're working on improving the documentation, creating more examples, and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). +//! Currently, the best way to learn about these APIs is to read the Zed source code, ask us about it at a fireside hack, or drop +//! a question in the [Zed Discord](https://discord.gg/U4qhCEhMXP). We're working on improving the documentation, creating more examples, +//! and will be publishing more guides to GPUI on our [blog](https://zed.dev/blog). #![deny(missing_docs)] #![allow(clippy::type_complexity)] diff --git a/crates/storybook/src/stories/z_index.rs b/crates/storybook/src/stories/z_index.rs index 63ee1af7591ee8a62f07f052b320db8a70077b9d..e32e39a2d1d96c078eeada0c4e1be616ae4408ac 100644 --- a/crates/storybook/src/stories/z_index.rs +++ b/crates/storybook/src/stories/z_index.rs @@ -1,4 +1,4 @@ -use gpui::{px, rgb, Div, Hsla, IntoElement, Render, RenderOnce}; +use gpui::{px, rgb, Div, IntoElement, Render, RenderOnce}; use story::Story; use ui::prelude::*; @@ -51,22 +51,22 @@ trait Styles: Styled + Sized { self.absolute() .w(px(150.)) .h(px(50.)) - .text_color(rgb::(0x000000)) + .text_color(rgb(0x000000)) } fn blue(self) -> Self { - self.bg(rgb::(0xe5e8fc)) + self.bg(rgb(0xe5e8fc)) .border_5() - .border_color(rgb::(0x112382)) + .border_color(rgb(0x112382)) .line_height(px(55.)) // HACK: Simulate `text-align: center`. .pl(px(24.)) } fn red(self) -> Self { - self.bg(rgb::(0xfce5e7)) + self.bg(rgb(0xfce5e7)) .border_5() - .border_color(rgb::(0xe3a1a7)) + .border_color(rgb(0xe3a1a7)) // HACK: Simulate `text-align: center`. .pl(px(8.)) } @@ -92,10 +92,10 @@ impl RenderOnce for ZIndexExample { .left(px(15.)) .w(px(180.)) .h(px(230.)) - .bg(rgb::(0xfcfbe5)) - .text_color(rgb::(0x000000)) + .bg(rgb(0xfcfbe5)) + .text_color(rgb(0x000000)) .border_5() - .border_color(rgb::(0xe3e0a1)) + .border_color(rgb(0xe3e0a1)) .line_height(px(215.)) // HACK: Simulate `text-align: center`. .pl(px(24.))