put the image popup menu into a dummy menubar to work around the silly

2004-05-17  Michael Natterer  <mitch@gimp.org>

	* menus/menus.xsl: put the image popup menu into a dummy menubar
	to work around the silly GtkUIManager restriction that popup menus
	can't have tearoff items.

	* app/menus/menus.c
	* app/menus/image-menu.c
	* app/display/gimpdisplayshell-callbacks.c
	* app/gui/gui-vtable.c
	* app/menus/plug-in-menus.c: changed accordingly.

	* app/gui/gui.c (gui_restore_after_callback): connect to
	"notify::tearoff-menus" of GimpGuiConfig and reconfigure the
	global image UI manager accordingly.

	* app/config/gimpguiconfig.c: removed GIMP_PARAM_RESTART from the
	"tearoff-menus" property because GtkUIManager can change this on
	the fly.

	* app/display/gimpdisplayshell.[ch]: added the menubar to the
	GimpDisplayShell struct. Some cleanup in gimp_display_shell_new().

	* app/display/gimpdisplayshell-appearance.c
	(gimp_display_shell_set_show_menubar): use shell->menubar instead
	of asking the UI manager.

	* app/widgets/gimpuimanager.[ch]: changed gimp_ui_manager_ui_get()
	to transparently load the XML files even if a sub-widget was
	requested. Reordered parameters of gimp_ui_manager_ui_popup().
	Lots of internal cleanups.

	* app/widgets/gimpdockable.c
	* app/widgets/gimptooloptionseditor.c: simplified accordingly.

	* app/widgets/gimpeditor.[ch]: added new function
	gimp_editor_popup_menu() which takes a GimpMenuPositionFunc and
	updates/shows the editor's menu.

	* app/widgets/gimpcolormapeditor.c
	* app/widgets/gimpcomponenteditor.c
	* app/widgets/gimpcontainereditor.c
	* app/widgets/gimpcontainergridview.c
	* app/widgets/gimpcontainertreeview.c
	* app/widgets/gimperrorconsole.c
	* app/widgets/gimpgradienteditor.c
	* app/widgets/gimpitemtreeview.c
	* app/widgets/gimppaletteeditor.c: use gimp_editor_popup_menu().

	* app/widgets/gimptoolbox.c: moved all code from
	gimp_toolbox_new() to GObject::constructor().
This commit is contained in:
Michael Natterer
2004-05-17 13:38:03 +00:00
committed by Michael Natterer
parent bd95efd50e
commit cf3533ba9c
28 changed files with 513 additions and 449 deletions

View File

