I have a label in Gtk 3.0 (using Vala) that is styled with CSS. I'd like to scale the font size based on the widget's size, so that the font fills the widget/label but never gets too big.
What is the best way to do that using the CSS approach? Right now I'm setting the font to
font-size: 5em
but as far as I can tell, that does not scale with screen resolution.
For example, on a lower resolution screen, I get this (note the cut-off clock):
Previously we used an absolute scaling (see this diff for a surprisingly concise explanation) but we'd like to stick with CSS.
(more context if you're interested)
If you set a font size in ems or %, it will base itself on the default font size. The trick is to change the default font size according to the window size. Connect to the window's configure_event
, and set a new default font size when the window is resized.
Here's a simplified example:
const string WINDOW_CSS_TEMPLATE = "#mywindow { font-size: %fpx; }";
const string APPLICATION_CSS = "#mywindow .label { font-size: 5em; }";
void main(string [] args) {
Gtk.init(ref args);
var win = new Gtk.Window();
win.name = "mywindow";
win.default_width = 800;
win.default_height = 600;
var label = new Gtk.Label("Some text");
label.halign = Gtk.Align.END;
label.valign = Gtk.Align.END;
win.add(label);
win.destroy.connect(Gtk.main_quit);
var win_provider = new Gtk.CssProvider();
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
win_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
var app_provider = new Gtk.CssProvider();
try {
app_provider.load_from_data(APPLICATION_CSS, -1);
} catch (Error e) {
Process.exit(1);
}
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
app_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
win.configure_event.connect((event) => {
try {
// Replace this with your desired calculation of the base font size
var target_size = (double) event.height / 600.0 * 12.0;
var css = WINDOW_CSS_TEMPLATE.printf(target_size);
win_provider.load_from_data(css, -1);
} catch (Error e) {
Process.exit(1);
}
return Gdk.EVENT_PROPAGATE;
});
win.show_all();
Gtk.main();
}
This only cares about the height of the window, so you'll get an unreadably tiny label if you resize the window to be much wider than it is high, but you can plug in whatever calculation works for you.