[Xfce4-commits] <garcon:master> Add the test menu code again.
Nick Schermer
nick at xfce.org
Mon Aug 17 22:30:02 CEST 2009
Updating branch refs/heads/master
to d68e0db46e0ab86c33a0ca3365f86d80a6d8e180 (commit)
from ad38df8f34a17c8e0d3c971dbcb924ee84f6c865 (commit)
commit d68e0db46e0ab86c33a0ca3365f86d80a6d8e180
Author: Nick Schermer <nick at xfce.org>
Date: Mon Aug 17 22:28:07 2009 +0200
Add the test menu code again.
Useful for testing parts of the code, but only distribute it.
tests/Makefile.am | 3 +
tests/test-display-menu.c | 351 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 354 insertions(+), 0 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d51c387..30b608d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -58,3 +58,6 @@ test_menu_spec_LDADD = \
$(LIBXFCE4UTIL_LIBS) \
$(GLIB_LIBS) \
$(top_builddir)/garcon/libgarcon-$(GARCON_VERSION_API).la
+
+EXTRA_DIST = \
+ test-display-menu.c
diff --git a/tests/test-display-menu.c b/tests/test-display-menu.c
new file mode 100644
index 0000000..c62dbd8
--- /dev/null
+++ b/tests/test-display-menu.c
@@ -0,0 +1,351 @@
+/*-
+ * vi:set et ai sts=2 sw=2 cindent:
+ *
+ * Copyright (c) 2007 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <garcon/garcon.h>
+
+
+
+/* Default icon size */
+#define ICON_SIZE 22
+
+
+
+/* Root menu */
+static GarconMenu *root = NULL;
+
+
+
+static void
+execute_item_command (GtkWidget *widget,
+ GarconMenuItem *item)
+{
+#if 0
+ GError *error = NULL;
+#endif
+ const gchar *command;
+ gboolean terminal;
+ gboolean startup_notification;
+
+ command = garcon_menu_item_get_command (item);
+ terminal = garcon_menu_item_requires_terminal (item);
+ startup_notification = garcon_menu_item_supports_startup_notification (item);
+
+ if (G_UNLIKELY (command == NULL))
+ return;
+
+#if 0
+ if (!xfce_exec_on_screen (gdk_screen_get_default (), command, terminal, startup_notification, &error))
+ {
+ xfce_err (error->message);
+ g_error_free (error);
+ }
+#endif
+}
+
+
+
+static GdkPixbuf*
+create_item_icon (GarconMenuItem *item)
+{
+ GdkPixbuf *icon = NULL;
+ GtkIconTheme *icon_theme;
+ const gchar *icon_name;
+ const gchar *item_name;
+ gchar *basename;
+ gchar *extension;
+ gchar *new_item_name;
+ gchar new_icon_name[1024];
+
+ /* Get current icon theme */
+ icon_theme = gtk_icon_theme_get_default ();
+
+ item_name = garcon_menu_element_get_name (GARCON_MENU_ELEMENT (item));
+ icon_name = garcon_menu_element_get_icon_name (GARCON_MENU_ELEMENT (item));
+
+ if (icon_name == NULL)
+ return NULL;
+
+ /* Check if we have an absolute filename */
+ if (g_path_is_absolute (icon_name) && g_file_test (icon_name, G_FILE_TEST_EXISTS))
+ icon = gdk_pixbuf_new_from_file_at_scale (icon_name, ICON_SIZE, ICON_SIZE, TRUE, NULL);
+ else
+ {
+ /* Try to load the icon name directly using the icon theme */
+ icon = gtk_icon_theme_load_icon (icon_theme, icon_name, ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+
+ /* If that didn't work, try to remove the filename extension if there is one */
+ if (icon == NULL)
+ {
+ /* Get basename (just to be sure) */
+ basename = g_path_get_basename (icon_name);
+
+ /* Determine position of the extension */
+ extension = g_utf8_strrchr (basename, -1, '.');
+
+ /* Make sure we found an extension */
+ if (extension != NULL)
+ {
+ /* Remove extension */
+ g_utf8_strncpy (new_icon_name, basename, g_utf8_strlen (basename, -1) - g_utf8_strlen (extension, -1));
+
+ /* Try to load the pixbuf using the new icon name */
+ icon = gtk_icon_theme_load_icon (icon_theme, new_icon_name, ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+ }
+
+ /* Free basename */
+ g_free (basename);
+
+ /* As a last fallback, we try to load the icon by lowercase item name */
+ if (icon == NULL && item_name != NULL)
+ {
+ new_item_name = g_utf8_strdown (item_name, -1);
+ icon = gtk_icon_theme_load_icon (icon_theme, new_item_name, ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+ g_free (new_item_name);
+ }
+ }
+ }
+
+ /* Scale icon (if needed) */
+ if (icon != NULL)
+ {
+ GdkPixbuf *old_icon = icon;
+ icon = gdk_pixbuf_scale_simple (old_icon, ICON_SIZE, ICON_SIZE, GDK_INTERP_BILINEAR);
+ g_object_unref (old_icon);
+ }
+
+ return icon;
+}
+
+
+
+static void
+create_item_widgets (GarconMenuItem *item,
+ GtkWidget *parent_menu)
+{
+ GtkWidget *gtk_item;
+ GtkWidget *image;
+ GdkPixbuf *icon;
+
+ /* Try to load the icon */
+ icon = create_item_icon (item);
+
+ if (icon != NULL)
+ image = gtk_image_new_from_pixbuf (icon);
+ else
+ image = gtk_image_new_from_icon_name ("applications-other", ICON_SIZE);
+
+ gtk_item = gtk_image_menu_item_new_with_label (garcon_menu_element_get_name (GARCON_MENU_ELEMENT (item)));
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gtk_item), image);
+ gtk_menu_shell_append (GTK_MENU_SHELL (parent_menu), gtk_item);
+ gtk_widget_show (gtk_item);
+
+ /* Execute command if item is clicked */
+ g_signal_connect (gtk_item, "activate", G_CALLBACK (execute_item_command), item);
+}
+
+
+
+static void
+create_menu_widgets (GtkWidget *gtk_menu,
+ GarconMenu *menu)
+{
+ GarconMenuDirectory *directory;
+ GarconMenu *submenu;
+ GtkIconTheme *icon_theme;
+ GtkWidget *gtk_item;
+ GtkWidget *gtk_submenu;
+ GtkWidget *image;
+ GdkPixbuf *icon;
+ GList *iter;
+ GList *items;
+ const gchar *display_name;
+ const gchar *icon_name;
+
+ /* Get current icon theme */
+ icon_theme = gtk_icon_theme_get_default ();
+
+ /* Get submenus and items based on the menu layout */
+ items = garcon_menu_get_elements (menu);
+
+ /* Iterate over menu items */
+ for (iter = items; iter != NULL; iter = g_list_next (iter))
+ {
+ if (GARCON_IS_MENU_ITEM (iter->data))
+ {
+ /* Add menu item to the menu */
+ create_item_widgets (GARCON_MENU_ITEM (iter->data), gtk_menu);
+ }
+ else if (GARCON_IS_MENU_SEPARATOR (iter->data))
+ {
+ /* Add separator to the menu */
+ gtk_item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu), gtk_item);
+ gtk_widget_show (gtk_item);
+ }
+ else if (GARCON_IS_MENU (iter->data))
+ {
+ submenu = GARCON_MENU (iter->data);
+ directory = garcon_menu_get_directory (submenu);
+
+ /* Determine display name */
+ display_name = garcon_menu_element_get_name (GARCON_MENU_ELEMENT (submenu));
+
+ /* Determine icon name */
+ icon_name = garcon_menu_element_get_icon_name (GARCON_MENU_ELEMENT (submenu));
+ if (icon_name == NULL)
+ icon_name = "applications-other";
+
+ /* Load menu icon */
+ icon = gtk_icon_theme_load_icon (icon_theme, icon_name, ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+ if (G_UNLIKELY (icon == NULL))
+ icon = gtk_icon_theme_load_icon (icon_theme, "applications-other", ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+
+ /* Create image widget */
+ image = gtk_image_new_from_pixbuf (icon);
+
+ /* Create menu item */
+ gtk_item = gtk_image_menu_item_new_with_label (display_name);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gtk_item), image);
+ gtk_menu_shell_append (GTK_MENU_SHELL (gtk_menu), gtk_item);
+ gtk_widget_show (gtk_item);
+
+ /* Create submenu */
+ gtk_submenu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (gtk_item), gtk_submenu);
+
+ /* Create widgets for submenu */
+ create_menu_widgets (gtk_submenu, submenu);
+
+ /* Destroy submenu if it is empty */
+ if (G_UNLIKELY (gtk_container_get_children (GTK_CONTAINER (gtk_submenu)) == NULL))
+ gtk_widget_destroy (gtk_item);
+ }
+ }
+
+ /* Free menu item list */
+ g_list_free (items);
+}
+
+
+
+static void
+show_menu (GtkButton *button,
+ GtkWidget *menu)
+{
+ /* Create menu widgets if not already done */
+ if (g_list_length (gtk_container_get_children (GTK_CONTAINER (menu))) == 0)
+ create_menu_widgets (menu, root);
+
+ /* Display the menu */
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
+}
+
+
+
+static void
+main_window_destroy (GtkWidget *window)
+{
+ gtk_main_quit ();
+}
+
+
+
+static void
+create_main_window (void)
+{
+ GtkWidget *window;
+ GtkWidget *button;
+ GtkWidget *menu;
+
+ /* Create main window */
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "GarconMenu: Display Menu Test");
+ gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+ gtk_widget_show (window);
+
+ /* Exit main loop when when the window is closed */
+ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (main_window_destroy), NULL);
+
+ /* Create button */
+ button = gtk_button_new_with_mnemonic ("_Show menu");
+ gtk_container_add (GTK_CONTAINER (window), button);
+ gtk_widget_show (button);
+
+ /* Create GTK+ root menu */
+ menu = gtk_menu_new ();
+
+ /* Display root menu when the button is clicked */
+ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (show_menu), menu);
+}
+
+
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ gint exit_code = EXIT_SUCCESS;
+ GError *error = NULL;
+
+ /* Initialize the menu library */
+ garcon_set_environment ("XFCE");
+
+ /* Initialize GTK+ */
+ gtk_init (&argc, &argv);
+
+ /* Try to load the menu */
+ if (G_UNLIKELY (g_strv_length (argv) > 1))
+ root = garcon_menu_new_for_path (argv[1]);
+ else
+ root = garcon_menu_new_applications ();
+
+ /* Check if the menu was loaded */
+ if (root != NULL
+ && garcon_menu_load (root, NULL, &error))
+ {
+ /* Create main window */
+ create_main_window ();
+
+ /* Enter main loop */
+ gtk_main ();
+
+ /* Destroy the root menu */
+ g_object_unref (root);
+ }
+ else
+ {
+ g_error ("Failed to load the menu: %s", error != NULL ? error->message : "No error");
+ if (error != NULL)
+ g_error_free (error);
+ exit_code = EXIT_FAILURE;
+ }
+
+ return exit_code;
+}
More information about the Xfce4-commits
mailing list