> div() .flex() .flex_col() .gap_3() .bg(rgb(0x505050)) .size(px(500.0)) .justify_center() .items_center() .shadow_lg() .border_1() .border_color(rgb(0x0000ff)) .text_xl() .text_color(rgb(0xffffff)) .child(format!("Hello, {}!", &self.text)) .child( div() .flex() .gap_2() .child(div().size_8().bg(gpui::red())) .child(div().size_8().bg(gpui::green())) .child(div().size_8().bg(gpui::blue())) .child(div().size_8().bg(gpui::yellow())) .child(div().size_8().bg(gpui::black())) .child(div().size_8().bg(gpui::white())), )
[–] ogoffart 2 days ago
[–] c-smile 2 days ago
That's is not about just Rust ... Any domain has its own optimal or sub-optimal language describing it. Criteria of optimality is a bit subjective of course. Like: INI, TOML, YAML, etc. are better (YMMV, again) for user facing configs than JSON or XML and so on.
I think that HTML is better for defining hierarchical UI structures and CSS and CSS selectors are (arguably again) better to define UI styling.
My Sciter[1] was initially using .FRM alike inputs (VisualBasic forms, good for IDE but bad for a human) but I quickly discovered that having styles, structure and code-behind-UI in single PL makes non-manageable mess. So Sciter uses HTML, CSS and JS we all familiar with. Not 100% match of course but good enough.
[–] ivanmontillam 2 days ago
They have no shame in deploying a 300 MB hot mess bundle.
[–] thisismyanon2 2 days ago
Here's a more idiomatic version of the previous example. IME gpui (and iced) is a lot easier to extend than something with a DSL, and if you check out the gpui example you'll see that gpui provides convenient methods to get consistent styles vs the Slint example where you hardcode widths and sizes. Those hex color abbreviations give me a facial tic every single time.
use gpui::{black,red,green,blue,yellow,white};
let Self{text,..} = self;
v_flex()
.gap_3()
.bg(rgb(0x505050))
.size(px(500.0))
.justify_center()
.items_center()
.shadow_lg()
.border_1()
.border_color(black())
.text_xl()
.text_color(white())
.child(format!("Hello, {text}!"))
.child(
h_flex()
.gap_2()
.children(
[red(), green(), blue(), yellow(), black(), white()].map(|color|
div().size_8().bg(color)
)))[–] MisterMunchkin 2 days ago
[–] ogoffart 2 days ago
Btw, a rug pull can happen under even the most permissive licenses. As we've seen in the past with some project changing license or direction. That's more or less already happened with GPUI when Zed refocused development on its own needs rather than other GPUI users resulting in several forks.
[–] IshKebab 2 days ago
It even added ANSI colour support... which I am still on the fence about but it did make the very good point that it means the logging is exactly the same in GUI and CLI mode.
[–] LittleLily 2 days ago
[–] ordu 2 days ago
I'd like to know it. I don't think that it can be substantially better. You have to compromise between the amount of customization you are allowed to do and the amount of options you have to pick values for.
I can't vouch for GPUI, I don't know how good its compromise is, but it bears enough similarities to other modern UI-toolkits. I don't think there is a better way, but if you know one, I'd like to know about it.
And, well, don't forget, it is a front-page example, that is not necessarily an example how one should compose their code, it demonstrates what you can do with GPUI. In real life code you'd probably move those children's construction into separate named functions, maybe you'd use some predefined styles to apply to individual elements, instead of picking fg/bg/text-colors, maybe sizes and some other attributes for each one explicitly, and maybe some other tricks.
[–] eviks 2 days ago
Instead of
.border_1().border_color(rgb(0x0000ff))
You get
.border(1 0x0000ff)
(guess, this can only be in a macro)
Or at least have "color" which understands that it's allied to border instead of having to repeat "border"
> I don't think that it can be substantially better
Don't give up too early, there is no way it can't be, we don't really have any good systems optimized for ergonomics to reach anything great
[–] c-smile 2 days ago
After 10 or so of those you'll start dreaming of
border-left: 2px solid rgb(0 0 100%);
right?[–] eviks 2 days ago
┠
or more explicitly
├2
that'd be perfectly paired with a dream-like visual designer that doesn't exist?
[–] tcallred 2 days ago
[–] CupricTea 2 days ago
[–] odo1242 2 days ago
Also, this is basically what Tailwind code looks like.
[–] ijustlovemath 2 days ago
[–] kalleboo 2 days ago
[–] selfmodruntime 1 day ago
[–] desolate_muffin 2 days ago
[–] Jonovono 2 days ago
[–] satvikpendem 2 days ago
[–] tomburgs 2 days ago
On a more serious note I feel like it's not bad but could be improved if they managed to break it down by styling domain (sort of like SwiftUI).
Something along the lines of .flex(gap: 2).text(size: "xl", color: ...)
Your example would look like this:
More on why we chose a DSL vs code in Rust: https://slint.dev/blog/domain-specific-language-vs-imperativ...