Reputation: 33
I am not able to change the colour of the progress element in the GtkProgressBar using CSS. I have tried different combinations to reference this progress bar such as the below but to no avail. I have attached a minimum example C program, Glade file and CSS file where CSS attempt 4 is currently active to demonstrate that all elements are affected except this progress bar.
/* attempt 1 */
#gtkprogressbar1 {
color: rgba(83,165,198,255);
background-color: rgba(83,165,198,255);
}
/* attempt 2 */
#progressbar * {
color: rgba(83,165,198,255);
background-color: rgba(83,165,198,255);
}
/* attempt 3 */
GtkProgressBar * {
color: rgba(83,165,198,255);
background-color: rgba(83,165,198,255);
}
/* attempt 4 */
* {
color: rgba(83,165,198,255);
background-color: rgba(83,165,198,255);
}
C Program: Save as progressbar.c
/* Compile as follows:
* gcc -o PROGRESS progressbar.c -g `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0` -pthread `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0` -export-dynamic
*/
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
GtkWidget *button_on;
GtkWidget *progressbar1;
time_t time_start;
time_t time_finish;
} app_gui;
void set_progress_bar (app_gui *gui);
void adding_timer (app_gui *gui);
void set_css (void);
int main (int argc, char *argv[]) {
GtkBuilder *builder = g_slice_new (GtkBuilder);
GtkWidget *window;
GError *gtk_error = NULL;
app_gui *gui = g_slice_new (app_gui);
gui->time_start = time (NULL);
gui->time_finish = gui->time_start + 60; // 60 seconds progress bar
printf("%s%lu\n", "button click: Time start at button click is ", gui->time_start);
printf("%s%lu\n", "button click: Time finish at button click is ", gui->time_finish);
gtk_init (&argc, &argv);
set_css ();
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, "progressbar_main.glade", NULL)) {
fprintf (stdout, "%s%s\n", "Error loading file with the reason: ", gtk_error->message);
g_free (gtk_error);
exit (EXIT_FAILURE);
}
window = GTK_WIDGET (gtk_builder_get_object (builder, "window_main"));
gui->button_on = GTK_WIDGET (gtk_builder_get_object (builder, "button_on"));
gui->progressbar1 = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar1"));
gtk_builder_connect_signals (builder, gui);
g_object_unref (builder);
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE, 1, (GSourceFunc)set_progress_bar,
gui, (GDestroyNotify)adding_timer);
gtk_widget_show (window);
gtk_main ();
g_slice_free (app_gui, gui);
return 0;
}
void set_css (void) {
GtkCssProvider *css_provider;
GdkDisplay *display;
GdkScreen *screen;
const char *css_file = "style.css";
GError *error = NULL;
css_provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_css_provider_load_from_file(css_provider, g_file_new_for_path (css_file), &error);
g_object_unref (css_provider);
}
void adding_timer (app_gui *gui) {
g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE, 1, (GSourceFunc)set_progress_bar,
gui, (GDestroyNotify)adding_timer);
}
void set_progress_bar (app_gui *gui) {
time_t time_now = time (NULL);
double progress = 1.00 - (((gui->time_finish * 1.0) - time_now)/60.0);
printf("%s%f\n", "set progress: Progress is ", progress);
if (progress >= 1.00) {
EXIT_SUCCESS;
}
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (gui->progressbar1), progress);
}
void on_window_main_destroy () {
gtk_main_quit ();
}
Glade File: Save as progressbar_main.glade
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window_main">
<property name="can_focus">False</property>
<signal name="destroy" handler="on_window_main_destroy" swapped="no"/>
<child>
<object class="GtkFixed" id="fixed1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button_on">
<property name="label" translatable="yes">ON</property>
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="x">48</property>
<property name="y">75</property>
</packing>
</child>
<child>
<object class="GtkViewport" id="viewport1">
<property name="width_request">200</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTextView" id="textview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
</object>
<packing>
<property name="x">201</property>
<property name="y">75</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progressbar1">
<property name="width_request">200</property>
<property name="height_request">-1</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="x">53</property>
<property name="y">31</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
CSS File: Save as style.css
* {
color: rgba(83,165,198,255);
background-color: rgba(83,165,198,255);
}
Thank you for any assistance offered.
Upvotes: 1
Views: 2106
Reputation: 6792
All of your attempts to select the ProgressBar widget are wrong:
progressbar1
is the id
, not the name
, and it's Glade's name
that gets used as the CSS ID. Confusing, right? Anyway, it's not gtkprogressbar1
, so that wouldn't work regardless.#widgetclass
, e.g. #progressbar
, is never used by GTK+ as the CSS ID is per-element, not per-class, and only one widget per process should have the same CSS name, but all GtkProgressBars would in this hypothetical.GtkProgressBar
style names are the old style, pre 3.18ish, and I presume you're not using so old a version (but you can try substituting it if you are).The CSS node name, as of now, is progressbar
, not GtkProgressBar
. The same pattern applies to other widgets: all nodes named GtkWhatever
are now named whatever
generally, with a few minor exceptions (e.g. GtkListBox
is list
).
So that's one problem. Your second is that your attempts to change the colour are not using specific enough selectors and therefore are being overridden by whatever theme you're using applying more specific selectors than *
- which is to say: all of them.
Even if your colour would take effect this way, it would have to apply to the whole widget, which is obviously wrong.
Read the documentation to learn the proper CSS node names and hierarchies, and select on something more specific, e.g.:
progressbar > trough > progress
is the most specific variant.
That said, if you prefer brevity, I just ran gtk3-widget-factory
and found this to be sufficient to style the progress
fill node:
progressbar progress {
background-color: rgba(83, 165, 198, 255);
}
So, yes: just selecting on progressbar
alone produces wrong results because you're not being specific enough. That's why we need separate CSS nodes and why the node hierarchy is documented!
Upvotes: 1