Updated Spanish translation
[anjuta-git-plugin.git] / libegg / egg-submenu-action.c
blobe4587f92c23094730e7c0f9c5b958d1b22e4f754
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 /* egg-submenu-action widget
5 * Copyright (C) Naba Kumar <naba@gnome.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
22 #include <stdio.h>
23 #include <gtk/gtkwidget.h>
24 #include <gtk/gtktoggletoolbutton.h>
25 #include "egg-submenu-action.h"
27 #ifndef _
28 # define _(s) (s)
29 #endif
31 struct _EggSubmenuActionPriv
33 EggSubmenuFactory factory;
34 gpointer user_data;
37 static void egg_submenu_action_init (EggSubmenuAction *action);
38 static void egg_submenu_action_class_init (EggSubmenuActionClass *kclass);
40 static GtkWidget *create_tool_item (GtkAction *action);
41 static GtkWidget *create_menu_item (GtkAction *action);
42 static void connect_proxy (GtkAction *action,
43 GtkWidget *proxy);
44 static void disconnect_proxy (GtkAction *action,
45 GtkWidget *proxy);
46 static void egg_submenu_action_finalize (GObject *object);
48 static GObjectClass *parent_class = NULL;
50 GType
51 egg_submenu_action_get_type (void)
53 static GtkType type = 0;
55 if (!type)
57 static const GTypeInfo type_info =
59 sizeof (EggSubmenuActionClass),
60 (GBaseInitFunc) NULL,
61 (GBaseFinalizeFunc) NULL,
62 (GClassInitFunc) egg_submenu_action_class_init,
63 (GClassFinalizeFunc) NULL,
64 NULL,
66 sizeof (EggSubmenuAction),
67 0, /* n_preallocs */
68 (GInstanceInitFunc) egg_submenu_action_init,
71 type = g_type_register_static (GTK_TYPE_ACTION,
72 "EggSubmenuAction",
73 &type_info, 0);
75 return type;
78 static void
79 egg_submenu_action_class_init (EggSubmenuActionClass *kclass)
81 GtkActionClass *action_class;
82 GObjectClass *object_class;
84 parent_class = g_type_class_peek_parent (kclass);
85 action_class = GTK_ACTION_CLASS (kclass);
86 object_class = G_OBJECT_CLASS (kclass);
88 object_class->finalize = egg_submenu_action_finalize;
90 action_class->connect_proxy = connect_proxy;
91 action_class->disconnect_proxy = disconnect_proxy;
92 action_class->menu_item_type = GTK_TYPE_MENU_ITEM;
93 action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
94 action_class->create_tool_item = create_tool_item;
95 action_class->create_menu_item = create_menu_item;
98 static void
99 egg_submenu_action_init (EggSubmenuAction *action)
101 action->priv = g_new0 (EggSubmenuActionPriv, 1);
102 action->priv->factory = NULL;
103 action->priv->user_data = NULL;
106 static void
107 egg_submenu_action_finalize (GObject *object)
109 g_free (EGG_SUBMENU_ACTION (object)->priv);
110 if (parent_class->finalize)
111 parent_class->finalize (object);
114 static GtkWidget*
115 create_submenu_submenu (EggSubmenuAction *action)
117 GtkWidget *submenu;
119 if (action->priv->factory)
121 submenu = (*action->priv->factory)(action->priv->user_data);
123 else
125 submenu = gtk_menu_new ();
126 gtk_widget_show (submenu);
128 gtk_widget_show (submenu);
129 return submenu;
132 static void
133 on_reposition_menu (GtkMenu *menu, gint *x, gint *y, gboolean *push_in,
134 gpointer data)
136 gint x1, y1, w, h, d;
137 GtkWidget *button = GTK_WIDGET (data);
138 gdk_window_get_origin (button->window, x, y);
139 gdk_window_get_geometry (button->window, &x1, &y1, &w, &h, &d);
140 *y += button->allocation.height;
141 if (GTK_WIDGET_NO_WINDOW (button))
143 *x += button->allocation.x;
144 *y += button->allocation.y;
148 static void
149 on_selection_done_menu (GtkMenu *menu, GtkWidget *button)
151 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
154 static void
155 on_button_pressed (GtkToggleToolButton *button, EggSubmenuAction *action)
157 GtkWidget *submenu;
159 /* g_message ("Submenu toolitem toggled"); */
160 submenu = g_object_get_data (G_OBJECT (button), "submenu");
161 if (!submenu)
163 submenu = create_submenu_submenu (action);
164 g_object_set_data_full (G_OBJECT (button), "submenu", submenu,
165 (GDestroyNotify)gtk_widget_destroy);
166 g_object_set_data (G_OBJECT (submenu), "thebutton", button);
167 g_signal_connect (G_OBJECT (submenu), "selection-done",
168 G_CALLBACK (on_selection_done_menu), button);
169 gtk_widget_show (submenu);
171 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
173 gtk_menu_popup (GTK_MENU (submenu), NULL, NULL, on_reposition_menu,
174 button, 0, gtk_get_current_event_time ());
175 gtk_menu_reposition (GTK_MENU (submenu));
177 else
179 gtk_menu_popdown (GTK_MENU (submenu));
183 static GtkWidget *
184 create_tool_item (GtkAction *action)
186 GtkWidget *arrow;
187 GtkWidget *button;
188 GtkToolItem *item;
190 g_return_val_if_fail (EGG_IS_SUBMENU_ACTION (action), NULL);
191 /* g_message ("Creating submenu toolitem"); */
193 item = gtk_tool_item_new ();
194 gtk_widget_show(GTK_WIDGET (item));
195 button = gtk_toggle_button_new ();
196 gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
197 gtk_container_add (GTK_CONTAINER (item), button);
198 gtk_widget_show(GTK_WIDGET (button));
199 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
200 gtk_widget_show (arrow);
201 gtk_container_add (GTK_CONTAINER (button), arrow);
202 return GTK_WIDGET (item);
205 static GtkWidget *
206 create_menu_item (GtkAction *action)
208 GtkWidget *menuitem, *submenu;
209 menuitem = (* GTK_ACTION_CLASS (parent_class)->create_menu_item) (action);
210 submenu = create_submenu_submenu (EGG_SUBMENU_ACTION (action));
211 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
212 return menuitem;
215 static void
216 connect_proxy (GtkAction *action, GtkWidget *proxy)
218 EggSubmenuAction *submenu_action;
220 submenu_action = EGG_SUBMENU_ACTION (action);
222 /* do this before hand, so that we don't call the "activate" handler */
223 if (GTK_IS_TOOL_ITEM (proxy))
225 g_signal_connect (G_OBJECT (gtk_bin_get_child(GTK_BIN (proxy))),
226 "toggled",
227 G_CALLBACK (on_button_pressed), action);
229 (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
232 static void
233 disconnect_proxy (GtkAction *action, GtkWidget *proxy)
235 EggSubmenuAction *submenu_action;
237 submenu_action = EGG_SUBMENU_ACTION (action);
239 /* do this before hand, so that we don't call the "activate" handler */
240 if (GTK_IS_TOOL_ITEM (proxy))
242 g_signal_handlers_disconnect_by_func (G_OBJECT (gtk_bin_get_child(GTK_BIN (proxy))),
243 G_CALLBACK (on_button_pressed),
244 action);
246 (* GTK_ACTION_CLASS (parent_class)->connect_proxy) (action, proxy);
249 void
250 egg_submenu_action_set_menu_factory (EggSubmenuAction *action,
251 EggSubmenuFactory factory,
252 gpointer user_data)
254 g_return_if_fail (EGG_IS_SUBMENU_ACTION (action));
256 action->priv->factory = factory;
257 action->priv->user_data = user_data;