It might be lack of sleep, but I can’t figure this out.

I have a Label, and I want its text to be red when it represents an error, and I want it be green when it represent “good to go”.

I found search result for C and maybe a solution for Python, but nothing for Rust.

I tried manually setting the css-classes property and running queue_draw(); it didn’t work.

I can have a gtk::Box or a Frame that I place where the Label should go, then declare two Labels, and use set_child() to switch between them, but that seems like an ugly solution.

Do you have a solution?

SOLVED:

I have to add a “.” before declaring a CSS “thing” for it to be considered a class.

Ex:

.overlay {
        background: rgba(60, 60, 60, 1);
        font-size: 25px;
}

instead of:

overlay {
        background: rgba(60, 60, 60, 1);
        font-size: 25px;)
}

Just use label.add_css_class(), label.remove_css_class() or label.set_css_classes() and make sure to properly load your CSS style sheets,

Source: the comment of d_k_bo@feddit.org

5 points
*

Just use label.add_css_class(), label.remove_css_class() or label.set_css_classes() and make sure to properly load your CSS style sheets, this is usually done by including them as a resource alongside .ui files and icons. If you are using libadwaita, you can also use its predefined style classes.

full example (requires nightly toolchain)
#!/usr/bin/env -S cargo +nightly -Zscript
---
[dependencies]
gtk = { package = "gtk4", version = "0.9.3", features = ["v4_12"] }
---

use gtk::{glib, prelude::*};

const STYLESHEET: &str = r#"
.green {
    color: green;
}
.red {
    color: red;
}
"#;

fn main() -> glib::ExitCode {
    let app = gtk::Application::builder()
        .application_id("org.example.HelloWorld")
        .build();

    app.connect_activate(|app| {
        let window = gtk::ApplicationWindow::builder()
            .application(app)
            .title("Hello, World!")
            .build();

        // Stylesheets are usually bundled with application resources
        // and automatically loaded
        let css_provider = gtk::CssProvider::new();
        css_provider.load_from_string(STYLESHEET);
        gtk::style_context_add_provider_for_display(
            &RootExt::display(&window),
            &css_provider,
            0
        );

        let box_ = gtk::Box::new(gtk::Orientation::Vertical, 6);

        let label = gtk::Label::builder()
            .label("Hello, World")
            .css_classes(["green"].as_slice())
            .build();
        box_.append(&label);


        let button = gtk::Button::builder()
            .label("Toggle Color")
            .build();
        box_.append(&button);

        button.connect_clicked(glib::clone!(#[weak] label, move |_| {
            if label.has_css_class("red") {
                label.add_css_class("green");
                label.remove_css_class("red");
            } else {
                label.add_css_class("red");
                label.remove_css_class("green");
            }
        }));

        window.set_child(Some(&box_));
        window.present();
    });

    app.run()
}
permalink
report
reply
5 points

This is embarrassing, but when was it not?

I have to add a “.” before the name of a css class, I must learn my tools.

permalink
report
parent
reply
3 points

I mean, it is not embarrassing for you. In the browser, the CSS’s “native platform”, you add classes, via the JavaScript API, without the dot. It’s not a stupid assumption.

To have to add the dot in the CSS class name seems a bit of an oversight in the gtkrs API.

permalink
report
parent
reply
1 point

(sorry for the late response, I have to get in the habit of checking my Lemmy account)

No, I get that - a stylesheet denotes a class by having a dot. A JavaScript API for adding a CSS class omits this redundancy.

I was saying that the author might not be wrong to want to avoid the redundancy in rust example as well (since it explicitly mentions CSS classes).

permalink
report
parent
reply
1 point

I think you understood their comment wrong. In your code (e.g. label.add_css_class("green");) you don’t use a dot, but in the CSS stylesheet. It works the same as with HTML/JS/CSS.

permalink
report
parent
reply
2 points

Well, that’s CSS :D

Note that if you create a custom Widget class, you can set a CSS name, wich isn’t a CSS class and doesn’t use a leading dot.

permalink
report
parent
reply
1 point

you can set a CSS name, wich isn’t a CSS class and doesn’t use a leading dot.

Yeah that’s what I’ve been using all along.

permalink
report
parent
reply
1 point

@Doods my blog note is not showing up in Lemmy.

I’ve tried this quickly and you can use pango markup (https://docs.gtk.org/Pango/pango_markup.html) to change the text color in the label.

Here is a snippet with a label and a button that changes the text color from blue to red.

Here you can find the snippet: https://blog.libove.org/posts/454ace46-64f1-4f7f-a03f-4183430a8d68/

permalink
report
reply
2 points

Before anyone suggests another library:

  • Iced and Egui both can’t handle Arabic, which is a deal breaker.
  • Iced takes forever to compile and iterate, maybe that’ll be fixed with dynamic linking.
  • Relm: I didn’t know it existed before I started this project.
  • Qt bindings: IDK I forgot Qt existed, I was always more of GNOME* guy.
  • I am already pretty deep into this project, and don’t want to learn something else for now.

* GNU Network Object something Environment

permalink
report
reply
0 points

Use libcosmic 😑

No, but seriously… skip to the end.

Iced and Egui both can’t handle Arabic, which is a deal breaker.

Iced can handle Arabic shaping-wise when cosmic-text is used, but it can’t handle the direction (yet). If you only need it for the interface, a shit workaround would be to prefix all text with an RLM (RIGHT-TO-LEFT Mark). This would left-align all text of course.

Iced takes forever to compile and iterate, maybe that’ll be fixed with dynamic linking.

Fast iteration is already fixed by using cranelift in your release-dev profile (or whatever you want to call it), and mold as a linker. The binary will be slower, but iteration will be much much faster.


Okay, something helpful instead: Did you try asking in the rust:gnome.org matrix room mentioned in the project page?

permalink
report
parent
reply
5 points

If you only need it for the interface, a shit workaround would be to prefix all text with an RLM (RIGHT-TO-LEFT Mark).

Unfortunately no, I expect users to enter Arabic text as well.

Fast iteration is already fixed by using cranelift in your release-dev profile (or whatever you want to call it), and mold as a linker.

Maybe, I didn’t try that before, but I don’t expect Cranelift to match the speeds gtk-rs is currently giving me; Cranelift also doesn’t solve the problem of rust-analyzer acting crazy.

Okay, something helpful instead: Did you try asking in the rust:gnome.org matrix room mentioned in the project page?

No, I prefer public posts to prevent effort duplication, so much so that my mind started filtering out such things on project pages, but thanks for reminding me.

permalink
report
parent
reply

Rust

!rust@programming.dev

Create post

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits
  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

Community stats

  • 503

    Monthly active users

  • 285

    Posts

  • 1.3K

    Comments