diff --git a/doc/tint2.md b/doc/tint2.md index e0cf372..6ba3186 100644 --- a/doc/tint2.md +++ b/doc/tint2.md @@ -149,15 +149,19 @@ First the user must define one or more gradients in the config file, each starting with `gradient = TYPE`. These must be added before backgrounds. Then gradients can be added by index to backgrounds, -using the `gradient_id = INDEX`, `hover_gradient_id = INDEX` and -`pressed_gradient_id = INDEX`, where `INDEX` is +using the `gradient_id = INDEX`, `gradient_id_hover = INDEX` and +`gradient_id_pressed = INDEX`, where `INDEX` is the gradient index, starting from 1. -#### Simple gradients +#### Gradient types -These are gradients that vary from fixed control points (top-to-bottom, left-to-right -or center-to-corners). The user must specify the start and end colors, -and can optionally add extra color stops in between. +Gradients vary the color between fixed control points: +* vertical gradients: top-to-bottom; +* horizontal gradients: left-to-right; +* radial gradients: center-to-corners. + +The user must specify the start and end colors, and can optionally add extra color stops in between +using the `color_stop` option, as explained below. ##### Vertical gradient, with color varying from the top edge to the bottom edge, two colors @@ -175,10 +179,10 @@ start_color = #rrggbb opacity end_color = #rrggbb opacity ``` -##### Centered radial gradient, with color varying from the center to the corner, two colors: +##### Radial gradient, with color varying from the center to the corner, two colors: ``` -gradient = centered +gradient = radial start_color = #rrggbb opacity end_color = #rrggbb opacity ``` @@ -189,57 +193,6 @@ end_color = #rrggbb opacity color_stop = percentage #rrggbb opacity ``` -#### Advanced gradients - -These gradient types allow specifying the control points. This permits, for example, -adding off-center radial glow effects, linear gradients with arbitrary angles, -or using another element's edge as a control point. - -Note: updates are currently a little buggy for task buttons. - -##### Linear or radial gradients, with arbitrary control points (and orientation) - -``` -gradient = linear | radial -# Geometry -from_offset_x = SIZE_EXPRESSION -from_offset_y = SIZE_EXPRESSION -# from_offset_r for radial only -from_offset_r = SIZE_EXPRESSION -to_offset_x = SIZE_EXPRESSION -to_offset_y = SIZE_EXPRESSION -# to_offset_r for radial only -to_offset_r = SIZE_EXPRESSION -# Colors -start_color = #rrggbb opacity -end_color = #rrggbb opacity -# Optional: more color stops -color_stop = percentage #rrggbb opacity -color_stop = percentage #rrggbb opacity -``` - -`SIZE_EXPRESSION` is an expression that encodes an offset, -following the grammar: - -``` -SIZE_EXPRESSION = number | - SIZE | - SIZE * number | - SIZE * number% -SIZE = width | height | radius | left | right | top | bottom | centerx | centery | - ELEMENT width | ELEMENT height | ELEMENT radius | ELEMENT left | ELEMENT right | ELEMENT top | ELEMENT bottom | ELEMENT centerx | ELEMENT centery -ELEMENT = self | parent | panel -``` - -All coordinates are computed in the drawn element's coordinate system, -with origin in the top-left corner and the vertical axis growing down. - -Numbers are any real numbers. Negative numbers must not have spaces between -the minus sign and the first digit, for example `-1.234` is correct, -while `- 1.234` is not. - -Multiple `*_offset_*` can be given, in which case they are added together. - #### Gradient examples ``` @@ -249,60 +202,17 @@ start_color = #111122 30 end_color = #112211 30 color_stop = 60 #221111 30 -# Gradient 2: center glow -gradient = centered -start_color = #ffffff 20 -end_color = #ffffff 0 - -# Gradient 3: glow +# Gradient 2: radial glow gradient = radial start_color = #ffffff 20 end_color = #ffffff 0 -from_offset_x = width * 0.28 -from_offset_y = height * 0.28 -from_offset_r = 0 -to_offset_x = width * 0.28 -to_offset_y = height * 0.28 -to_offset_r = radius * 2 -# Gradient 4: aurora -gradient = linear -start_color = #ffffff 0 -end_color = #ffffff 0 -from_offset_x = panel left -from_offset_y = panel top -to_offset_x = panel width * 3 -to_offset_x = panel height * 3 -to_offset_y = panel width -to_offset_y = panel height -color_stop = 0.1 #ffffff 30 -color_stop = 0.8 #ffffff 30 -color_stop = 2.1 #7777aa 30 -color_stop = 3.1 #7777aa 30 -color_stop = 4.0 #ffffaa 30 -color_stop = 4.8 #aa7733 30 -color_stop = 5.1 #ff7733 30 -color_stop = 6.5 #337788 30 -color_stop = 9.2 #ffffaa 30 -color_stop = 10.1 #777777 30 -color_stop = 12.1 #aaaaff 30 -color_stop = 14.0 #77ff77 30 -color_stop = 18.0 #ffff77 30 -color_stop = 19.8 #77ffaa 30 -color_stop = 21.1 #ffffaa 20 -color_stop = 23.5 #337733 30 -color_stop = 25.5 #337733 30 -color_stop = 29.2 #77ffff 30 -color_stop = 30.1 #77ffaa 30 -color_stop = 31.0 #ffffaa 30 -color_stop = 34.8 #aa7733 30 - -# Gradient 5: elegant black +# Gradient 3: elegant black gradient = vertical start_color = #444444 100 end_color = #222222 100 -# Gradient 6: elegant black +# Gradient 4: elegant black gradient = horizontal start_color = #111111 100 end_color = #222222 100 @@ -318,8 +228,8 @@ border_color_hover = #ffffff 60 background_color_pressed = #555555 10 border_color_pressed = #ffffff 60 gradient_id = 3 -hover_gradient_id = 4 -pressed_gradient_id = 2 +gradient_id_hover = 4 +gradient_id_pressed = 2 [...] ``` diff --git a/src/config.c b/src/config.c index cba0cb0..4fcb33a 100644 --- a/src/config.c +++ b/src/config.c @@ -319,13 +319,13 @@ void add_entry(char *key, char *value) id = (id < gradients->len && id >= 0) ? id : -1; if (id >= 0) bg->gradients[MOUSE_NORMAL] = &g_array_index(gradients, GradientClass, id); - } else if (strcmp(key, "hover_gradient_id") == 0) { + } else if (strcmp(key, "gradient_id_hover") == 0 || strcmp(key, "hover_gradient_id") == 0) { Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1); int id = atoi(value); id = (id < gradients->len && id >= 0) ? id : -1; if (id >= 0) bg->gradients[MOUSE_OVER] = &g_array_index(gradients, GradientClass, id); - } else if (strcmp(key, "pressed_gradient_id") == 0) { + } else if (strcmp(key, "gradient_id_pressed") == 0 || strcmp(key, "pressed_gradient_id") == 0) { Background *bg = &g_array_index(backgrounds, Background, backgrounds->len - 1); int id = atoi(value); id = (id < gradients->len && id >= 0) ? id : -1; @@ -366,82 +366,6 @@ void add_entry(char *key, char *value) else color_stop->color.alpha = 0.5; g->extra_color_stops = g_list_append(g->extra_color_stops, color_stop); - } else if (strcmp(key, "from_offset_x") == 0) { - GradientClass *g = &g_array_index(gradients, GradientClass, gradients->len - 1); - if (g->type == GRADIENT_HORIZONTAL || g->type == GRADIENT_VERTICAL || g->type == GRADIENT_CENTERED) { - fprintf(stderr, RED "Control points can only be specified for linear and radial gradients: line %s = %s" RESET "\n", key, value); - } else { - Offset *offset = offset_from_string(value); - if (!offset) { - fprintf(stderr, RED "Invalid value: line %s = %s" RESET "\n", key, value); - } else { - g->from.offsets_x = g_list_append(g->from.offsets_x, offset); - } - } - } else if (strcmp(key, "from_offset_y") == 0) { - GradientClass *g = &g_array_index(gradients, GradientClass, gradients->len - 1); - if (g->type == GRADIENT_HORIZONTAL || g->type == GRADIENT_VERTICAL || g->type == GRADIENT_CENTERED) { - fprintf(stderr, RED "Control points can only be specified for linear and radial gradients: line %s = %s" RESET "\n", key, value); - } else { - Offset *offset = offset_from_string(value); - if (!offset) { - fprintf(stderr, RED "Invalid value: line %s = %s" RESET "\n", key, value); - } else { - g->from.offsets_y = g_list_append(g->from.offsets_y, offset); - } - } - } else if (strcmp(key, "from_offset_r") == 0) { - GradientClass *g = &g_array_index(gradients, GradientClass, gradients->len - 1); - if (g->type == GRADIENT_HORIZONTAL || g->type == GRADIENT_VERTICAL || g->type == GRADIENT_CENTERED) { - fprintf(stderr, RED "Control points can only be specified for linear and radial gradients: line %s = %s" RESET "\n", key, value); - } else if (g->type == GRADIENT_LINEAR) { - fprintf(stderr, RED "Invalid parameter for linear gradient: line %s = %s" RESET "\n", key, value); - } else { - Offset *offset = offset_from_string(value); - if (!offset) { - fprintf(stderr, RED "Invalid value: line %s = %s" RESET "\n", key, value); - } else { - g->from.offsets_r = g_list_append(g->from.offsets_r, offset); - } - } - } else if (strcmp(key, "to_offset_x") == 0) { - GradientClass *g = &g_array_index(gradients, GradientClass, gradients->len - 1); - if (g->type == GRADIENT_HORIZONTAL || g->type == GRADIENT_VERTICAL || g->type == GRADIENT_CENTERED) { - fprintf(stderr, RED "Control points can only be specified for linear and radial gradients: line %s = %s" RESET "\n", key, value); - } else { - Offset *offset = offset_from_string(value); - if (!offset) { - fprintf(stderr, RED "Invalid value: line %s = %s" RESET "\n", key, value); - } else { - g->to.offsets_x = g_list_append(g->to.offsets_x, offset); - } - } - } else if (strcmp(key, "to_offset_y") == 0) { - GradientClass *g = &g_array_index(gradients, GradientClass, gradients->len - 1); - if (g->type == GRADIENT_HORIZONTAL || g->type == GRADIENT_VERTICAL || g->type == GRADIENT_CENTERED) { - fprintf(stderr, RED "Control points can only be specified for linear and radial gradients: line %s = %s" RESET "\n", key, value); - } else { - Offset *offset = offset_from_string(value); - if (!offset) { - fprintf(stderr, RED "Invalid value: line %s = %s" RESET "\n", key, value); - } else { - g->to.offsets_y = g_list_append(g->to.offsets_y, offset); - } - } - } else if (strcmp(key, "to_offset_r") == 0) { - GradientClass *g = &g_array_index(gradients, GradientClass, gradients->len - 1); - if (g->type == GRADIENT_HORIZONTAL || g->type == GRADIENT_VERTICAL || g->type == GRADIENT_CENTERED) { - fprintf(stderr, RED "Control points can only be specified for linear and radial gradients: line %s = %s" RESET "\n", key, value); - } else if (g->type == GRADIENT_LINEAR) { - fprintf(stderr, RED "Invalid parameter for linear gradient: line %s = %s" RESET "\n", key, value); - } else { - Offset *offset = offset_from_string(value); - if (!offset) { - fprintf(stderr, RED "Invalid value: line %s = %s" RESET "\n", key, value); - } else { - g->to.offsets_r = g_list_append(g->to.offsets_r, offset); - } - } } /* Panel */ diff --git a/src/tint2conf/CMakeLists.txt b/src/tint2conf/CMakeLists.txt index 3623dc7..5d199b2 100644 --- a/src/tint2conf/CMakeLists.txt +++ b/src/tint2conf/CMakeLists.txt @@ -30,7 +30,8 @@ set(SOURCES ../util/common.c properties.c properties_rw.c theme_view.c - background_gui.c ) + background_gui.c + gradient_gui.c ) add_definitions( -DTINT2CONF ) diff --git a/src/tint2conf/background_gui.c b/src/tint2conf/background_gui.c index 2d67806..4bba67e 100644 --- a/src/tint2conf/background_gui.c +++ b/src/tint2conf/background_gui.c @@ -1,19 +1,12 @@ #include "background_gui.h" +#include "gradient_gui.h" GtkListStore *backgrounds; -GtkWidget *current_background, - *background_fill_color, - *background_border_color, - *background_fill_color_over, - *background_border_color_over, - *background_fill_color_press, - *background_border_color_press, - *background_border_width, - *background_corner_radius, - *background_border_sides_top, - *background_border_sides_bottom, - *background_border_sides_left, - *background_border_sides_right; +GtkWidget *current_background, *background_fill_color, *background_border_color, *background_gradient, + *background_fill_color_over, *background_border_color_over, *background_gradient_over, *background_fill_color_press, + *background_border_color_press, *background_gradient_press, *background_border_width, *background_corner_radius, + *background_border_sides_top, *background_border_sides_bottom, *background_border_sides_left, + *background_border_sides_right; GtkWidget *create_background_combo(const char *label) { @@ -26,19 +19,19 @@ GtkWidget *create_background_combo(const char *label) g_object_set(renderer, "wrap-width", 300, NULL); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, FALSE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", bgColText, NULL); - g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(background_combo_changed), (void*)label); + g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(background_combo_changed), (void *)label); return combo; } void background_combo_changed(GtkWidget *widget, gpointer data) { - gchar *combo_text = (gchar*)data; + gchar *combo_text = (gchar *)data; if (!combo_text || g_str_equal(combo_text, "")) return; int selected_index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); int index; - for (index = 0; ; index++) { + for (index = 0;; index++) { GtkTreePath *path; GtkTreeIter iter; @@ -51,9 +44,7 @@ void background_combo_changed(GtkWidget *widget, gpointer data) } gchar *text; - gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), &iter, - bgColText, &text, - -1); + gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), &iter, bgColText, &text, -1); gchar **parts = g_strsplit(text, ", ", -1); int ifound; for (ifound = 0; parts[ifound]; ifound++) { @@ -61,18 +52,16 @@ void background_combo_changed(GtkWidget *widget, gpointer data) break; } if (parts[ifound] && index != selected_index) { - for (; parts[ifound+1]; ifound++) { + for (; parts[ifound + 1]; ifound++) { gchar *tmp = parts[ifound]; - parts[ifound] = parts[ifound+1]; - parts[ifound+1] = tmp; + parts[ifound] = parts[ifound + 1]; + parts[ifound + 1] = tmp; } g_free(parts[ifound]); parts[ifound] = NULL; text = g_strjoinv(", ", parts); g_strfreev(parts); - gtk_list_store_set(backgrounds, &iter, - bgColText, text, - -1); + gtk_list_store_set(backgrounds, &iter, bgColText, text, -1); g_free(text); } else if (!parts[ifound] && index == selected_index) { if (!ifound) { @@ -95,9 +84,7 @@ void background_combo_changed(GtkWidget *widget, gpointer data) text = g_strjoinv(", ", parts); g_strfreev(parts); } - gtk_list_store_set(backgrounds, &iter, - bgColText, text, - -1); + gtk_list_store_set(backgrounds, &iter, bgColText, text, -1); g_free(text); } } @@ -106,26 +93,29 @@ void background_combo_changed(GtkWidget *widget, gpointer data) void create_background(GtkWidget *parent) { backgrounds = gtk_list_store_new(bgNumCols, - GDK_TYPE_PIXBUF, - GDK_TYPE_COLOR, + GDK_TYPE_PIXBUF, + GDK_TYPE_COLOR, + GTK_TYPE_INT, + GDK_TYPE_COLOR, + GTK_TYPE_INT, GTK_TYPE_INT, - GDK_TYPE_COLOR, + GTK_TYPE_INT, + GTK_TYPE_INT, + GTK_TYPE_STRING, + GDK_TYPE_COLOR, + GTK_TYPE_INT, + GDK_TYPE_COLOR, + GTK_TYPE_INT, GTK_TYPE_INT, + GDK_TYPE_COLOR, + GTK_TYPE_INT, + GDK_TYPE_COLOR, + GTK_TYPE_INT, GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_STRING, - GDK_TYPE_COLOR, - GTK_TYPE_INT, - GDK_TYPE_COLOR, - GTK_TYPE_INT, - GDK_TYPE_COLOR, - GTK_TYPE_INT, - GDK_TYPE_COLOR, - GTK_TYPE_INT, - GTK_TYPE_BOOL, - GTK_TYPE_BOOL, - GTK_TYPE_BOOL, - GTK_TYPE_BOOL); + GTK_TYPE_BOOL, + GTK_TYPE_BOOL, + GTK_TYPE_BOOL, + GTK_TYPE_BOOL); GtkWidget *table, *label, *button; int row, col; @@ -142,26 +132,26 @@ void create_background(GtkWidget *parent) gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_label_set_use_markup(GTK_LABEL(label), TRUE); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; current_background = create_background_combo(NULL); gtk_widget_show(current_background); - gtk_table_attach(GTK_TABLE(table), current_background, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), current_background, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; gtk_tooltips_set_tip(tooltips, current_background, _("Selects the background you would like to modify"), NULL); button = gtk_button_new_from_stock("gtk-add"); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(background_duplicate), NULL); gtk_widget_show(button); - gtk_table_attach(GTK_TABLE(table), button, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), button, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; gtk_tooltips_set_tip(tooltips, button, _("Creates a copy of the current background"), NULL); button = gtk_button_new_from_stock("gtk-remove"); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(background_delete), NULL); gtk_widget_show(button); - gtk_table_attach(GTK_TABLE(table), button, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), button, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; gtk_tooltips_set_tip(tooltips, button, _("Deletes the current background"), NULL); @@ -175,13 +165,13 @@ void create_background(GtkWidget *parent) label = gtk_label_new(_("Fill color")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_fill_color = gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(background_fill_color), TRUE); gtk_widget_show(background_fill_color); - gtk_table_attach(GTK_TABLE(table), background_fill_color, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_fill_color, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; gtk_tooltips_set_tip(tooltips, background_fill_color, _("The fill color of the current background"), NULL); @@ -189,95 +179,146 @@ void create_background(GtkWidget *parent) label = gtk_label_new(_("Border color")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_color = gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(background_border_color), TRUE); gtk_widget_show(background_border_color); - gtk_table_attach(GTK_TABLE(table), background_border_color, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_color, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; gtk_tooltips_set_tip(tooltips, background_border_color, _("The border color of the current background"), NULL); + row++, col = 2; + label = gtk_label_new(_("Gradient")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + background_gradient = create_gradient_combo(); + gtk_widget_show(background_gradient); + gtk_table_attach(GTK_TABLE(table), background_gradient, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + row++, col = 2; label = gtk_label_new(_("Fill color (mouse over)")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_fill_color_over = gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(background_fill_color_over), TRUE); gtk_widget_show(background_fill_color_over); - gtk_table_attach(GTK_TABLE(table), background_fill_color_over, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_fill_color_over, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - gtk_tooltips_set_tip(tooltips, background_fill_color_over, _("The fill color of the current background on mouse over"), NULL); + gtk_tooltips_set_tip(tooltips, + background_fill_color_over, + _("The fill color of the current background on mouse over"), + NULL); row++, col = 2; label = gtk_label_new(_("Border color (mouse over)")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_color_over = gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(background_border_color_over), TRUE); gtk_widget_show(background_border_color_over); - gtk_table_attach(GTK_TABLE(table), background_border_color_over, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_color_over, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + gtk_tooltips_set_tip(tooltips, + background_border_color_over, + _("The border color of the current background on mouse over"), + NULL); + + row++, col = 2; + label = gtk_label_new(_("Gradient (mouse over)")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + background_gradient_over = create_gradient_combo(); + gtk_widget_show(background_gradient_over); + gtk_table_attach(GTK_TABLE(table), background_gradient_over, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - gtk_tooltips_set_tip(tooltips, background_border_color_over, _("The border color of the current background on mouse over"), NULL); row++, col = 2; label = gtk_label_new(_("Fill color (pressed)")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_fill_color_press = gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(background_fill_color_press), TRUE); gtk_widget_show(background_fill_color_press); - gtk_table_attach(GTK_TABLE(table), background_fill_color_press, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_fill_color_press, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - gtk_tooltips_set_tip(tooltips, background_fill_color_press, _("The fill color of the current background on mouse button press"), NULL); + gtk_tooltips_set_tip(tooltips, + background_fill_color_press, + _("The fill color of the current background on mouse button press"), + NULL); row++, col = 2; label = gtk_label_new(_("Border color (pressed)")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_color_press = gtk_color_button_new(); gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(background_border_color_press), TRUE); gtk_widget_show(background_border_color_press); - gtk_table_attach(GTK_TABLE(table), background_border_color_press, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_color_press, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + gtk_tooltips_set_tip(tooltips, + background_border_color_press, + _("The border color of the current background on mouse button press"), + NULL); + + row++, col = 2; + label = gtk_label_new(_("Gradient (pressed)")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + background_gradient_press = create_gradient_combo(); + gtk_widget_show(background_gradient_press); + gtk_table_attach(GTK_TABLE(table), background_gradient_press, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - gtk_tooltips_set_tip(tooltips, background_border_color_press, _("The border color of the current background on mouse button press"), NULL); row++, col = 2; label = gtk_label_new(_("Border width")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_width = gtk_spin_button_new_with_range(0, 100, 1); gtk_widget_show(background_border_width); - gtk_table_attach(GTK_TABLE(table), background_border_width, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_width, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; - gtk_tooltips_set_tip(tooltips, background_border_width, _("The width of the border of the current background, in pixels"), NULL); + gtk_tooltips_set_tip(tooltips, + background_border_width, + _("The width of the border of the current background, in pixels"), + NULL); row++, col = 2; label = gtk_label_new(_("Corner radius")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_corner_radius = gtk_spin_button_new_with_range(0, 100, 1); gtk_widget_show(background_corner_radius); - gtk_table_attach(GTK_TABLE(table), background_corner_radius, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_corner_radius, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; gtk_tooltips_set_tip(tooltips, background_corner_radius, _("The corner radius of the current background"), NULL); @@ -286,36 +327,39 @@ void create_background(GtkWidget *parent) label = gtk_label_new(_("Border sides")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_widget_show(label); - gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_sides_top = gtk_check_button_new_with_label(_("Top")); gtk_widget_show(background_border_sides_top); - gtk_table_attach(GTK_TABLE(table), background_border_sides_top, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_sides_top, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_sides_bottom = gtk_check_button_new_with_label(_("Bottom")); gtk_widget_show(background_border_sides_bottom); - gtk_table_attach(GTK_TABLE(table), background_border_sides_bottom, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_sides_bottom, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_sides_left = gtk_check_button_new_with_label(_("Left")); gtk_widget_show(background_border_sides_left); - gtk_table_attach(GTK_TABLE(table), background_border_sides_left, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_sides_left, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; background_border_sides_right = gtk_check_button_new_with_label(_("Right")); gtk_widget_show(background_border_sides_right); - gtk_table_attach(GTK_TABLE(table), background_border_sides_right, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + gtk_table_attach(GTK_TABLE(table), background_border_sides_right, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); col++; g_signal_connect(G_OBJECT(current_background), "changed", G_CALLBACK(current_background_changed), NULL); g_signal_connect(G_OBJECT(background_fill_color), "color-set", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_border_color), "color-set", G_CALLBACK(background_update), NULL); + g_signal_connect(G_OBJECT(background_gradient), "changed", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_fill_color_over), "color-set", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_border_color_over), "color-set", G_CALLBACK(background_update), NULL); + g_signal_connect(G_OBJECT(background_gradient_over), "changed", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_fill_color_press), "color-set", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_border_color_press), "color-set", G_CALLBACK(background_update), NULL); + g_signal_connect(G_OBJECT(background_gradient_over), "changed", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_border_width), "value-changed", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_corner_radius), "value-changed", G_CALLBACK(background_update), NULL); g_signal_connect(G_OBJECT(background_border_sides_top), "toggled", G_CALLBACK(background_update), NULL); @@ -370,28 +414,55 @@ void background_create_new() GtkTreeIter iter; gtk_list_store_append(backgrounds, &iter); - gtk_list_store_set(backgrounds, &iter, - bgColPixbuf, NULL, - bgColFillColor, &fillColor, - bgColFillOpacity, fillOpacity, - bgColBorderColor, &borderColor, - bgColBorderOpacity, borderOpacity, - bgColBorderWidth, b, - bgColCornerRadius, r, - bgColText, "", - bgColFillColorOver, &fillColorOver, - bgColFillOpacityOver, fillOpacityOver, - bgColBorderColorOver, &borderColorOver, - bgColBorderOpacityOver, borderOpacityOver, - bgColFillColorPress, &fillColorPress, - bgColFillOpacityPress, fillOpacityPress, - bgColBorderColorPress, &borderColorPress, - bgColBorderOpacityPress, borderOpacityPress, - bgColBorderSidesTop, sideTop, - bgColBorderSidesBottom, sideBottom, - bgColBorderSidesLeft, sideLeft, - bgColBorderSidesRight, sideRight, - -1); + gtk_list_store_set(backgrounds, + &iter, + bgColPixbuf, + NULL, + bgColFillColor, + &fillColor, + bgColFillOpacity, + fillOpacity, + bgColBorderColor, + &borderColor, + bgColBorderOpacity, + borderOpacity, + bgColGradientId, + 0, + bgColBorderWidth, + b, + bgColCornerRadius, + r, + bgColText, + "", + bgColFillColorOver, + &fillColorOver, + bgColFillOpacityOver, + fillOpacityOver, + bgColBorderColorOver, + &borderColorOver, + bgColBorderOpacityOver, + borderOpacityOver, + bgColGradientIdOver, + 0, + bgColFillColorPress, + &fillColorPress, + bgColFillOpacityPress, + fillOpacityPress, + bgColBorderColorPress, + &borderColorPress, + bgColBorderOpacityPress, + borderOpacityPress, + bgColGradientIdPress, + 0, + bgColBorderSidesTop, + sideTop, + bgColBorderSidesBottom, + sideBottom, + bgColBorderSidesLeft, + sideLeft, + bgColBorderSidesRight, + sideRight, + -1); background_update_image(index); gtk_combo_box_set_active(GTK_COMBO_BOX(current_background), get_model_length(GTK_TREE_MODEL(backgrounds)) - 1); @@ -432,50 +503,96 @@ void background_duplicate(GtkWidget *widget, gpointer data) GdkColor *borderColorPress; int borderOpacityPress; - gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), &iter, - bgColFillColor, &fillColor, - bgColFillOpacity, &fillOpacity, - bgColBorderColor, &borderColor, - bgColBorderOpacity, &borderOpacity, - bgColFillColorOver, &fillColorOver, - bgColFillOpacityOver, &fillOpacityOver, - bgColBorderColorOver, &borderColorOver, - bgColBorderOpacityOver, &borderOpacityOver, - bgColFillColorPress, &fillColorPress, - bgColFillOpacityPress, &fillOpacityPress, - bgColBorderColorPress, &borderColorPress, - bgColBorderOpacityPress, &borderOpacityPress, - bgColBorderWidth, &b, - bgColCornerRadius, &r, - bgColBorderSidesTop, &sideTop, - bgColBorderSidesBottom, &sideBottom, - bgColBorderSidesLeft, &sideLeft, - bgColBorderSidesRight, &sideRight, - -1); + gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), + &iter, + bgColFillColor, + &fillColor, + bgColFillOpacity, + &fillOpacity, + bgColBorderColor, + &borderColor, + bgColBorderOpacity, + &borderOpacity, + bgColFillColorOver, + &fillColorOver, + bgColFillOpacityOver, + &fillOpacityOver, + bgColBorderColorOver, + &borderColorOver, + bgColBorderOpacityOver, + &borderOpacityOver, + bgColFillColorPress, + &fillColorPress, + bgColFillOpacityPress, + &fillOpacityPress, + bgColBorderColorPress, + &borderColorPress, + bgColBorderOpacityPress, + &borderOpacityPress, + bgColBorderWidth, + &b, + bgColCornerRadius, + &r, + bgColBorderSidesTop, + &sideTop, + bgColBorderSidesBottom, + &sideBottom, + bgColBorderSidesLeft, + &sideLeft, + bgColBorderSidesRight, + &sideRight, + -1); gtk_list_store_append(backgrounds, &iter); - gtk_list_store_set(backgrounds, &iter, - bgColPixbuf, NULL, - bgColFillColor, fillColor, - bgColFillOpacity, fillOpacity, - bgColBorderColor, borderColor, - bgColBorderOpacity, borderOpacity, - bgColText, "", - bgColFillColorOver, fillColorOver, - bgColFillOpacityOver, fillOpacityOver, - bgColBorderColorOver, borderColorOver, - bgColBorderOpacityOver, borderOpacityOver, - bgColFillColorPress, fillColorPress, - bgColFillOpacityPress, fillOpacityPress, - bgColBorderColorPress, borderColorPress, - bgColBorderOpacityPress, borderOpacityPress, - bgColBorderWidth, b, - bgColCornerRadius, r, - bgColBorderSidesTop, sideTop, - bgColBorderSidesBottom, sideBottom, - bgColBorderSidesLeft, sideLeft, - bgColBorderSidesRight, sideRight, - -1); + gtk_list_store_set(backgrounds, + &iter, + bgColPixbuf, + NULL, + bgColFillColor, + fillColor, + bgColFillOpacity, + fillOpacity, + bgColBorderColor, + borderColor, + bgColGradientId, + 0, + bgColBorderOpacity, + borderOpacity, + bgColText, + "", + bgColFillColorOver, + fillColorOver, + bgColFillOpacityOver, + fillOpacityOver, + bgColBorderColorOver, + borderColorOver, + bgColBorderOpacityOver, + borderOpacityOver, + bgColGradientIdOver, + 0, + bgColFillColorPress, + fillColorPress, + bgColFillOpacityPress, + fillOpacityPress, + bgColBorderColorPress, + borderColorPress, + bgColBorderOpacityPress, + borderOpacityPress, + bgColGradientIdPress, + 0, + bgColBorderWidth, + b, + bgColCornerRadius, + r, + bgColBorderSidesTop, + sideTop, + bgColBorderSidesBottom, + sideBottom, + bgColBorderSidesLeft, + sideLeft, + bgColBorderSidesRight, + sideRight, + -1); g_boxed_free(GDK_TYPE_COLOR, fillColor); g_boxed_free(GDK_TYPE_COLOR, borderColor); g_boxed_free(GDK_TYPE_COLOR, fillColorOver); @@ -528,14 +645,21 @@ void background_update_image(int index) GdkColor *borderColor; int borderOpacity = 100; - gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), &iter, - bgColFillColor, &fillColor, - bgColFillOpacity, &fillOpacity, - bgColBorderColor, &borderColor, - bgColBorderOpacity, &borderOpacity, - bgColBorderWidth, &b, - bgColCornerRadius, &r, - -1); + gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), + &iter, + bgColFillColor, + &fillColor, + bgColFillOpacity, + &fillOpacity, + bgColBorderColor, + &borderColor, + bgColBorderOpacity, + &borderOpacity, + bgColBorderWidth, + &b, + bgColCornerRadius, + &r, + -1); double bg_r, bg_g, bg_b, bg_a; gdkColor2CairoColor(*fillColor, &bg_r, &bg_g, &bg_b); @@ -566,13 +690,11 @@ void background_update_image(int index) cairo_arc(cr, r + b, r + b, r, 180 * degrees, 270 * degrees); cairo_close_path(cr); -// cairo_pattern_t *gpat; -// gpat = cairo_pattern_create_linear(0, 0, 0, h - b); -// cairo_pattern_add_color_stop_rgba(gpat, 0.1, bg_r, bg_g, bg_b, bg_a); -// cairo_pattern_add_color_stop_rgba(gpat, 0.9, bg_r2, bg_g2, bg_b2, bg_a2); -// cairo_set_source(cr, gpat); -// cairo_fill_preserve(cr); -// cairo_pattern_destroy(gpat); + int gradient_index = gtk_combo_box_get_active(GTK_COMBO_BOX(background_gradient)); + if (index >= 1 && gradient_index >= 1) { + GradientConfig *g = (GradientConfig *)g_list_nth(gradients, (guint)gradient_index)->data; + gradient_draw(cr, g, w, h, TRUE); + } cairo_set_source_rgba(cr, bg_r, bg_g, bg_b, bg_a); cairo_fill_preserve(cr); @@ -587,9 +709,7 @@ void background_update_image(int index) if (pixmap) g_object_unref(pixmap); - gtk_list_store_set(backgrounds, &iter, - bgColPixbuf, pixbuf, - -1); + gtk_list_store_set(backgrounds, &iter, bgColPixbuf, pixbuf, -1); if (pixbuf) g_object_unref(pixbuf); } @@ -633,47 +753,81 @@ void background_update(GtkWidget *widget, gpointer data) gtk_color_button_get_color(GTK_COLOR_BUTTON(background_fill_color), &fillColor); fillOpacity = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_fill_color)) * 100.0 / 0xffff); gtk_color_button_get_color(GTK_COLOR_BUTTON(background_border_color), &borderColor); - borderOpacity = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_border_color)) * 100.0 / 0xffff); + borderOpacity = + MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_border_color)) * 100.0 / 0xffff); + int gradient_id = gtk_combo_box_get_active(GTK_COMBO_BOX(background_gradient)); GdkColor fillColorOver; int fillOpacityOver; GdkColor borderColorOver; int borderOpacityOver; gtk_color_button_get_color(GTK_COLOR_BUTTON(background_fill_color_over), &fillColorOver); - fillOpacityOver = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_fill_color_over)) * 100.0 / 0xffff); + fillOpacityOver = + MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_fill_color_over)) * 100.0 / 0xffff); gtk_color_button_get_color(GTK_COLOR_BUTTON(background_border_color_over), &borderColorOver); - borderOpacityOver = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_border_color_over)) * 100.0 / 0xffff); + borderOpacityOver = + MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_border_color_over)) * 100.0 / 0xffff); + int gradient_id_over = gtk_combo_box_get_active(GTK_COMBO_BOX(background_gradient_over)); GdkColor fillColorPress; int fillOpacityPress; GdkColor borderColorPress; int borderOpacityPress; gtk_color_button_get_color(GTK_COLOR_BUTTON(background_fill_color_press), &fillColorPress); - fillOpacityPress = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_fill_color_press)) * 100.0 / 0xffff); + fillOpacityPress = + MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_fill_color_press)) * 100.0 / 0xffff); gtk_color_button_get_color(GTK_COLOR_BUTTON(background_border_color_press), &borderColorPress); - borderOpacityPress = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_border_color_press)) * 100.0 / 0xffff); + borderOpacityPress = + MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(background_border_color_press)) * 100.0 / 0xffff); + int gradient_id_press = gtk_combo_box_get_active(GTK_COMBO_BOX(background_gradient_press)); - gtk_list_store_set(backgrounds, &iter, - bgColPixbuf, NULL, - bgColFillColor, &fillColor, - bgColFillOpacity, fillOpacity, - bgColBorderColor, &borderColor, - bgColBorderOpacity, borderOpacity, - bgColFillColorOver, &fillColorOver, - bgColFillOpacityOver, fillOpacityOver, - bgColBorderColorOver, &borderColorOver, - bgColBorderOpacityOver, borderOpacityOver, - bgColFillColorPress, &fillColorPress, - bgColFillOpacityPress, fillOpacityPress, - bgColBorderColorPress, &borderColorPress, - bgColBorderOpacityPress, borderOpacityPress, - bgColBorderWidth, b, - bgColCornerRadius, r, - bgColBorderSidesTop, sideTop, - bgColBorderSidesBottom, sideBottom, - bgColBorderSidesLeft, sideLeft, - bgColBorderSidesRight, sideRight, - -1); + gtk_list_store_set(backgrounds, + &iter, + bgColPixbuf, + NULL, + bgColFillColor, + &fillColor, + bgColFillOpacity, + fillOpacity, + bgColBorderColor, + &borderColor, + bgColBorderOpacity, + borderOpacity, + bgColGradientId, + gradient_id, + bgColFillColorOver, + &fillColorOver, + bgColFillOpacityOver, + fillOpacityOver, + bgColBorderColorOver, + &borderColorOver, + bgColBorderOpacityOver, + borderOpacityOver, + bgColGradientIdOver, + gradient_id_over, + bgColFillColorPress, + &fillColorPress, + bgColFillOpacityPress, + fillOpacityPress, + bgColBorderColorPress, + &borderColorPress, + bgColBorderOpacityPress, + borderOpacityPress, + bgColGradientIdPress, + gradient_id_press, + bgColBorderWidth, + b, + bgColCornerRadius, + r, + bgColBorderSidesTop, + sideTop, + bgColBorderSidesBottom, + sideBottom, + bgColBorderSidesLeft, + sideLeft, + bgColBorderSidesRight, + sideRight, + -1); background_update_image(index); } @@ -712,28 +866,53 @@ void current_background_changed(GtkWidget *widget, gpointer data) int fillOpacityPress; GdkColor *borderColorPress; int borderOpacityPress; + int gradient_id, gradient_id_over, gradient_id_press; - - gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), &iter, - bgColFillColor, &fillColor, - bgColFillOpacity, &fillOpacity, - bgColBorderColor, &borderColor, - bgColBorderOpacity, &borderOpacity, - bgColFillColorOver, &fillColorOver, - bgColFillOpacityOver, &fillOpacityOver, - bgColBorderColorOver, &borderColorOver, - bgColBorderOpacityOver, &borderOpacityOver, - bgColFillColorPress, &fillColorPress, - bgColFillOpacityPress, &fillOpacityPress, - bgColBorderColorPress, &borderColorPress, - bgColBorderOpacityPress, &borderOpacityPress, - bgColBorderWidth, &b, - bgColCornerRadius, &r, - bgColBorderSidesTop, &sideTop, - bgColBorderSidesBottom, &sideBottom, - bgColBorderSidesLeft, &sideLeft, - bgColBorderSidesRight, &sideRight, - -1); + gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), + &iter, + bgColFillColor, + &fillColor, + bgColFillOpacity, + &fillOpacity, + bgColBorderColor, + &borderColor, + bgColBorderOpacity, + &borderOpacity, + bgColGradientId, + &gradient_id, + bgColFillColorOver, + &fillColorOver, + bgColFillOpacityOver, + &fillOpacityOver, + bgColBorderColorOver, + &borderColorOver, + bgColBorderOpacityOver, + &borderOpacityOver, + bgColGradientIdOver, + &gradient_id_over, + bgColFillColorPress, + &fillColorPress, + bgColFillOpacityPress, + &fillOpacityPress, + bgColBorderColorPress, + &borderColorPress, + bgColBorderOpacityPress, + &borderOpacityPress, + bgColGradientIdPress, + &gradient_id_press, + bgColBorderWidth, + &b, + bgColCornerRadius, + &r, + bgColBorderSidesTop, + &sideTop, + bgColBorderSidesBottom, + &sideBottom, + bgColBorderSidesLeft, + &sideLeft, + bgColBorderSidesRight, + &sideRight, + -1); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(background_border_sides_top), sideTop); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(background_border_sides_bottom), sideBottom); @@ -741,20 +920,24 @@ void current_background_changed(GtkWidget *widget, gpointer data) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(background_border_sides_right), sideRight); gtk_color_button_set_color(GTK_COLOR_BUTTON(background_fill_color), fillColor); - gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color), (fillOpacity*0xffff)/100); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color), (fillOpacity * 0xffff) / 100); gtk_color_button_set_color(GTK_COLOR_BUTTON(background_border_color), borderColor); - gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_border_color), (borderOpacity*0xffff)/100); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_border_color), (borderOpacity * 0xffff) / 100); + + gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient), gradient_id); gtk_color_button_set_color(GTK_COLOR_BUTTON(background_fill_color_over), fillColorOver); - gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color_over), (fillOpacityOver*0xffff)/100); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color_over), (fillOpacityOver * 0xffff) / 100); gtk_color_button_set_color(GTK_COLOR_BUTTON(background_border_color_over), borderColorOver); - gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_border_color_over), (borderOpacityOver*0xffff)/100); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_border_color_over), (borderOpacityOver * 0xffff) / 100); + gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient_over), gradient_id_over); gtk_color_button_set_color(GTK_COLOR_BUTTON(background_fill_color_press), fillColorPress); - gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color_press), (fillOpacityPress*0xffff)/100); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color_press), (fillOpacityPress * 0xffff) / 100); gtk_color_button_set_color(GTK_COLOR_BUTTON(background_border_color_press), borderColorPress); - gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_border_color_press), (borderOpacityPress*0xffff)/100); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_border_color_press), (borderOpacityPress * 0xffff) / 100); + gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient_press), gradient_id_press); gtk_spin_button_set_value(GTK_SPIN_BUTTON(background_border_width), b); gtk_spin_button_set_value(GTK_SPIN_BUTTON(background_corner_radius), r); diff --git a/src/tint2conf/background_gui.h b/src/tint2conf/background_gui.h index 2844ec9..10e5d48 100644 --- a/src/tint2conf/background_gui.h +++ b/src/tint2conf/background_gui.h @@ -1,3 +1,6 @@ +#ifndef BACKGROUND_GUI_H +#define BACKGROUND_GUI_H + #include "gui.h" void create_background(GtkWidget *parent); @@ -8,3 +11,5 @@ void background_update(GtkWidget *widget, gpointer data); void current_background_changed(GtkWidget *widget, gpointer data); void background_combo_changed(GtkWidget *widget, gpointer data); GtkWidget *create_background_combo(const char *label); + +#endif diff --git a/src/tint2conf/gradient_gui.c b/src/tint2conf/gradient_gui.c new file mode 100644 index 0000000..bf4f0d0 --- /dev/null +++ b/src/tint2conf/gradient_gui.c @@ -0,0 +1,334 @@ +#include "gradient_gui.h" + +#include + +GtkListStore *gradient_ids; +GList *gradients; +GtkWidget *current_gradient, *gradient_combo_type, *gradient_start_color, *gradient_end_color, *gradient_color_stops; + +int gradient_index_safe(int index) +{ + if (index <= 0) + index = 0; + if (index >= get_model_length(GTK_TREE_MODEL(gradient_ids))) + index = 0; + return index; +} + +GtkWidget *create_gradient_combo() +{ + GtkWidget *combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(gradient_ids)); + GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "pixbuf", grColPixbuf, NULL); + renderer = gtk_cell_renderer_text_new(); + g_object_set(renderer, "wrap-mode", PANGO_WRAP_WORD, NULL); + g_object_set(renderer, "wrap-width", 300, NULL); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", grColText, NULL); + return combo; +} + +void create_gradient(GtkWidget *parent) +{ + gradient_ids = gtk_list_store_new(grNumCols, GDK_TYPE_PIXBUF, GTK_TYPE_INT, GTK_TYPE_STRING); + gradients = NULL; + + GtkWidget *table, *label, *button; + int row, col; + // GtkTooltips *tooltips = gtk_tooltips_new(); + + table = gtk_table_new(1, 4, FALSE); + gtk_widget_show(table); + gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0); + gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING); + gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING); + + row = 0, col = 0; + label = gtk_label_new(_("Gradient")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + current_gradient = create_gradient_combo(); + gtk_widget_show(current_gradient); + gtk_table_attach(GTK_TABLE(table), current_gradient, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + button = gtk_button_new_from_stock("gtk-add"); + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gradient_duplicate), NULL); + gtk_widget_show(button); + gtk_table_attach(GTK_TABLE(table), button, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + button = gtk_button_new_from_stock("gtk-remove"); + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gradient_delete), NULL); + gtk_widget_show(button); + gtk_table_attach(GTK_TABLE(table), button, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + table = gtk_table_new(3, 4, FALSE); + gtk_widget_show(table); + gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0); + gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING); + gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING); + + row = 0, col = 2; + label = gtk_label_new(_("Type")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + gradient_combo_type = gtk_combo_box_new_text(); + gtk_widget_show(gradient_combo_type); + gtk_table_attach(GTK_TABLE(table), gradient_combo_type, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + gtk_combo_box_append_text(GTK_COMBO_BOX(gradient_combo_type), _("Vertical")); + gtk_combo_box_append_text(GTK_COMBO_BOX(gradient_combo_type), _("Horizontal")); + gtk_combo_box_append_text(GTK_COMBO_BOX(gradient_combo_type), _("Radial")); + gtk_combo_box_set_active(GTK_COMBO_BOX(gradient_combo_type), 0); + + row++, col = 2; + label = gtk_label_new(_("Start color")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + gradient_start_color = gtk_color_button_new(); + gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(gradient_start_color), TRUE); + gtk_widget_show(gradient_start_color); + gtk_table_attach(GTK_TABLE(table), gradient_start_color, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + row++, col = 2; + label = gtk_label_new(_("End color")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + gradient_end_color = gtk_color_button_new(); + gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(gradient_end_color), TRUE); + gtk_widget_show(gradient_end_color); + gtk_table_attach(GTK_TABLE(table), gradient_end_color, col, col + 1, row, row + 1, GTK_FILL, 0, 0, 0); + col++; + + change_paragraph(parent); + +#if 0 + label = gtk_label_new(_("Color stops")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(parent), label, FALSE, FALSE, 0); + + table = gtk_table_new(1, 4, FALSE); + gtk_widget_show(table); + gtk_box_pack_start(GTK_BOX(parent), table, FALSE, FALSE, 0); + gtk_table_set_row_spacings(GTK_TABLE(table), ROW_SPACING); + gtk_table_set_col_spacings(GTK_TABLE(table), COL_SPACING); + + row = 0, col = 2; + label = gtk_label_new(_("--")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_show(label); + gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, 0, 0, 0); + col++; +#endif + + g_signal_connect(G_OBJECT(current_gradient), "changed", G_CALLBACK(current_gradient_changed), NULL); + g_signal_connect(G_OBJECT(gradient_combo_type), "changed", G_CALLBACK(gradient_update), NULL); + g_signal_connect(G_OBJECT(gradient_start_color), "color-set", G_CALLBACK(gradient_update), NULL); + g_signal_connect(G_OBJECT(gradient_end_color), "color-set", G_CALLBACK(gradient_update), NULL); + + change_paragraph(parent); +} + +void gradient_create_new(GradientConfigType t) +{ + int index = get_model_length(GTK_TREE_MODEL(gradient_ids)); + + GradientConfig *g = (GradientConfig *)calloc(1, sizeof(GradientConfig)); + g->type = t; + gradients = g_list_append(gradients, g); + GtkTreeIter iter; + gtk_list_store_append(gradient_ids, &iter); + gtk_list_store_set(gradient_ids, &iter, + grColPixbuf, NULL, + grColId, &index, + grColText, "", + -1); + + gradient_update_image(index); + gtk_combo_box_set_active(GTK_COMBO_BOX(current_gradient), index); + current_gradient_changed(0, 0); +} + +void gradient_duplicate(GtkWidget *widget, gpointer data) +{ + gradient_create_new(GRADIENT_CONFIG_VERTICAL); +} + +void gradient_delete(GtkWidget *widget, gpointer data) +{ + int index = gtk_combo_box_get_active(GTK_COMBO_BOX(current_gradient)); + if (index < 0) + return; + + if (get_model_length(GTK_TREE_MODEL(gradient_ids)) <= 1) + return; + + GtkTreePath *path; + GtkTreeIter iter; + + path = gtk_tree_path_new_from_indices(index, -1); + gtk_tree_model_get_iter(GTK_TREE_MODEL(gradient_ids), &iter, path); + gtk_tree_path_free(path); + + gradients = g_list_remove(gradients, g_list_nth(gradients, (guint)index)->data); + gtk_list_store_remove(gradient_ids, &iter); + + if (index == get_model_length(GTK_TREE_MODEL(gradient_ids))) + index--; + gtk_combo_box_set_active(GTK_COMBO_BOX(gradient_ids), index); +} + +void gradient_draw(cairo_t *c, GradientConfig *g, int w, int h, gboolean preserve) +{ + cairo_pattern_t *gpat; + if (g->type == GRADIENT_CONFIG_VERTICAL) + gpat = cairo_pattern_create_linear(0, 0, 0, h); + else if (g->type == GRADIENT_CONFIG_HORIZONTAL) + gpat = cairo_pattern_create_linear(0, 0, w, 0); + else gpat = cairo_pattern_create_radial(w/2, h/2, 0, w/2, h/2, sqrt(w * w + h * h) / 2); + cairo_pattern_add_color_stop_rgba(gpat, 0.0, g->start_color.color.rgb[0], g->start_color.color.rgb[1], g->start_color.color.rgb[2], g->start_color.color.alpha); + for (GList *l = g->extra_color_stops; l; l = l->next) { + GradientConfigColorStop *stop = (GradientConfigColorStop *)l->data; + cairo_pattern_add_color_stop_rgba(gpat, + stop->offset, + stop->color.rgb[0], + stop->color.rgb[1], + stop->color.rgb[2], + stop->color.alpha); + } + cairo_pattern_add_color_stop_rgba(gpat, 1.0, g->end_color.color.rgb[0], g->end_color.color.rgb[1], g->end_color.color.rgb[2], g->end_color.color.alpha); + cairo_set_source(c, gpat); + cairo_rectangle(c, 0, 0, w, h); + if (preserve) + cairo_fill_preserve(c); + else + cairo_fill(c); + cairo_pattern_destroy(gpat); +} + +void gradient_update_image(int index) +{ + GradientConfig *g = (GradientConfig *)g_list_nth(gradients, (guint)index)->data; + + int w = 70; + int h = 30; + GdkPixmap *pixmap = gdk_pixmap_new(NULL, w, h, 24); + + cairo_t *cr = gdk_cairo_create(pixmap); + cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); + cairo_rectangle(cr, 0, 0, w, h); + cairo_fill(cr); + + gradient_draw(cr, g, w, h, FALSE); + + GdkPixbuf *pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap, gdk_colormap_get_system(), 0, 0, 0, 0, w, h); + if (pixmap) + g_object_unref(pixmap); + + GtkTreePath *path; + GtkTreeIter iter; + + path = gtk_tree_path_new_from_indices(index, -1); + gtk_tree_model_get_iter(GTK_TREE_MODEL(gradient_ids), &iter, path); + gtk_tree_path_free(path); + + gtk_list_store_set(gradient_ids, &iter, + grColPixbuf, pixbuf, + -1); + if (pixbuf) + g_object_unref(pixbuf); +} + +void gradient_force_update() +{ + gradient_update(NULL, NULL); +} + +static gboolean gradient_updates_disabled = FALSE; +void gradient_update(GtkWidget *widget, gpointer data) +{ + if (gradient_updates_disabled) + return; + int index = gtk_combo_box_get_active(GTK_COMBO_BOX(current_gradient)); + if (index < 0) + return; + + GtkTreePath *path; + GtkTreeIter iter; + + path = gtk_tree_path_new_from_indices(index, -1); + gtk_tree_model_get_iter(GTK_TREE_MODEL(gradient_ids), &iter, path); + gtk_tree_path_free(path); + + GradientConfig *g = (GradientConfig *)g_list_nth(gradients, (guint)index)->data; + + g->type = (GradientConfigType)MAX(0, gtk_combo_box_get_active(GTK_COMBO_BOX(gradient_combo_type))); + + GdkColor color; + int opacity; + + gtk_color_button_get_color(GTK_COLOR_BUTTON(gradient_start_color), &color); + opacity = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(gradient_start_color)) * 100.0 / 0xffff); + gdkColor2CairoColor(color, &g->start_color.color.rgb[0], &g->start_color.color.rgb[1], &g->start_color.color.rgb[2]); + g->start_color.color.alpha = opacity / 100.0; + + gtk_color_button_get_color(GTK_COLOR_BUTTON(gradient_end_color), &color); + opacity = MIN(100, 0.5 + gtk_color_button_get_alpha(GTK_COLOR_BUTTON(gradient_end_color)) * 100.0 / 0xffff); + gdkColor2CairoColor(color, &g->end_color.color.rgb[0], &g->end_color.color.rgb[1], &g->end_color.color.rgb[2]); + g->end_color.color.alpha = opacity / 100.0; + + gtk_list_store_set(gradient_ids, &iter, + grColPixbuf, NULL, + grColId, &index, + grColText, "", + -1); + gradient_update_image(index); +} + +void current_gradient_changed(GtkWidget *widget, gpointer data) +{ + int index = gtk_combo_box_get_active(GTK_COMBO_BOX(current_gradient)); + if (index < 0) + return; + + gradient_updates_disabled = TRUE; + + GradientConfig *g = (GradientConfig *)g_list_nth(gradients, (guint)index)->data; + + gtk_combo_box_set_active(GTK_COMBO_BOX(gradient_combo_type), g->type); + + GdkColor color; + int opacity; + + cairoColor2GdkColor(g->start_color.color.rgb[0], g->start_color.color.rgb[1], g->start_color.color.rgb[2], &color); + opacity = (g->start_color.color.alpha * 65535) / 100; + gtk_color_button_set_color(GTK_COLOR_BUTTON(gradient_start_color), &color); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color_over), opacity); + + cairoColor2GdkColor(g->end_color.color.rgb[0], g->end_color.color.rgb[1], g->end_color.color.rgb[2], &color); + opacity = (g->end_color.color.alpha * 65535) / 100; + gtk_color_button_set_color(GTK_COLOR_BUTTON(gradient_end_color), &color); + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(background_fill_color_over), opacity); + + gradient_updates_disabled = FALSE; + gradient_update_image(index); +} diff --git a/src/tint2conf/gradient_gui.h b/src/tint2conf/gradient_gui.h new file mode 100644 index 0000000..8f3fe9a --- /dev/null +++ b/src/tint2conf/gradient_gui.h @@ -0,0 +1,39 @@ +#ifndef GRADIENT_GUI_H +#define GRADIENT_GUI_H + +#include "gui.h" + +int gradient_index_safe(int index); +void create_gradient(GtkWidget *parent); +GtkWidget *create_gradient_combo(); +void gradient_duplicate(GtkWidget *widget, gpointer data); +void gradient_delete(GtkWidget *widget, gpointer data); +void gradient_update_image(int index); +void gradient_update(GtkWidget *widget, gpointer data); +void gradient_force_update(); +void current_gradient_changed(GtkWidget *widget, gpointer data); + +typedef enum GradientConfigType { + GRADIENT_CONFIG_VERTICAL = 0, + GRADIENT_CONFIG_HORIZONTAL, + GRADIENT_CONFIG_RADIAL +} GradientConfigType; + +typedef struct GradientConfigColorStop { + Color color; + // offset in 0-1 + double offset; +} GradientConfigColorStop; + +typedef struct GradientConfig { + GradientConfigType type; + GradientConfigColorStop start_color; + GradientConfigColorStop end_color; + // Each element is a GradientConfigColorStop + GList *extra_color_stops; +} GradientConfig; + +void gradient_create_new(GradientConfigType t); +void gradient_draw(cairo_t *c, GradientConfig *g, int w, int h, gboolean preserve); + +#endif diff --git a/src/tint2conf/properties.c b/src/tint2conf/properties.c index 0190619..f71c5ec 100644 --- a/src/tint2conf/properties.c +++ b/src/tint2conf/properties.c @@ -19,6 +19,7 @@ #include "gui.h" #include "background_gui.h" +#include "gradient_gui.h" GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y, *panel_spacing; GtkWidget *panel_wm_menu, *panel_dock, *panel_autohide, *panel_autohide_show_time, *panel_autohide_hide_time, *panel_autohide_size; @@ -129,8 +130,6 @@ IconThemeWrapper *icon_theme; GtkWidget *launcher_tooltip; GtkWidget *launcher_icon_theme_override; -GtkListStore *gradients_lists; - GtkWidget *addScrollBarToWidget(GtkWidget *widget); gboolean gtk_tree_model_iter_prev_tint2(GtkTreeModel *model, GtkTreeIter *iter); @@ -220,7 +219,7 @@ GtkWidget *create_properties() GtkWidget *view, *dialog_vbox3, *button; GtkTooltips *tooltips; GtkWidget *page_panel, *page_panel_items, *page_launcher, *page_taskbar, *page_battery, *page_clock, - *page_tooltip, *page_systemtray, *page_task, *page_background; + *page_tooltip, *page_systemtray, *page_task, *page_background, *page_gradient; GtkWidget *label; tooltips = gtk_tooltips_new(); @@ -265,6 +264,14 @@ GtkWidget *create_properties() GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); // notebook + label = gtk_label_new(_("Gradients")); + gtk_widget_show(label); + page_gradient = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING); + gtk_container_set_border_width(GTK_CONTAINER(page_gradient), 10); + gtk_widget_show(page_gradient); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), addScrollBarToWidget(page_gradient), label); + create_gradient(page_gradient); + label = gtk_label_new(_("Backgrounds")); gtk_widget_show(label); page_background = gtk_vbox_new(FALSE, DEFAULT_HOR_SPACING); diff --git a/src/tint2conf/properties.h b/src/tint2conf/properties.h index 062dfa8..bc9bf36 100644 --- a/src/tint2conf/properties.h +++ b/src/tint2conf/properties.h @@ -185,6 +185,7 @@ enum { bgColFillOpacity, bgColBorderColor, bgColBorderOpacity, + bgColGradientId, bgColBorderWidth, bgColCornerRadius, bgColText, @@ -192,10 +193,12 @@ enum { bgColFillOpacityOver, bgColBorderColorOver, bgColBorderOpacityOver, + bgColGradientIdOver, bgColFillColorPress, bgColFillOpacityPress, bgColBorderColorPress, bgColBorderOpacityPress, + bgColGradientIdPress, bgColBorderSidesTop, bgColBorderSidesBottom, bgColBorderSidesLeft, @@ -207,10 +210,13 @@ extern GtkListStore *backgrounds; extern GtkWidget *current_background, *background_fill_color, *background_border_color, + *background_gradient, *background_fill_color_over, *background_border_color_over, + *background_gradient_over, *background_fill_color_press, *background_border_color_press, + *background_gradient_press, *background_border_width, *background_border_sides_top, *background_border_sides_bottom, @@ -218,7 +224,21 @@ extern GtkWidget *current_background, *background_border_sides_right, *background_corner_radius; -extern GtkListStore *gradients_list; +// gradients +enum { + grColPixbuf = 0, + grColId, + grColText, + grNumCols +}; +extern GtkListStore *gradient_ids; +extern GList *gradients; + +extern GtkWidget *current_gradient, + *gradient_combo_type, + *gradient_start_color, + *gradient_end_color, + *gradient_color_stops; void background_create_new(); void background_force_update(); diff --git a/src/tint2conf/properties_rw.c b/src/tint2conf/properties_rw.c index 4eabd07..7600a0b 100644 --- a/src/tint2conf/properties_rw.c +++ b/src/tint2conf/properties_rw.c @@ -6,7 +6,9 @@ #include "common.h" #include "properties.h" #include "properties_rw.h" +#include "gradient_gui.h" +void finalize_gradient(); void finalize_bg(); void add_entry(char *key, char *value); void hex2gdk(char *hex, GdkColor *color); @@ -28,10 +30,13 @@ static int read_border_color_hover; static int read_bg_color_press; static int read_border_color_press; +static int num_gr; + void config_read_file(const char *path) { num_bg = 0; background_create_new(); + gradient_create_new(GRADIENT_CONFIG_VERTICAL); FILE *fp; char line[512]; @@ -58,6 +63,7 @@ void config_read_file(const char *path) } fclose(fp); + finalize_gradient(); finalize_bg(); if (!config_has_panel_items) { @@ -89,6 +95,40 @@ void config_write_color(FILE *fp, const char *name, GdkColor color, int opacity) fprintf(fp, "%s = #%02x%02x%02x %d\n", name, color.red >> 8, color.green >> 8, color.blue >> 8, opacity); } +void config_write_gradients(FILE *fp) +{ + fprintf(fp, "#-------------------------------------\n"); + fprintf(fp, "# Gradients\n"); + + int index = 1; + + for (GList *gl = gradients ? gradients->next : NULL; gl; gl = gl->next, index++) { + GradientConfig *g = (GradientConfig *)gl->data; + GdkColor color; + int opacity; + + fprintf(fp, "# Gradient %d\n", index); + fprintf(fp, "gradient = %s\n", g->type == GRADIENT_CONFIG_HORIZONTAL ? "horizontal" : g->type == GRADIENT_CONFIG_VERTICAL ? "vertical" : "radial"); + + cairoColor2GdkColor(g->start_color.color.rgb[0], g->start_color.color.rgb[1], g->start_color.color.rgb[2], &color); + opacity = g->start_color.color.alpha * 100; + config_write_color(fp, "start_color", color, opacity); + + cairoColor2GdkColor(g->end_color.color.rgb[0], g->end_color.color.rgb[1], g->end_color.color.rgb[2], &color); + opacity = g->end_color.color.alpha * 100; + config_write_color(fp, "end_color", color, opacity); + + for (GList *l = g->extra_color_stops; l; l = l->next) { + GradientConfigColorStop *stop = (GradientConfigColorStop *)l->data; + // color_stop = percentage #rrggbb opacity + cairoColor2GdkColor(stop->color.rgb[0], stop->color.rgb[1], stop->color.rgb[2], &color); + opacity = stop->color.alpha * 100; + fprintf(fp, "color_stop = %f #%02x%02x%02x %d\n", stop->offset * 100, color.red >> 8, color.green >> 8, color.blue >> 8, opacity); + } + fprintf(fp, "\n"); + } +} + void config_write_backgrounds(FILE *fp) { fprintf(fp, "#-------------------------------------\n"); @@ -117,14 +157,17 @@ void config_write_backgrounds(FILE *fp) int fillOpacity; GdkColor *borderColor; int borderOpacity; + int gradient_id; GdkColor *fillColorOver; int fillOpacityOver; GdkColor *borderColorOver; int borderOpacityOver; + int gradient_id_over; GdkColor *fillColorPress; int fillOpacityPress; GdkColor *borderColorPress; int borderOpacityPress; + int gradient_id_press; gchar *text; gtk_tree_model_get(GTK_TREE_MODEL(backgrounds), @@ -137,6 +180,8 @@ void config_write_backgrounds(FILE *fp) &borderColor, bgColBorderOpacity, &borderOpacity, + bgColGradientId, + &gradient_id, bgColFillColorOver, &fillColorOver, bgColFillOpacityOver, @@ -145,6 +190,8 @@ void config_write_backgrounds(FILE *fp) &borderColorOver, bgColBorderOpacityOver, &borderOpacityOver, + bgColGradientIdOver, + &gradient_id_over, bgColFillColorPress, &fillColorPress, bgColFillOpacityPress, @@ -153,6 +200,8 @@ void config_write_backgrounds(FILE *fp) &borderColorPress, bgColBorderOpacityPress, &borderOpacityPress, + bgColGradientIdPress, + &gradient_id_press, bgColBorderWidth, &b, bgColCornerRadius, @@ -186,10 +235,13 @@ void config_write_backgrounds(FILE *fp) config_write_color(fp, "background_color", *fillColor, fillOpacity); config_write_color(fp, "border_color", *borderColor, borderOpacity); + fprintf(fp, "gradient_id = %d\n", gradient_id); config_write_color(fp, "background_color_hover", *fillColorOver, fillOpacityOver); config_write_color(fp, "border_color_hover", *borderColorOver, borderOpacityOver); + fprintf(fp, "gradient_id_hover = %d\n", gradient_id_over); config_write_color(fp, "background_color_pressed", *fillColorPress, fillOpacityPress); config_write_color(fp, "border_color_pressed", *borderColorPress, borderOpacityPress); + fprintf(fp, "gradient_id_pressed = %d\n", gradient_id_press); fprintf(fp, "\n"); } } @@ -871,6 +923,7 @@ void config_save_file(const char *path) fprintf(fp, "# See https://gitlab.com/o9000/tint2/wikis/Configure for \n"); fprintf(fp, "# full documentation of the configuration options.\n"); + config_write_gradients(fp); config_write_backgrounds(fp); config_write_panel(fp); config_write_taskbar(fp); @@ -959,10 +1012,60 @@ void finalize_bg() } } +void finalize_gradient() +{ + if (num_gr > 0) { + gradient_force_update(); + } +} + void add_entry(char *key, char *value) { char *value1 = 0, *value2 = 0, *value3 = 0; + /* Gradients */ + if (strcmp(key, "gradient") == 0) { + finalize_gradient(); + GradientConfigType t; + if (g_str_equal(value, "horizontal")) + t = GRADIENT_CONFIG_HORIZONTAL; + else if (g_str_equal(value, "vertical")) + t = GRADIENT_CONFIG_VERTICAL; + else + t = GRADIENT_CONFIG_RADIAL; + gradient_create_new(t); + num_gr++; + gradient_force_update(); + } else if (strcmp(key, "start_color") == 0) { + extract_values(value, &value1, &value2, &value3); + GdkColor col; + hex2gdk(value1, &col); + gtk_color_button_set_color(GTK_COLOR_BUTTON(gradient_start_color), &col); + int alpha = value2 ? atoi(value2) : 50; + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(gradient_start_color), (alpha * 65535) / 100); + gradient_force_update(); + } else if (strcmp(key, "end_color") == 0) { + extract_values(value, &value1, &value2, &value3); + GdkColor col; + hex2gdk(value1, &col); + gtk_color_button_set_color(GTK_COLOR_BUTTON(gradient_end_color), &col); + int alpha = value2 ? atoi(value2) : 50; + gtk_color_button_set_alpha(GTK_COLOR_BUTTON(gradient_end_color), (alpha * 65535) / 100); + gradient_force_update(); + } else if (strcmp(key, "color_stop") == 0) { + GradientConfig *g = (GradientConfig *)g_list_last(gradients)->data; + extract_values(value, &value1, &value2, &value3); + GradientConfigColorStop *color_stop = (GradientConfigColorStop *) calloc(1, sizeof(GradientConfigColorStop)); + color_stop->offset = atof(value1) / 100.0; + get_color(value2, color_stop->color.rgb); + if (value3) + color_stop->color.alpha = (atoi(value3) / 100.0); + else + color_stop->color.alpha = 0.5; + g->extra_color_stops = g_list_append(g->extra_color_stops, color_stop); + current_gradient_changed(NULL, NULL); + } else + /* Background and border */ if (strcmp(key, "rounded") == 0) { // 'rounded' is the first parameter => alloc a new background @@ -1040,7 +1143,20 @@ void add_entry(char *key, char *value) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(background_border_sides_right), strchr(value, 'r') || strchr(value, 'R')); background_force_update(); + } else if (strcmp(key, "gradient_id") == 0) { + int id = gradient_index_safe(atoi(value)); + gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient), id); + background_force_update(); + } else if (strcmp(key, "gradient_id_hover") == 0 || strcmp(key, "hover_gradient_id") == 0) { + int id = gradient_index_safe(atoi(value)); + gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient_over), id); + background_force_update(); + } else if (strcmp(key, "gradient_id_pressed") == 0 || strcmp(key, "pressed_gradient_id") == 0) { + int id = gradient_index_safe(atoi(value)); + gtk_combo_box_set_active(GTK_COMBO_BOX(background_gradient_press), id); + background_force_update(); } + /* Panel */ else if (strcmp(key, "panel_size") == 0) { extract_values(value, &value1, &value2, &value3); diff --git a/src/util/area.c b/src/util/area.c index 9991152..6ba5bc2 100644 --- a/src/util/area.c +++ b/src/util/area.c @@ -1061,8 +1061,7 @@ void update_gradient(GradientInstance *gi) compute_control_point(gi, &gi->gradient_class->from, &from_x, &from_y, &from_r); double to_x, to_y, to_r; compute_control_point(gi, &gi->gradient_class->to, &to_x, &to_y, &to_r); - if (gi->gradient_class->type == GRADIENT_VERTICAL || gi->gradient_class->type == GRADIENT_HORIZONTAL || - gi->gradient_class->type == GRADIENT_LINEAR) { + if (gi->gradient_class->type == GRADIENT_VERTICAL || gi->gradient_class->type == GRADIENT_HORIZONTAL) { gi->pattern = cairo_pattern_create_linear(from_x, from_y, to_x, to_y); if (debug_gradients) fprintf(stderr, @@ -1072,7 +1071,7 @@ void update_gradient(GradientInstance *gi) from_y, to_x, to_y); - } else if (gi->gradient_class->type == GRADIENT_CENTERED || gi->gradient_class->type == GRADIENT_RADIAL) { + } else if (gi->gradient_class->type == GRADIENT_CENTERED) { gi->pattern = cairo_pattern_create_radial(from_x, from_y, from_r, to_x, to_y, to_r); if (debug_gradients) fprintf(stderr, diff --git a/src/util/gradient.c b/src/util/gradient.c index 30ae0e6..e272abc 100644 --- a/src/util/gradient.c +++ b/src/util/gradient.c @@ -38,191 +38,12 @@ GradientType gradient_type_from_string(const char *str) return GRADIENT_HORIZONTAL; if (g_str_equal(str, "vertical")) return GRADIENT_VERTICAL; - if (g_str_equal(str, "centered")) - return GRADIENT_CENTERED; - if (g_str_equal(str, "linear")) - return GRADIENT_LINEAR; if (g_str_equal(str, "radial")) - return GRADIENT_RADIAL; + return GRADIENT_CENTERED; fprintf(stderr, RED "Invalid gradient type: %s" RESET "\n", str); return GRADIENT_VERTICAL; } -gboolean read_element_from_string(const char *str, Element *element) -{ - if (g_str_equal(str, "self")) { - *element = ELEMENT_SELF; - return TRUE; - } - if (g_str_equal(str, "parent")) { - *element = ELEMENT_PARENT; - return TRUE; - } - if (g_str_equal(str, "panel")) { - *element = ELEMENT_PANEL; - return TRUE; - } - return FALSE; -} - -Element element_from_string(const char *str) -{ - Element result; - if (read_element_from_string(str, &result)) - return result; - fprintf(stderr, RED "Invalid origin type: %s" RESET "\n", str); - return ELEMENT_SELF; -} - -gboolean read_size_from_string(const char *str, SizeVariable *variable) -{ - if (g_str_equal(str, "width")) { - *variable = SIZE_WIDTH; - return TRUE; - } - if (g_str_equal(str, "height")) { - *variable = SIZE_HEIGHT; - return TRUE; - } - if (g_str_equal(str, "radius")) { - *variable = SIZE_RADIUS; - return TRUE; - } - if (g_str_equal(str, "left")) { - *variable = SIZE_LEFT; - return TRUE; - } - if (g_str_equal(str, "right")) { - *variable = SIZE_RIGHT; - return TRUE; - } - if (g_str_equal(str, "top")) { - *variable = SIZE_TOP; - return TRUE; - } - if (g_str_equal(str, "bottom")) { - *variable = SIZE_BOTTOM; - return TRUE; - } - if (g_str_equal(str, "centerx")) { - *variable = SIZE_CENTERX; - return TRUE; - } - if (g_str_equal(str, "centery")) { - *variable = SIZE_CENTERY; - return TRUE; - } - return FALSE; -} - -gboolean read_size_variable_from_string(const char *str, - Element *variable_element, - SizeVariable *variable, - double *multiplier) -{ - if (read_size_from_string(str, variable)) { - *variable_element = ELEMENT_SELF; - *multiplier = 1; - return TRUE; - } - - char *value1 = 0, *value2 = 0, *value3 = 0, *value4 = 0; - extract_values_4(str, &value1, &value2, &value3, &value4); - - if (value1 && !value2) { - if (read_size_from_string(value1, variable)) { - *multiplier = 1; - if (value1) - free(value1); - if (value2) - free(value2); - if (value3) - free(value3); - if (value4) - free(value4); - return TRUE; - } - } - - if (value1 && value2 && !value3) { - if (read_element_from_string(value1, variable_element) && read_size_from_string(value2, variable)) { - *multiplier = 1; - if (value1) - free(value1); - if (value2) - free(value2); - if (value3) - free(value3); - if (value4) - free(value4); - return TRUE; - } - } - - if (value1 && value2 && value3 && !value4) { - if (read_size_from_string(value1, variable) && g_str_equal(value2, "*") && - read_double_with_percent(value3, multiplier)) { - if (value1) - free(value1); - if (value2) - free(value2); - if (value3) - free(value3); - if (value4) - free(value4); - return TRUE; - } - } - - if (value1 && value2 && value3 && value4) { - if (read_element_from_string(value1, variable_element) && read_size_from_string(value2, variable) && - g_str_equal(value3, "*") && read_double_with_percent(value4, multiplier)) { - if (value1) - free(value1); - if (value2) - free(value2); - if (value3) - free(value3); - if (value4) - free(value4); - return TRUE; - } - } - - if (value1) - free(value1); - if (value2) - free(value2); - if (value3) - free(value3); - if (value4) - free(value4); - - return FALSE; -} - -Offset *offset_from_string(const char *str) -{ - Offset *offset = (Offset *)calloc(1, sizeof(Offset)); - if (read_double(str, &offset->constant_value)) { - offset->constant = TRUE; - return offset; - } - offset->constant = FALSE; - if (read_size_variable_from_string(str, &offset->element, &offset->variable, &offset->multiplier)) { - if (debug_gradients) - fprintf(stderr, - "Read offset '%s' as: %d %d %f\n", - str, - offset->element, - offset->variable, - offset->multiplier); - return offset; - } - free(offset); - return NULL; -} - void init_gradient(GradientClass *g, GradientType type) { memset(g, 0, sizeof(*g)); @@ -286,10 +107,6 @@ void init_gradient(GradientClass *g, GradientType type) offset_center_r->variable = SIZE_RADIUS; offset_center_r->multiplier = 1.0; g->to.offsets_r = g_list_append(g->to.offsets_r, offset_center_r); - } else if (g->type == GRADIENT_LINEAR) { - // Nothing to do, the user has to add control points - } else if (g->type == GRADIENT_RADIAL) { - // Nothing to do, the user has to add control points } } diff --git a/src/util/gradient.h b/src/util/gradient.h index ae62fc8..055ed8d 100644 --- a/src/util/gradient.h +++ b/src/util/gradient.h @@ -12,9 +12,7 @@ typedef enum GradientType { GRADIENT_VERTICAL = 0, GRADIENT_HORIZONTAL, - GRADIENT_CENTERED, - GRADIENT_LINEAR, - GRADIENT_RADIAL + GRADIENT_CENTERED } GradientType; typedef struct ColorStop { @@ -70,8 +68,6 @@ typedef struct GradientClass { } GradientClass; GradientType gradient_type_from_string(const char *str); -Element element_from_string(const char *str); -Offset *offset_from_string(const char *str); void init_gradient(GradientClass *g, GradientType type); void cleanup_gradient(GradientClass *g); diff --git a/tint2.files b/tint2.files index b485fee..68410e7 100644 --- a/tint2.files +++ b/tint2.files @@ -217,3 +217,5 @@ src/util/color.c src/tint2conf/background_gui.h src/tint2conf/background_gui.c src/tint2conf/gui.h +src/tint2conf/gradient_gui.h +src/tint2conf/gradient_gui.c