diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-10-27 12:17:37 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-10-27 12:31:11 -0400 |
commit | d323c88a4ad0962e3dd44ef70a8c3aee86ff467e (patch) | |
tree | 6079f37ea1b6309ae445dda2edf3ffd070c2c733 | |
parent | 6d5c512571889860bc3583bd46e2b33acd185c3f (diff) | |
download | gtk+-dropdown-checkmark.tar.gz |
dropdown: Add a checkmark to the selected itemdropdown-checkmark
Make the default factory add a checkmark to the
currently selected item (not the hovered item)
in the popup. This will unfortunately have to be
done in non-default factories too.
Related: #3291
-rw-r--r-- | gtk/gtkdropdown.c | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/gtk/gtkdropdown.c b/gtk/gtkdropdown.c index 80dc7a1ae6..54f2164e64 100644 --- a/gtk/gtkdropdown.c +++ b/gtk/gtkdropdown.c @@ -44,6 +44,7 @@ #include "gtkbuildable.h" #include "gtkbuilderprivate.h" #include "gtkstringlist.h" +#include "gtkbox.h" /** * SECTION:gtkdropdown @@ -537,11 +538,34 @@ setup_item (GtkSignalListItemFactory *factory, GtkListItem *list_item, gpointer data) { + GtkWidget *box; GtkWidget *label; + GtkWidget *icon; + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); label = gtk_label_new (NULL); gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_list_item_set_child (list_item, label); + gtk_box_append (GTK_BOX (box), label); + icon = gtk_image_new_from_icon_name ("object-select-symbolic"); + gtk_box_append (GTK_BOX (box), icon); + gtk_list_item_set_child (list_item, box); +} + +static void +selected_changed (GtkDropDown *self, + GParamSpec *pspec, + GtkListItem *list_item) +{ + GtkWidget *box; + GtkWidget *icon; + + box = gtk_list_item_get_child (list_item); + icon = gtk_widget_get_last_child (box); + + if (gtk_drop_down_get_selected (self) == gtk_list_item_get_position (list_item)) + gtk_widget_set_opacity (icon, 1.0); + else + gtk_widget_set_opacity (icon, 0.0); } static void @@ -551,11 +575,15 @@ bind_item (GtkSignalListItemFactory *factory, { GtkDropDown *self = data; gpointer item; + GtkWidget *box; GtkWidget *label; + GtkWidget *icon; GValue value = G_VALUE_INIT; item = gtk_list_item_get_item (list_item); - label = gtk_list_item_get_child (list_item); + box = gtk_list_item_get_child (list_item); + label = gtk_widget_get_first_child (box); + icon = gtk_widget_get_last_child (box); if (self->expression && gtk_expression_evaluate (self->expression, item, &value)) @@ -574,6 +602,27 @@ bind_item (GtkSignalListItemFactory *factory, { g_critical ("Either GtkDropDown:factory or GtkDropDown:expression must be set"); } + + if (gtk_widget_get_ancestor (box, GTK_TYPE_POPOVER) == self->popup) + { + gtk_widget_show (icon); + g_signal_connect (self, "notify::selected", G_CALLBACK (selected_changed), list_item); + selected_changed (self, NULL, list_item); + } + else + { + gtk_widget_hide (icon); + } +} + +static void +unbind_item (GtkSignalListItemFactory *factory, + GtkListItem *list_item, + gpointer data) +{ + GtkDropDown *self = data; + + g_signal_handlers_disconnect_by_func (self, selected_changed, list_item); } static void @@ -585,6 +634,7 @@ set_default_factory (GtkDropDown *self) g_signal_connect (factory, "setup", G_CALLBACK (setup_item), self); g_signal_connect (factory, "bind", G_CALLBACK (bind_item), self); + g_signal_connect (factory, "unbind", G_CALLBACK (unbind_item), self); gtk_drop_down_set_factory (self, factory); |