summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhuyaliang <[email protected]>2023-03-30 17:15:09 +0800
committerLuke from DC <[email protected]>2023-04-02 16:14:14 +0000
commit3312217c28c82ff2eb6e02154460e75f5de9c18f (patch)
treefa8e27da996b4e2b46676dd60ffabf00ffd72431
parent96e97b3bd0593c6c160d571c54ea2ebf6ee1c011 (diff)
downloadmate-desktop-3312217c28c82ff2eb6e02154460e75f5de9c18f.tar.bz2
mate-desktop-3312217c28c82ff2eb6e02154460e75f5de9c18f.tar.xz
Add mate image menu item apis
-rw-r--r--docs/reference/mate-desktop/mate-desktop-docs.sgml5
-rw-r--r--docs/reference/mate-desktop/mate-desktop-sections.txt10
-rw-r--r--libmate-desktop/Makefile.am14
-rw-r--r--libmate-desktop/mate-desktop.abi5
-rw-r--r--libmate-desktop/mate-image-menu-item.c552
-rw-r--r--libmate-desktop/mate-image-menu-item.h42
-rw-r--r--libmate-desktop/meson.build8
-rw-r--r--libmate-desktop/test-image-menu-item.c88
8 files changed, 721 insertions, 3 deletions
diff --git a/docs/reference/mate-desktop/mate-desktop-docs.sgml b/docs/reference/mate-desktop/mate-desktop-docs.sgml
index a629d8c..7daa9df 100644
--- a/docs/reference/mate-desktop/mate-desktop-docs.sgml
+++ b/docs/reference/mate-desktop/mate-desktop-docs.sgml
@@ -41,6 +41,11 @@ The libmate-desktop library contains APIs that can be useful for a few applicati
<xi:include href="xml/mate-languages.xml"/>
</part>
+ <part id="image-menu-item">
+ <title>MateImageMenuItem</title>
+ <xi:include href="xml/mate-image-menu-item.xml"/>
+ </part>
+
<part id="libmate">
<title>Miscellaneous</title>
<xi:include href="xml/mate-desktop-item.xml"/>
diff --git a/docs/reference/mate-desktop/mate-desktop-sections.txt b/docs/reference/mate-desktop/mate-desktop-sections.txt
index 7145307..7d89696 100644
--- a/docs/reference/mate-desktop/mate-desktop-sections.txt
+++ b/docs/reference/mate-desktop/mate-desktop-sections.txt
@@ -280,6 +280,16 @@ mate_language_has_translations
</SECTION>
<SECTION>
+<FILE>mate-image-menu-item</FILE>
+<TITLE>MateImageMenuItem</TITLE>
+mate_image_menu_item_new
+mate_image_menu_item_new_with_label
+mate_image_menu_item_new_with_mnemonic
+mate_image_menu_item_set_image
+mate_image_menu_item_get_image
+</SECTION>
+
+<SECTION>
<INCLUDE>mate-desktop-utils.h</INCLUDE>
<FILE>mate-desktop-utils</FILE>
<TITLE>Miscellaneous Functions</TITLE>
diff --git a/libmate-desktop/Makefile.am b/libmate-desktop/Makefile.am
index 0c63a9f..44b8b9b 100644
--- a/libmate-desktop/Makefile.am
+++ b/libmate-desktop/Makefile.am
@@ -15,7 +15,8 @@ libmate_desktop_HEADERS = \
mate-colorbutton.h \
mate-colorsel.h \
mate-hsv.h \
- mate-colorseldialog.h
+ mate-colorseldialog.h \
+ mate-image-menu-item.h
lib_LTLIBRARIES = libmate-desktop-2.la
@@ -31,7 +32,7 @@ AM_CPPFLAGS = \
AM_CFLAGS = $(WARN_CFLAGS)
-noinst_PROGRAMS = test-desktop-thumbnail test-ditem test test-languages
+noinst_PROGRAMS = test-desktop-thumbnail test-ditem test test-languages test-image-menu-item
CLEANFILES =
@@ -52,7 +53,8 @@ introspection_sources = \
mate-colorsel.c \
mate-hsv.c \
mate-colorseldialog.c \
- edid-parse.c
+ edid-parse.c \
+ mate-image-menu-item.c
libmate_desktop_2_la_SOURCES = \
$(introspection_sources) \
@@ -98,6 +100,12 @@ test_languages_LDADD = \
libmate-desktop-2.la \
$(MATE_DESKTOP_LIBS)
+test_image_menu_item_SOURCES = test-image-menu-item.c
+
+test_image_menu_item_LDADD = \
+ libmate-desktop-2.la \
+ $(MATE_DESKTOP_LIBS)
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = mate-desktop-2.0.pc
diff --git a/libmate-desktop/mate-desktop.abi b/libmate-desktop/mate-desktop.abi
index 7b57994..4addd07 100644
--- a/libmate-desktop/mate-desktop.abi
+++ b/libmate-desktop/mate-desktop.abi
@@ -148,6 +148,11 @@ mate_hsv_is_adjusting
mate_hsv_new
mate_hsv_set_color
mate_hsv_set_metrics
+mate_image_menu_item_new
+mate_image_menu_item_new_with_label
+mate_image_menu_item_new_with_mnemonic
+mate_image_menu_item_set_image
+mate_image_menu_item_get_image
mate_language_has_translations
mate_normalize_locale
mate_parse_locale
diff --git a/libmate-desktop/mate-image-menu-item.c b/libmate-desktop/mate-image-menu-item.c
new file mode 100644
index 0000000..85bc2f3
--- /dev/null
+++ b/libmate-desktop/mate-image-menu-item.c
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2023 zhuyaliang.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include "mate-image-menu-item.h"
+
+struct _MateImageMenuItem
+{
+ GtkMenuItem menu_item;
+ GtkWidget *image;
+ gchar *label;
+};
+
+enum {
+ PROP_0,
+ PROP_IMAGE,
+};
+
+G_DEFINE_TYPE (MateImageMenuItem, mate_image_menu_item, GTK_TYPE_MENU_ITEM)
+
+static void
+mate_image_menu_item_destroy (GtkWidget *widget)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (widget);
+
+ if (image_menu_item->image)
+ gtk_container_remove (GTK_CONTAINER (image_menu_item),
+ image_menu_item->image);
+
+ GTK_WIDGET_CLASS (mate_image_menu_item_parent_class)->destroy (widget);
+}
+
+static void
+mate_image_menu_item_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (widget);
+ GtkPackDirection pack_dir;
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (widget);
+
+ if (GTK_IS_MENU_BAR (parent))
+ pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
+ else
+ pack_dir = GTK_PACK_DIRECTION_LTR;
+
+ GTK_WIDGET_CLASS (mate_image_menu_item_parent_class)->get_preferred_width (widget, minimum, natural);
+
+ if ((pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT) &&
+ image_menu_item->image &&
+ gtk_widget_get_visible (image_menu_item->image))
+ {
+ gint child_minimum, child_natural;
+
+ gtk_widget_get_preferred_width (image_menu_item->image, &child_minimum, &child_natural);
+
+ *minimum = MAX (*minimum, child_minimum);
+ *natural = MAX (*natural, child_natural);
+ }
+}
+
+static void
+mate_image_menu_item_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (widget);
+ gint child_height = 0;
+ GtkPackDirection pack_dir;
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (widget);
+
+ if (GTK_IS_MENU_BAR (parent))
+ pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
+ else
+ pack_dir = GTK_PACK_DIRECTION_LTR;
+
+ if (image_menu_item->image && gtk_widget_get_visible (image_menu_item->image))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_preferred_size (image_menu_item->image, &child_requisition, NULL);
+
+ child_height = child_requisition.height;
+ }
+
+ GTK_WIDGET_CLASS (mate_image_menu_item_parent_class)->get_preferred_height (widget, minimum, natural);
+
+ if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR)
+ {
+ *minimum = MAX (*minimum, child_height);
+ *natural = MAX (*natural, child_height);
+ }
+}
+
+static void
+mate_image_menu_item_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum,
+ gint *natural)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (widget);
+ gint child_height = 0;
+ GtkPackDirection pack_dir;
+ GtkWidget *parent;
+
+ parent = gtk_widget_get_parent (widget);
+
+ if (GTK_IS_MENU_BAR (parent))
+ pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
+ else
+ pack_dir = GTK_PACK_DIRECTION_LTR;
+
+ if (image_menu_item->image && gtk_widget_get_visible (image_menu_item->image))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_preferred_size (image_menu_item->image, &child_requisition, NULL);
+
+ child_height = child_requisition.height;
+ }
+
+ GTK_WIDGET_CLASS (mate_image_menu_item_parent_class)->get_preferred_height_for_width (widget, width, minimum, natural);
+
+ if (pack_dir == GTK_PACK_DIRECTION_RTL || pack_dir == GTK_PACK_DIRECTION_LTR)
+ {
+ *minimum = MAX (*minimum, child_height);
+ *natural = MAX (*natural, child_height);
+ }
+}
+
+static void
+mate_image_menu_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (widget);
+ GtkAllocation widget_allocation;
+ GtkRequisition image_requisition;
+ GtkPackDirection pack_dir;
+ GtkTextDirection text_dir;
+ GtkAllocation image_allocation;
+ GtkStyleContext *context;
+ GtkStateFlags state;
+ GtkBorder padding;
+ GtkWidget *parent;
+ gint toggle_size;
+ gint x;
+ gint y;
+
+ parent = gtk_widget_get_parent (widget);
+
+ if (GTK_IS_MENU_BAR (parent))
+ pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
+ else
+ pack_dir = GTK_PACK_DIRECTION_LTR;
+
+ GTK_WIDGET_CLASS (mate_image_menu_item_parent_class)->size_allocate (widget, allocation);
+
+ if (!image_menu_item->image || !gtk_widget_get_visible (image_menu_item->image))
+ return;
+
+ gtk_widget_get_allocation (widget, &widget_allocation);
+ gtk_widget_get_preferred_size (image_menu_item->image, &image_requisition, NULL);
+
+ context = gtk_widget_get_style_context (widget);
+ state = gtk_style_context_get_state (context);
+ gtk_style_context_get_padding (context, state, &padding);
+
+ toggle_size = 0;
+ gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (image_menu_item), &toggle_size);
+
+ text_dir = gtk_widget_get_direction (widget);
+
+ if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL)
+ {
+ if ((text_dir == GTK_TEXT_DIR_LTR) == (pack_dir == GTK_PACK_DIRECTION_LTR))
+ {
+ x = padding.left + (toggle_size - image_requisition.width) / 2;
+ }
+ else
+ {
+ x = widget_allocation.width - padding.right - toggle_size +
+ (toggle_size - image_requisition.width) / 2;
+ }
+
+ y = (widget_allocation.height - image_requisition.height) / 2;
+ }
+ else
+ {
+ if ((text_dir == GTK_TEXT_DIR_LTR) == (pack_dir == GTK_PACK_DIRECTION_TTB))
+ {
+ y = padding.top + (toggle_size - image_requisition.height) / 2;
+ }
+ else
+ {
+ y = widget_allocation.height - padding.bottom - toggle_size +
+ (toggle_size - image_requisition.height) / 2;
+ }
+
+ x = (widget_allocation.width - image_requisition.width) / 2;
+ }
+
+ image_allocation.x = widget_allocation.x + MAX (0, x);
+ image_allocation.y = widget_allocation.y + MAX (0, y);
+ image_allocation.width = image_requisition.width;
+ image_allocation.height = image_requisition.height;
+
+ gtk_widget_size_allocate (image_menu_item->image, &image_allocation);
+}
+
+static void
+mate_image_menu_item_add (GtkContainer *container,
+ GtkWidget *widget)
+{
+ GTK_CONTAINER_CLASS (mate_image_menu_item_parent_class)->add (container, widget);
+}
+
+static void
+mate_image_menu_item_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (container);
+
+ GTK_CONTAINER_CLASS (mate_image_menu_item_parent_class)->forall (container,
+ include_internals,
+ callback,
+ callback_data);
+
+ if (include_internals && image_menu_item->image)
+ (* callback) (image_menu_item->image, callback_data);
+}
+
+static void
+mate_image_menu_item_remove (GtkContainer *container,
+ GtkWidget *child)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (container);
+
+ if (child == image_menu_item->image)
+ {
+ gboolean widget_was_visible;
+
+ widget_was_visible = gtk_widget_get_visible (child);
+
+ gtk_widget_unparent (child);
+ image_menu_item->image = NULL;
+
+ if (widget_was_visible &&
+ gtk_widget_get_visible (GTK_WIDGET (container)))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+
+ g_object_notify (G_OBJECT (image_menu_item), "image");
+ }
+ else
+ {
+ GTK_CONTAINER_CLASS (mate_image_menu_item_parent_class)->remove (container, child);
+ }
+}
+
+static void
+mate_image_menu_item_toggle_size_request (GtkMenuItem *menu_item,
+ gint *requisition)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (menu_item);
+ GtkPackDirection pack_dir;
+ GtkWidget *parent;
+ GtkWidget *widget = GTK_WIDGET (menu_item);
+
+ parent = gtk_widget_get_parent (widget);
+
+ if (GTK_IS_MENU_BAR (parent))
+ pack_dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
+ else
+ pack_dir = GTK_PACK_DIRECTION_LTR;
+
+ *requisition = 0;
+
+ if (image_menu_item->image && gtk_widget_get_visible (image_menu_item->image))
+ {
+ GtkRequisition image_requisition;
+ guint toggle_spacing;
+
+ gtk_widget_get_preferred_size (image_menu_item->image, &image_requisition, NULL);
+
+ gtk_widget_style_get (GTK_WIDGET (menu_item),
+ "toggle-spacing", &toggle_spacing,
+ NULL);
+
+ if (pack_dir == GTK_PACK_DIRECTION_LTR || pack_dir == GTK_PACK_DIRECTION_RTL)
+ {
+ if (image_requisition.width > 0)
+ *requisition = image_requisition.width + toggle_spacing;
+ }
+ else
+ {
+ if (image_requisition.height > 0)
+ *requisition = image_requisition.height + toggle_spacing;
+ }
+ }
+}
+
+static void
+mate_image_menu_item_set_label (GtkMenuItem *menu_item,
+ const gchar *label)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (menu_item);
+
+ if (image_menu_item->label != label)
+ {
+ g_free (image_menu_item->label);
+ image_menu_item->label = g_strdup (label);
+ GTK_MENU_ITEM_CLASS (mate_image_menu_item_parent_class)->set_label (menu_item, label);
+ g_object_notify (G_OBJECT (menu_item), "label");
+ }
+}
+
+static const gchar *
+mate_image_menu_item_get_label (GtkMenuItem *menu_item)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (menu_item);
+
+ return image_menu_item->label;
+}
+
+static void
+mate_image_menu_item_finalize (GObject *object)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (object);
+
+ g_free (image_menu_item->label);
+ image_menu_item->label = NULL;
+
+ G_OBJECT_CLASS (mate_image_menu_item_parent_class)->finalize (object);
+}
+
+static void
+mate_image_menu_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_IMAGE:
+ mate_image_menu_item_set_image (image_menu_item, (GtkWidget *) g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_image_menu_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateImageMenuItem *image_menu_item = MATE_IMAGE_MENU_ITEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_IMAGE:
+ g_value_set_object (value, mate_image_menu_item_get_image (image_menu_item));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_image_menu_item_class_init (MateImageMenuItemClass *class)
+{
+ GObjectClass *gobject_class = (GObjectClass*) class;
+ GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
+ GtkMenuItemClass *menu_item_class = (GtkMenuItemClass*) class;
+ GtkContainerClass *container_class = (GtkContainerClass*) class;
+
+ widget_class->destroy = mate_image_menu_item_destroy;
+ widget_class->get_preferred_width = mate_image_menu_item_get_preferred_width;
+ widget_class->get_preferred_height = mate_image_menu_item_get_preferred_height;
+ widget_class->get_preferred_height_for_width = mate_image_menu_item_get_preferred_height_for_width;
+ widget_class->size_allocate = mate_image_menu_item_size_allocate;
+
+ container_class->add = mate_image_menu_item_add;
+ container_class->forall = mate_image_menu_item_forall;
+ container_class->remove = mate_image_menu_item_remove;
+
+ menu_item_class->toggle_size_request = mate_image_menu_item_toggle_size_request;
+ menu_item_class->set_label = mate_image_menu_item_set_label;
+ menu_item_class->get_label = mate_image_menu_item_get_label;
+
+ gobject_class->finalize = mate_image_menu_item_finalize;
+ gobject_class->set_property = mate_image_menu_item_set_property;
+ gobject_class->get_property = mate_image_menu_item_get_property;
+
+ /**
+ * MateImageMenuItem:image:
+ *
+ * Child widget to appear next to the menu text.
+ *
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_IMAGE,
+ g_param_spec_object ("image",
+ _("Image widget"),
+ _("Child widget to appear next to the menu text"),
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE | G_PARAM_DEPRECATED));
+}
+
+static void
+mate_image_menu_item_init (MateImageMenuItem *image_menu_item)
+{
+ image_menu_item->image = NULL;
+ image_menu_item->label = NULL;
+}
+
+/**
+ * mate_image_menu_item_new:
+ *
+ * Creates a new #MateImageMenuItem with an empty label.
+ *
+ * Returns: a new #MateImageMenuItem
+ *
+ */
+GtkWidget*
+mate_image_menu_item_new (void)
+{
+ return g_object_new (MATE_TYPE_IMAGE_MENU_ITEM, NULL);
+}
+
+/**
+ * mate_image_menu_item_new_with_label:
+ * @label: the text of the menu item.
+ *
+ * Creates a new #MateImageMenuItem containing a label.
+ *
+ * Returns: a new #MateImageMenuItem.
+ *
+ */
+GtkWidget*
+mate_image_menu_item_new_with_label (const gchar *label)
+{
+ return g_object_new (MATE_TYPE_IMAGE_MENU_ITEM,
+ "label", label,
+ NULL);
+}
+
+/**
+ * mate_image_menu_item_new_with_mnemonic:
+ * @label: the text of the menu item, with an underscore in front of the
+ * mnemonic character
+ *
+ * Creates a new #MateImageMenuItem containing a label. The label
+ * will be created using gtk_label_new_with_mnemonic(), so underscores
+ * in @label indicate the mnemonic for the menu item.
+ *
+ * Returns: a new #MateImageMenuItem
+ *
+ */
+GtkWidget*
+mate_image_menu_item_new_with_mnemonic (const gchar *label)
+{
+ return g_object_new (MATE_TYPE_IMAGE_MENU_ITEM,
+ "use-underline", TRUE,
+ "label", label,
+ NULL);
+}
+
+/**
+ * mate_image_menu_item_set_image:
+ * @image_menu_item: a #MateImageMenuItem.
+ * @image: (allow-none): a widget to set as the image for the menu item.
+ *
+ * Sets the image of @image_menu_item to the given widget.
+ * Note that it depends on the show-menu-images setting whether
+ * the image will be displayed or not.
+ *
+ */
+void
+mate_image_menu_item_set_image (MateImageMenuItem *image_menu_item,
+ GtkWidget *image)
+{
+ g_return_if_fail (MATE_IS_IMAGE_MENU_ITEM (image_menu_item));
+
+ if (image == image_menu_item->image)
+ return;
+
+ if (image_menu_item->image)
+ gtk_container_remove (GTK_CONTAINER (image_menu_item),
+ image_menu_item->image);
+
+ image_menu_item->image = image;
+
+ if (image == NULL)
+ return;
+
+ gtk_widget_set_parent (image, GTK_WIDGET (image_menu_item));
+ g_object_set (image,
+ "visible", TRUE,
+ "no-show-all", TRUE,
+ NULL);
+ gtk_image_set_pixel_size (GTK_IMAGE (image), 16);
+
+ g_object_notify (G_OBJECT (image_menu_item), "image");
+}
+
+/**
+ * mate_image_menu_item_get_image:
+ * @image_menu_item: a #MateImageMenuItem
+ *
+ * Gets the widget that is currently set as the image of @image_menu_item.
+ * See mate_image_menu_item_set_image().
+ *
+ * Returns: (transfer none): the widget set as image of @image_menu_item
+ *
+ **/
+GtkWidget*
+mate_image_menu_item_get_image (MateImageMenuItem *image_menu_item)
+{
+ g_return_val_if_fail (MATE_IS_IMAGE_MENU_ITEM (image_menu_item), NULL);
+
+ return image_menu_item->image;
+}
diff --git a/libmate-desktop/mate-image-menu-item.h b/libmate-desktop/mate-image-menu-item.h
new file mode 100644
index 0000000..4e0c97b
--- /dev/null
+++ b/libmate-desktop/mate-image-menu-item.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 zhuyaliang.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MATE_IMAGE_MENU_ITEM_H__
+#define __MATE_IMAGE_MENU_ITEM_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define MATE_TYPE_IMAGE_MENU_ITEM (mate_image_menu_item_get_type ())
+
+G_DECLARE_FINAL_TYPE (MateImageMenuItem, mate_image_menu_item, MATE, IMAGE_MENU_ITEM, GtkMenuItem);
+
+GtkWidget* mate_image_menu_item_new (void);
+
+GtkWidget* mate_image_menu_item_new_with_label (const gchar *label);
+
+GtkWidget* mate_image_menu_item_new_with_mnemonic (const gchar *label);
+
+void mate_image_menu_item_set_image (MateImageMenuItem *image_menu_item,
+ GtkWidget *image);
+
+GtkWidget* mate_image_menu_item_get_image (MateImageMenuItem *image_menu_item);
+
+G_END_DECLS
+
+#endif /* __GTK_IMAGE_MENU_ITEM_H__ */
diff --git a/libmate-desktop/meson.build b/libmate-desktop/meson.build
index 1fd0569..b11f242 100644
--- a/libmate-desktop/meson.build
+++ b/libmate-desktop/meson.build
@@ -11,6 +11,7 @@ headers = files(
'mate-desktop-thumbnail.h',
'mate-rr.h',
'mate-languages.h',
+ 'mate-image-menu-item.h',
'mate-rr-config.h',
'mate-rr-labeler.h',
'mate-colorbutton.h',
@@ -35,6 +36,7 @@ sources = files(
'display-name.c',
'mate-rr.c',
'mate-languages.c',
+ 'mate-image-menu-item.c',
'mate-rr-config.c',
'mate-rr-output-info.c',
'mate-rr-labeler.c',
@@ -160,3 +162,9 @@ test_languages = executable('test-languages',
dependencies : libmate_desktop_dep,
install : false,
)
+
+test_image_menu_item = executable('test-image-menu-item',
+ sources : 'test-image-menu-item.c',
+ dependencies : libmate_desktop_dep,
+ install : false,
+)
diff --git a/libmate-desktop/test-image-menu-item.c b/libmate-desktop/test-image-menu-item.c
new file mode 100644
index 0000000..dcd08cd
--- /dev/null
+++ b/libmate-desktop/test-image-menu-item.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023 zhuyaliang.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mate-image-menu-item.h"
+static void
+test_menu_cb (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ GtkWidget *image;
+ const char *icon_name;
+
+ image = mate_image_menu_item_get_image (MATE_IMAGE_MENU_ITEM (menuitem));
+ gtk_image_get_icon_name (GTK_IMAGE (image), &icon_name, NULL);
+ g_print ("menu item icon is %s\r\n", icon_name);
+}
+
+int main (int argc, char **argv)
+{
+ GtkWidget *window;
+ GtkWidget *box;
+ GtkWidget *button;
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+ GtkWidget *label;
+ GtkWidget *image;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (window), 350, 220);
+ g_signal_connect ((window), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
+
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+ gtk_container_add (GTK_CONTAINER (window), box);
+
+ button = gtk_menu_button_new ();
+ gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
+ gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
+
+ gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 6);
+
+ menu = gtk_menu_new ();
+ gtk_menu_button_set_popup (GTK_MENU_BUTTON (button), menu);
+
+ menuitem = mate_image_menu_item_new ();
+ label = gtk_label_new ("test image_menu_item_new");
+ gtk_container_add (GTK_CONTAINER (menuitem), label);
+ image = gtk_image_new_from_icon_name ("edit-copy", GTK_ICON_SIZE_MENU);
+ mate_image_menu_item_set_image (MATE_IMAGE_MENU_ITEM (menuitem), image);
+ gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
+ g_signal_connect (menuitem, "activate", G_CALLBACK (test_menu_cb), NULL);
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
+
+ menuitem = mate_image_menu_item_new_with_label ("test mate_new_with_label");
+ image = gtk_image_new_from_icon_name ("edit-clear-all", GTK_ICON_SIZE_MENU);
+ mate_image_menu_item_set_image (MATE_IMAGE_MENU_ITEM (menuitem), image);
+ gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
+ g_signal_connect (menuitem, "activate", G_CALLBACK (test_menu_cb), NULL);
+
+ menuitem = mate_image_menu_item_new_with_mnemonic ("test mate_new_with_mnemonic");
+ image = gtk_image_new_from_icon_name ("edit-find-replace", GTK_ICON_SIZE_MENU);
+ mate_image_menu_item_set_image (MATE_IMAGE_MENU_ITEM (menuitem), image);
+ gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
+ g_signal_connect (menuitem, "activate", G_CALLBACK (test_menu_cb), NULL);
+
+ gtk_widget_show_all (menu);
+ gtk_widget_show_all (window);
+
+ gtk_main();
+
+ return 0;
+}