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 Label
s, 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
Before anyone suggests another library:
Iced
andEgui
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 forgotQt
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
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
matrix room mentioned in the project page?
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
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.
@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/
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()
}
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.
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.
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.
(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).