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

  • d_k_bo@feddit.org
    link
    fedilink
    arrow-up
    5
    ·
    edit-2
    2 months ago

    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()
    }
    
    • Doods@infosec.pubOP
      link
      fedilink
      arrow-up
      5
      ·
      2 months ago

      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.

      • zlatko@programming.dev
        link
        fedilink
        arrow-up
        3
        ·
        2 months ago

        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.

        • d_k_bo@feddit.org
          link
          fedilink
          arrow-up
          1
          ·
          2 months ago

          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.

        • zlatko@programming.dev
          link
          fedilink
          arrow-up
          1
          ·
          1 month ago

          (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).

      • d_k_bo@feddit.org
        link
        fedilink
        arrow-up
        2
        ·
        2 months ago

        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.

        • Doods@infosec.pubOP
          link
          fedilink
          arrow-up
          1
          ·
          2 months ago

          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.

  • Doods@infosec.pubOP
    link
    fedilink
    arrow-up
    2
    ·
    2 months ago

    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

    • BB_C@programming.dev
      link
      fedilink
      arrow-up
      1
      arrow-down
      1
      ·
      2 months ago

      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?

      • Doods@infosec.pubOP
        link
        fedilink
        arrow-up
        5
        ·
        2 months ago

        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.