[gtk/wip/exalm/buttons] menubutton: Support custom children
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/exalm/buttons] menubutton: Support custom children
- Date: Fri, 3 Sep 2021 11:18:21 +0000 (UTC)
commit a42d87d813a978817ec72232a616ac7659d82adf
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Fri Sep 3 16:18:06 2021 +0500
menubutton: Support custom children
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4205
gtk/gtkmenubutton.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkmenubutton.h | 6 +++
2 files changed, 138 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c
index e1d8209ddc..5ba36417ca 100644
--- a/gtk/gtkmenubutton.c
+++ b/gtk/gtkmenubutton.c
@@ -87,6 +87,7 @@
#include "config.h"
#include "gtkactionable.h"
+#include "gtkbuildable.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkintl.h"
#include "gtkimage.h"
@@ -122,6 +123,7 @@ struct _GtkMenuButton
GtkWidget *label_widget;
GtkWidget *image_widget;
GtkWidget *arrow_widget;
+ GtkWidget *child;
GtkArrowType arrow_type;
gboolean always_show_arrow;
@@ -147,6 +149,7 @@ enum
PROP_USE_UNDERLINE,
PROP_HAS_FRAME,
PROP_PRIMARY,
+ PROP_CHILD,
LAST_PROP
};
@@ -158,7 +161,10 @@ enum {
static GParamSpec *menu_button_props[LAST_PROP];
static guint signals[LAST_SIGNAL] = { 0 };
-G_DEFINE_TYPE (GtkMenuButton, gtk_menu_button, GTK_TYPE_WIDGET)
+static void gtk_menu_button_buildable_iface_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkMenuButton, gtk_menu_button, GTK_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_menu_button_buildable_iface_init))
static void gtk_menu_button_dispose (GObject *object);
@@ -199,6 +205,9 @@ gtk_menu_button_set_property (GObject *object,
case PROP_PRIMARY:
gtk_menu_button_set_primary (self, g_value_get_boolean (value));
break;
+ case PROP_CHILD:
+ gtk_menu_button_set_child (self, g_value_get_object (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -241,6 +250,9 @@ gtk_menu_button_get_property (GObject *object,
case PROP_PRIMARY:
g_value_set_boolean (value, gtk_menu_button_get_primary (GTK_MENU_BUTTON (object)));
break;
+ case PROP_CHILD:
+ g_value_set_object (value, gtk_menu_button_get_child (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -507,6 +519,20 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * GtkMenuButton:child: (attributes org.gtk.Property.get=gtk_menu_button_get_child
org.gtk.Property.set=gtk_menu_button_set_child)
+ *
+ * The child widget.
+ *
+ * Since: 4.6
+ */
+ menu_button_props[PROP_CHILD] =
+ g_param_spec_object ("child",
+ P_("Child"),
+ P_("The child widget"),
+ GTK_TYPE_WIDGET,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (gobject_class, LAST_PROP, menu_button_props);
/**
@@ -635,6 +661,28 @@ gtk_menu_button_init (GtkMenuButton *self)
gtk_widget_add_css_class (GTK_WIDGET (self), "popup");
}
+static GtkBuildableIface *parent_buildable_iface;
+
+static void
+gtk_menu_button_buildable_add_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const char *type)
+{
+ if (GTK_IS_WIDGET (child))
+ gtk_menu_button_set_child (GTK_MENU_BUTTON (buildable), GTK_WIDGET (child));
+ else
+ parent_buildable_iface->add_child (buildable, builder, child, type);
+}
+
+static void
+gtk_menu_button_buildable_iface_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+
+ iface->add_child = gtk_menu_button_buildable_add_child;
+}
+
/**
* gtk_menu_button_new:
*
@@ -946,6 +994,9 @@ gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
if (gtk_menu_button_get_label (menu_button))
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_LABEL]);
+ if (gtk_menu_button_get_child (menu_button))
+ g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_CHILD]);
+
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
@@ -963,6 +1014,7 @@ gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
gtk_button_set_child (GTK_BUTTON (menu_button->button), box);
menu_button->label_widget = NULL;
+ menu_button->child = NULL;
update_arrow (menu_button);
@@ -1056,6 +1108,8 @@ gtk_menu_button_set_label (GtkMenuButton *menu_button,
if (gtk_menu_button_get_icon_name (menu_button))
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_ICON_NAME]);
+ if (gtk_menu_button_get_child (menu_button))
+ g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_CHILD]);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
label_widget = gtk_label_new (label);
@@ -1072,6 +1126,7 @@ gtk_menu_button_set_label (GtkMenuButton *menu_button,
menu_button->label_widget = label_widget;
menu_button->image_widget = NULL;
+ menu_button->child = NULL;
update_arrow (menu_button);
@@ -1354,3 +1409,79 @@ gtk_menu_button_get_primary (GtkMenuButton *menu_button)
return menu_button->primary;
}
+
+/**
+ * gtk_menu_button_set_child: (attributes org.gtk.Method.set_property=child)
+ * @menu_button: a `GtkMenuButton`
+ * @child: (nullable): the child widget
+ *
+ * Sets the child widget of @menu_button.
+ *
+ * Since: 4.6
+ */
+void
+gtk_menu_button_set_child (GtkMenuButton *menu_button,
+ GtkWidget *child)
+{
+ GtkWidget *box, *arrow;
+
+ g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
+ g_return_if_fail (child == NULL || GTK_IS_WIDGET (child));
+
+ g_object_freeze_notify (G_OBJECT (menu_button));
+
+ if (gtk_menu_button_get_label (menu_button))
+ g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_LABEL]);
+ if (gtk_menu_button_get_icon_name (menu_button))
+ g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_ICON_NAME]);
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
+
+ arrow = gtk_builtin_icon_new ("arrow");
+ menu_button->arrow_widget = arrow;
+
+ gtk_box_append (GTK_BOX (box), child);
+ gtk_box_append (GTK_BOX (box), arrow);
+ gtk_button_set_child (GTK_BUTTON (menu_button->button), box);
+
+ menu_button->child = child;
+
+ menu_button->image_widget = NULL;
+ menu_button->label_widget = NULL;
+
+ update_arrow (menu_button);
+
+ g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_CHILD]);
+
+ g_object_thaw_notify (G_OBJECT (menu_button));
+
+/*
+ g_clear_pointer (&priv->child, gtk_widget_unparent);
+
+ priv->child = child;
+
+ if (priv->child)
+ gtk_widget_set_parent (priv->child, GTK_WIDGET (button));
+
+ gtk_button_set_child_type (button, WIDGET_CHILD);
+ g_object_notify_by_pspec (G_OBJECT (button), props[PROP_CHILD]);*/
+}
+
+/**
+ * gtk_menu_button_get_child: (attributes org.gtk.Method.get_property=child)
+ * @menu_button: a `GtkMenuButton`
+ *
+ * Gets the child widget of @menu_button.
+ *
+ * Returns: (nullable) (transfer none): the child widget of @menu_button
+ *
+ * Since: 4.6
+ */
+GtkWidget *
+gtk_menu_button_get_child (GtkMenuButton *menu_button)
+{
+ g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), NULL);
+
+ return menu_button->child;
+}
diff --git a/gtk/gtkmenubutton.h b/gtk/gtkmenubutton.h
index 390771f049..723adb34da 100644
--- a/gtk/gtkmenubutton.h
+++ b/gtk/gtkmenubutton.h
@@ -121,6 +121,12 @@ void gtk_menu_button_set_primary (GtkMenuButton *menu_button,
GDK_AVAILABLE_IN_4_4
gboolean gtk_menu_button_get_primary (GtkMenuButton *menu_button);
+GDK_AVAILABLE_IN_4_6
+void gtk_menu_button_set_child (GtkMenuButton *menu_button,
+ GtkWidget *child);
+GDK_AVAILABLE_IN_4_6
+GtkWidget * gtk_menu_button_get_child (GtkMenuButton *menu_button);
+
G_END_DECLS
#endif /* __GTK_MENU_BUTTON_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]