@ -54,35 +54,50 @@ enum
};
static void gimp_ui_manager_init (GimpUIManager *manager);
static void gimp_ui_manager_class_init (GimpUIManagerClass *klass);
static void gimp_ui_manager_init (GimpUIManager *manager);
static void gimp_ui_manager_class_init (GimpUIManagerClass *klass);
static GObject * gimp_ui_manager_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_ui_manager_dispose (GObject *object);
static void gimp_ui_manager_finalize (GObject *object);
static void gimp_ui_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_connect_proxy (GtkUIManager *manager,
GtkAction *action,
GtkWidget *proxy);
static void gimp_ui_manager_real_update (GimpUIManager *manager,
gpointer update_data);
/* help support */
static void gimp_ui_manager_item_realize (GtkWidget *widget,
GimpUIManager *manager);
static gboolean gimp_ui_manager_item_key_press (GtkWidget *widget,
GdkEventKey *kevent,
GimpUIManager *manager);
static GObject * gimp_ui_manager_constructor (GType type,
guint n_params,
GObjectConstructParam *params);
static void gimp_ui_manager_dispose (GObject *object);
static void gimp_ui_manager_finalize (GObject *object);
static void gimp_ui_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_connect_proxy (GtkUIManager *manager,
GtkAction *action,
GtkWidget *proxy);
static void gimp_ui_manager_real_update (GimpUIManager *manager,
gpointer update_data);
static GimpUIManagerUIEntry *
gimp_ui_manager_entry_get (GimpUIManager *manager,
const gchar *ui_path);
static gboolean gimp_ui_manager_entry_load (GimpUIManager *manager,
GimpUIManagerUIEntry *entry,
GError **error);
static void gimp_ui_manager_menu_position (GtkMenu *menu,
gint *x,
gint *y,
gpointer data);
static void gimp_ui_manager_menu_pos (GtkMenu *menu,
gint *x,
gint *y,
gboolean *push_in,
gpointer data);
static void
gimp_ui_manager_delete_popdown_data (GtkObject *object,
GimpUIManager *manager);
static void gimp_ui_manager_item_realize (GtkWidget *widget,
GimpUIManager *manager);
static gboolean gimp_ui_manager_item_key_press (GtkWidget *widget,
GdkEventKey *kevent,
GimpUIManager *manager);
static guint manager_signals[LAST_SIGNAL] = { 0 };
@ -430,6 +445,7 @@ gimp_ui_manager_ui_register (GimpUIManager *manager,
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
g_return_if_fail (basename != NULL);
g_return_if_fail (gimp_ui_manager_entry_get (manager, ui_path) == NULL);
entry = g_new0 (GimpUIManagerUIEntry, 1);
@ -446,70 +462,204 @@ GtkWidget *
gimp_ui_manager_ui_get (GimpUIManager *manager,
const gchar *ui_path)
{
GList *list;
GimpUIManagerUIEntry *entry;
g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL);
g_return_val_if_fail (ui_path != NULL, NULL);
entry = gimp_ui_manager_entry_get (manager, ui_path);
if (! entry)
{
g_warning ("%s: no entry registered for \"%s\"", G_STRFUNC, ui_path);
return NULL;
}
if (! entry->merge_id)
{
GError *error = NULL;
if (! gimp_ui_manager_entry_load (manager, entry, &error))
{
g_message (error->message);
g_clear_error (&error);
return NULL;
}
}
if (! entry->widget)
{
entry->widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager),
entry->ui_path);
if (entry->widget)
{
g_object_ref (entry->widget);
/* take ownership of popup menus */
if (GTK_IS_MENU (entry->widget))
gtk_object_sink (GTK_OBJECT (entry->widget));
if (entry->setup_func)
entry->setup_func (manager, entry->ui_path);
}
else
{
g_warning ("%s: \"%s\" does not contain registered toplevel "
"widget \"%s\"",
G_STRFUNC, entry->basename, entry->ui_path);
return NULL;
}
}
if (! strcmp (entry->ui_path, ui_path))
return entry->widget;
return gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), ui_path);
}
typedef struct
{
guint x;
guint y;
} MenuPos;
void
gimp_ui_manager_ui_popup (GimpUIManager *manager,
const gchar *ui_path,
GtkWidget *parent,
GimpMenuPositionFunc position_func,
gpointer position_data,
GtkDestroyNotify popdown_func,
gpointer popdown_data)
{
GtkWidget *widget;
GdkEvent *current_event;
gint x, y;
guint button;
guint32 activate_time;
MenuPos *menu_pos;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent));
widget = gimp_ui_manager_ui_get (manager, ui_path);
if (GTK_IS_MENU_ITEM (widget))
widget = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
g_return_if_fail (GTK_IS_MENU (widget));
if (! position_func)
{
position_func = gimp_ui_manager_menu_position;
position_data = parent;
}
(* position_func) (GTK_MENU (widget), &x, &y, position_data);
current_event = gtk_get_current_event ();
if (current_event && current_event->type == GDK_BUTTON_PRESS)
{
GdkEventButton *bevent = (GdkEventButton *) current_event;
button = bevent->button;
activate_time = bevent->time;
}
else
{
button = 0;
activate_time = 0;
}
menu_pos = g_object_get_data (G_OBJECT (widget), "menu-pos");
if (! menu_pos)
{
menu_pos = g_new0 (MenuPos, 1);
g_object_set_data_full (G_OBJECT (widget), "menu-pos", menu_pos, g_free);
}
menu_pos->x = x;
menu_pos->y = y;
if (popdown_func && popdown_data)
{
g_object_set_data_full (G_OBJECT (manager), "popdown-data",
popdown_data, popdown_func);
g_signal_connect (widget, "selection-done",
G_CALLBACK (gimp_ui_manager_delete_popdown_data),
manager);
}
gtk_menu_popup (GTK_MENU (widget),
NULL, NULL,
gimp_ui_manager_menu_pos, menu_pos,
button, activate_time);
}
/* private functions */
static GimpUIManagerUIEntry *
gimp_ui_manager_entry_get (GimpUIManager *manager,
const gchar *ui_path)
{
GList *list;
gchar *path;
path = g_strdup (ui_path);
if (strlen (path) > 1)
{
gchar *p = strchr (path + 1, '/');
if (p)
*p = '\0';
}
for (list = manager->registered_uis; list; list = g_list_next (list))
{
GimpUIManagerUIEntry *entry = list->data;
if (! strcmp (entry->ui_path, ui_path))
if (! strcmp (entry->ui_path, path))
{
if (! entry->merge_id)
{
gchar *filename;
GError *error = NULL;
g_free (path);
filename = g_build_filename (gimp_data_directory (), "menus",
entry->basename, NULL);
g_print ("loading menu: %s for %s\n", filename,
entry->ui_path);
entry->merge_id =
gtk_ui_manager_add_ui_from_file (GTK_UI_MANAGER (manager),
filename, &error);
g_free (filename);
if (! entry->merge_id)
{
g_message (error->message);
g_clear_error (&error);
return NULL;
}
}
if (! entry->widget)
{
gtk_ui_manager_ensure_update (GTK_UI_MANAGER (manager));
entry->widget =
gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager),
entry->ui_path);
if (entry->widget)
{
g_object_ref (entry->widget);
if (entry->setup_func)
entry->setup_func (manager, entry->ui_path);
}
}
return entry->widget;
return entry;
}
}
g_warning ("%s: no entry registered for \"%s\"",
G_STRFUNC, ui_path);
g_free (path);
return NULL;
}
static gboolean
gimp_ui_manager_entry_load (GimpUIManager *manager,
GimpUIManagerUIEntry *entry,
GError **error)
{
gchar *filename;
filename = g_build_filename (gimp_data_directory (), "menus",
entry->basename, NULL);
g_print ("loading menu: %s for %s\n", filename, entry->ui_path);
entry->merge_id = gtk_ui_manager_add_ui_from_file (GTK_UI_MANAGER (manager),
filename, error);
g_free (filename);
if (! entry->merge_id)
return FALSE;
return TRUE;
}
static void
gimp_ui_manager_menu_position (GtkMenu *menu,
gint *x,
@ -562,12 +712,6 @@ gimp_ui_manager_menu_position (GtkMenu *menu,
if (*y < rect.y) *y = rect.y;
}
typedef struct
{
guint x;
guint y;
} MenuPos;
static void
gimp_ui_manager_menu_pos (GtkMenu *menu,
gint *x,
@ -582,91 +726,15 @@ gimp_ui_manager_menu_pos (GtkMenu *menu,
}
static void
gimp_ui_manager_delete_popup_data (GtkObject *object,
GimpUIManager *manager)
gimp_ui_manager_delete_popdown_data (GtkObject *object,
GimpUIManager *manager)
{
g_signal_handlers_disconnect_by_func (object,
gimp_ui_manager_delete_popup_data,
gimp_ui_manager_delete_popdown_data,
manager);
g_object_set_data (G_OBJECT (manager), "popup-data", NULL);
g_object_set_data (G_OBJECT (manager), "popdown-data", NULL);
}
void
gimp_ui_manager_ui_popup (GimpUIManager *manager,
const gchar *ui_path,
gpointer popup_data,
GtkWidget *parent,
GimpMenuPositionFunc position_func,
gpointer position_data,
GtkDestroyNotify popdown_func)
{
GtkWidget *widget;
GdkEvent *current_event;
gint x, y;
guint button;
guint32 activate_time;
MenuPos *menu_pos;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
g_return_if_fail (ui_path != NULL);
g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent));
widget = gimp_ui_manager_ui_get (manager, ui_path);
g_return_if_fail (GTK_IS_MENU (widget));
if (! position_func)
{
position_func = gimp_ui_manager_menu_position;
position_data = parent;
}
(* position_func) (GTK_MENU (widget), &x, &y, position_data);
current_event = gtk_get_current_event ();
if (current_event && current_event->type == GDK_BUTTON_PRESS)
{
GdkEventButton *bevent = (GdkEventButton *) current_event;
button = bevent->button;
activate_time = bevent->time;
}
else
{
button = 0;
activate_time = 0;
}
menu_pos = g_object_get_data (G_OBJECT (widget), "menu-pos");
if (! menu_pos)
{
menu_pos = g_new0 (MenuPos, 1);
g_object_set_data_full (G_OBJECT (widget), "menu-pos", menu_pos, g_free);
}
menu_pos->x = x;
menu_pos->y = y;
if (popup_data != NULL)
{
g_object_set_data_full (G_OBJECT (manager), "popup-data",
popup_data, popdown_func);
g_signal_connect (widget, "selection-done",
G_CALLBACK (gimp_ui_manager_delete_popup_data),
manager);
}
gtk_menu_popup (GTK_MENU (widget),
NULL, NULL,
gimp_ui_manager_menu_pos, menu_pos,
button, activate_time);
}
/* private functions */
static void
gimp_ui_manager_item_realize (GtkWidget *widget,
GimpUIManager *manager)