From 358809e0c178eaec997df98ad6de605640c75e43 Mon Sep 17 00:00:00 2001 From: deekayhd <53017684+deekayhd@users.noreply.github.com> Date: Sun, 31 May 2026 17:55:38 +0200 Subject: [PATCH 1/5] add "unrate" button in bottom row --- src/libs/tools/ratings.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libs/tools/ratings.c b/src/libs/tools/ratings.c index 80bf76e925cb..4779be30a943 100644 --- a/src/libs/tools/ratings.c +++ b/src/libs/tools/ratings.c @@ -134,7 +134,7 @@ static gboolean _lib_ratings_draw_callback(GtkWidget *widget, cairo_t *crf, dt_l gtk_widget_get_allocation(widget, &allocation); const float star_size = allocation.height; - const float star_spacing = (allocation.width - 5.0 * star_size) / 4.0; + const float star_spacing = (allocation.width - 6.0 * star_size) / 5.0; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, allocation.width, allocation.height); @@ -152,21 +152,34 @@ static gboolean _lib_ratings_draw_callback(GtkWidget *widget, cairo_t *crf, dt_l int x = 0; cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1)); gdk_cairo_set_source_rgba(cr, &fg_color); + cairo_set_line_width(cr, 1.6 * cairo_get_line_width(cr)); + cairo_move_to(cr, x + star_size * .1, star_size / 2.0); + cairo_line_to(cr, x + star_size * .9, star_size / 2.0); + cairo_stroke(cr); + cairo_set_line_width(cr, cairo_get_line_width(cr) / 1.6); + + // draw unrated star + dt_draw_star(cr, star_size / 2.0 + x, star_size / 2.0, star_size / 2.0, star_size / (2.0 * 2.5)); + cairo_stroke(cr); + x += star_size + star_spacing; + d->current = 0; - for(int k = 0; k < 5; k++) + for (int k = 0; k < 5; k++) { /* outline star */ dt_draw_star(cr, star_size / 2.0 + x, star_size / 2.0, star_size / 2.0, star_size / (2.0 * 2.5)); - if(x < d->pointerx) + if (x < d->pointerx) { cairo_fill_preserve(cr); cairo_set_source_rgba(cr, fg_color.red, fg_color.green, fg_color.blue, fg_color.alpha * 0.5); cairo_stroke(cr); gdk_cairo_set_source_rgba(cr, &fg_color); - if((k + 1) > d->current) d->current = darktable.control->element = (k + 1); + if ((k + 1) > d->current) + d->current = darktable.control->element = (k + 1); } else cairo_stroke(cr); + x += star_size + star_spacing; } @@ -194,7 +207,7 @@ static gboolean _lib_ratings_button_press_callback(GtkWidget *widget, GdkEventBu dt_lib_module_t *self) { dt_lib_ratings_t *d = self->data; - if(d->current > 0) + //if(d->current > 0) { GList *imgs = dt_act_on_get_images(FALSE, TRUE, FALSE); dt_ratings_apply_on_list(imgs, d->current, TRUE); From ada36a2f19413caa12c2ec50916a730a6fc3c936 Mon Sep 17 00:00:00 2001 From: deekayhd <53017684+deekayhd@users.noreply.github.com> Date: Sun, 31 May 2026 19:14:58 +0200 Subject: [PATCH 2/5] add unrate button to thumbnail overlay --- src/dtgtk/thumbnail.c | 23 +++++++++++++++++++++-- src/dtgtk/thumbnail.h | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/dtgtk/thumbnail.c b/src/dtgtk/thumbnail.c index b5a4e2445ec3..c6cb0b66fd75 100644 --- a/src/dtgtk/thumbnail.c +++ b/src/dtgtk/thumbnail.c @@ -1610,6 +1610,16 @@ GtkWidget *dt_thumbnail_create_widget(dt_thumbnail_t *thumb, gtk_overlay_add_overlay(GTK_OVERLAY(overlays_parent), thumb->w_reject); // the stars + // first for removing the rating + thumb->w_unrate = dtgtk_thumbnail_btn_new(dtgtk_cairo_paint_unratestar, 0, NULL); + gtk_widget_set_name(thumb->w_unrate, "thumb-unrate"); + dt_action_define(&darktable.control->actions_thumb, NULL, "rating", + thumb->w_unrate, &dt_action_def_rating); + gtk_widget_set_valign(thumb->w_unrate, GTK_ALIGN_END); + gtk_widget_set_halign(thumb->w_unrate, GTK_ALIGN_START); + gtk_widget_show(thumb->w_unrate); + gtk_overlay_add_overlay(GTK_OVERLAY(overlays_parent), thumb->w_unrate); + for(int i = 0; i < MAX_STARS; i++) { thumb->w_stars[i] = dtgtk_thumbnail_btn_new(dtgtk_cairo_paint_star, 0, NULL); @@ -1917,6 +1927,15 @@ static void _thumb_resize_overlays(dt_thumbnail_t *thumb) gtk_widget_set_margin_bottom(thumb->w_reject, margin_b_icons); // stars + gtk_widget_set_size_request(thumb->w_unrate, icon_size, icon_size); + gtk_widget_set_valign(thumb->w_unrate, GTK_ALIGN_END); + gtk_widget_set_margin_bottom(thumb->w_unrate, margin_b_icons); + gtk_widget_set_margin_start( + thumb->w_unrate, + thumb->img_margin->left + + (width - thumb->img_margin->left + - thumb->img_margin->right - (MAX_STARS + 1) * icon_size) * 0.5 ); + for(int i = 0; i < MAX_STARS; i++) { gtk_widget_set_size_request(thumb->w_stars[i], icon_size, icon_size); @@ -1926,8 +1945,8 @@ static void _thumb_resize_overlays(dt_thumbnail_t *thumb) thumb->w_stars[i], thumb->img_margin->left + (width - thumb->img_margin->left - - thumb->img_margin->right - MAX_STARS * icon_size) * 0.5 - + i * icon_size); + - thumb->img_margin->right - (MAX_STARS + 1) * icon_size) * 0.5 + + (i + 1) * icon_size); } // the color labels diff --git a/src/dtgtk/thumbnail.h b/src/dtgtk/thumbnail.h index 9a8e42b431cc..dc721511b722 100644 --- a/src/dtgtk/thumbnail.h +++ b/src/dtgtk/thumbnail.h @@ -123,6 +123,7 @@ typedef struct GtkWidget *w_bottom_eb; // GtkEventBox -- background of the bottom infos area (contains w_bottom) GtkWidget *w_bottom; // GtkLabel -- text of the bottom infos area, just with #thumb-bottom GtkWidget *w_reject; // GtkDarktableThumbnailBtn -- Reject icon + GtkWidget *w_unrate; // GtkDarktableThumbnailBtn -- Unrate icon GtkWidget *w_stars[MAX_STARS]; // GtkDarktableThumbnailBtn -- Stars icons GtkWidget *w_color; // GtkDarktableThumbnailBtn -- Colorlabels "flower" icon From 820547fdcfb38b7043a3401992ffdd11092d8a59 Mon Sep 17 00:00:00 2001 From: deekayhd <53017684+deekayhd@users.noreply.github.com> Date: Sun, 31 May 2026 20:00:00 +0200 Subject: [PATCH 3/5] add logic --- src/dtgtk/thumbnail.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dtgtk/thumbnail.c b/src/dtgtk/thumbnail.c index c6cb0b66fd75..588ab35f15c7 100644 --- a/src/dtgtk/thumbnail.c +++ b/src/dtgtk/thumbnail.c @@ -1070,8 +1070,10 @@ static gboolean _event_rating_release(GtkWidget *widget, rating = DT_VIEW_STAR_4; else if(widget == thumb->w_stars[4]) rating = DT_VIEW_STAR_5; + else if(widget == thumb->w_unrate) + rating = DT_VIEW_DESERT; - if(rating != DT_VIEW_DESERT) + if(rating != DT_VIEW_DESERT || widget == thumb->w_unrate) { dt_ratings_apply_on_image(thumb->imgid, rating, TRUE, TRUE, TRUE); dt_collection_update_query(darktable.collection, @@ -1619,6 +1621,15 @@ GtkWidget *dt_thumbnail_create_widget(dt_thumbnail_t *thumb, gtk_widget_set_halign(thumb->w_unrate, GTK_ALIGN_START); gtk_widget_show(thumb->w_unrate); gtk_overlay_add_overlay(GTK_OVERLAY(overlays_parent), thumb->w_unrate); + g_signal_connect(G_OBJECT(thumb->w_unrate), "enter-notify-event", + G_CALLBACK(_event_star_enter), thumb); + g_signal_connect(G_OBJECT(thumb->w_unrate), "leave-notify-event", + G_CALLBACK(_event_star_leave), thumb); + g_signal_connect(G_OBJECT(thumb->w_unrate), "button-press-event", + G_CALLBACK(_event_rating_press), thumb); + g_signal_connect(G_OBJECT(thumb->w_unrate), "button-release-event", + G_CALLBACK(_event_rating_release), + thumb); for(int i = 0; i < MAX_STARS; i++) { From 97c5ccf5e8a241d187f55cefc6f91f9bf5152a6f Mon Sep 17 00:00:00 2001 From: deekayhd <53017684+deekayhd@users.noreply.github.com> Date: Sun, 31 May 2026 21:20:52 +0200 Subject: [PATCH 4/5] correct icon --- src/libs/tools/ratings.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libs/tools/ratings.c b/src/libs/tools/ratings.c index 4779be30a943..6bf4ad94e2cb 100644 --- a/src/libs/tools/ratings.c +++ b/src/libs/tools/ratings.c @@ -152,17 +152,20 @@ static gboolean _lib_ratings_draw_callback(GtkWidget *widget, cairo_t *crf, dt_l int x = 0; cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1)); gdk_cairo_set_source_rgba(cr, &fg_color); + + // draw unrated star + cairo_set_source_rgba(cr, fg_color.red, fg_color.green, fg_color.blue, fg_color.alpha * 0.3); + dt_draw_star(cr, star_size / 2.0 + x, star_size / 2.0, star_size / 2.0, star_size / (2.0 * 2.5)); + cairo_stroke(cr); + gdk_cairo_set_source_rgba(cr, &fg_color); cairo_set_line_width(cr, 1.6 * cairo_get_line_width(cr)); cairo_move_to(cr, x + star_size * .1, star_size / 2.0); cairo_line_to(cr, x + star_size * .9, star_size / 2.0); cairo_stroke(cr); cairo_set_line_width(cr, cairo_get_line_width(cr) / 1.6); - - // draw unrated star - dt_draw_star(cr, star_size / 2.0 + x, star_size / 2.0, star_size / 2.0, star_size / (2.0 * 2.5)); - cairo_stroke(cr); x += star_size + star_spacing; + // now the regular stars d->current = 0; for (int k = 0; k < 5; k++) { From f9c9ebba463cef5c9e40cf4c38a701ad88049803 Mon Sep 17 00:00:00 2001 From: deekayhd <53017684+deekayhd@users.noreply.github.com> Date: Wed, 3 Jun 2026 15:55:57 +0200 Subject: [PATCH 5/5] clean up code --- src/libs/tools/ratings.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libs/tools/ratings.c b/src/libs/tools/ratings.c index 6bf4ad94e2cb..7f31abdf1b0c 100644 --- a/src/libs/tools/ratings.c +++ b/src/libs/tools/ratings.c @@ -167,17 +167,17 @@ static gboolean _lib_ratings_draw_callback(GtkWidget *widget, cairo_t *crf, dt_l // now the regular stars d->current = 0; - for (int k = 0; k < 5; k++) + for(int k = 0; k < 5; k++) { /* outline star */ dt_draw_star(cr, star_size / 2.0 + x, star_size / 2.0, star_size / 2.0, star_size / (2.0 * 2.5)); - if (x < d->pointerx) + if(x < d->pointerx) { cairo_fill_preserve(cr); cairo_set_source_rgba(cr, fg_color.red, fg_color.green, fg_color.blue, fg_color.alpha * 0.5); cairo_stroke(cr); gdk_cairo_set_source_rgba(cr, &fg_color); - if ((k + 1) > d->current) + if((k + 1) > d->current) d->current = darktable.control->element = (k + 1); } else @@ -210,14 +210,13 @@ static gboolean _lib_ratings_button_press_callback(GtkWidget *widget, GdkEventBu dt_lib_module_t *self) { dt_lib_ratings_t *d = self->data; - //if(d->current > 0) - { - GList *imgs = dt_act_on_get_images(FALSE, TRUE, FALSE); - dt_ratings_apply_on_list(imgs, d->current, TRUE); - dt_collection_update_query(darktable.collection, DT_COLLECTION_CHANGE_RELOAD, DT_COLLECTION_PROP_RATING_RANGE, imgs); - dt_control_queue_redraw_center(); - } + GList *imgs = dt_act_on_get_images(FALSE, TRUE, FALSE); + dt_ratings_apply_on_list(imgs, d->current, TRUE); + dt_collection_update_query(darktable.collection, DT_COLLECTION_CHANGE_RELOAD, DT_COLLECTION_PROP_RATING_RANGE, imgs); + + dt_control_queue_redraw_center(); + return TRUE; }