updated copyright in source files
[geeqie.git] / src / ui_menu.c
1 /*
2  * (SLIK) SimpLIstic sKin functions
3  * (C) 2004 John Ellis
4  * Copyright (C) 2008 The Geeqie Team
5  *
6  * Author: John Ellis
7  *
8  * This software is released under the GNU General Public License (GNU GPL).
9  * Please read the included file COPYING for more information.
10  * This software comes with no warranty of any kind, use at your own risk!
11  */
12
13 #ifdef HAVE_CONFIG_H
14 #  include "config.h"
15 #endif
16 #include "intl.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <gtk/gtk.h>
23
24 #include "ui_menu.h"
25
26
27 /*
28  *-----------------------------------------------------------------------------
29  * menu items
30  *-----------------------------------------------------------------------------
31  */
32
33 static void menu_item_finish(GtkWidget *menu, GtkWidget *item, GCallback func, gpointer data)
34 {
35         if (func) g_signal_connect(G_OBJECT(item), "activate", func, data);
36         gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
37         gtk_widget_show(item);
38 }
39
40 GtkWidget *menu_item_add(GtkWidget *menu, const gchar *label,
41                          GCallback func, gpointer data)
42 {
43         GtkWidget *item;
44
45         item = gtk_menu_item_new_with_mnemonic(label);
46         menu_item_finish(menu, item, func, data);
47
48         return item;
49 }
50
51 GtkWidget *menu_item_add_stock(GtkWidget *menu, const gchar *label, const gchar *stock_id,
52                                GCallback func, gpointer data)
53 {
54         GtkWidget *item;
55         GtkWidget *image;
56
57         item = gtk_image_menu_item_new_with_mnemonic(label);
58         image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
59         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
60         gtk_widget_show(image);
61         menu_item_finish(menu, item, func, data);
62
63         return item;
64 }
65
66 GtkWidget *menu_item_add_sensitive(GtkWidget *menu, const gchar *label, gint sensitive,
67                                    GCallback func, gpointer data)
68 {
69         GtkWidget *item;
70
71         item = menu_item_add(menu, label, func, data);
72         gtk_widget_set_sensitive(item, sensitive);
73
74         return item;
75 }
76
77 GtkWidget *menu_item_add_stock_sensitive(GtkWidget *menu, const gchar *label, const gchar *stock_id, gint sensitive,
78                                          GCallback func, gpointer data)
79 {
80         GtkWidget *item;
81
82         item = menu_item_add_stock(menu, label, stock_id, func, data);
83         gtk_widget_set_sensitive(item, sensitive);
84
85         return item;
86 }
87
88 GtkWidget *menu_item_add_check(GtkWidget *menu, const gchar *label, gint active,
89                                GCallback func, gpointer data)
90 {
91         GtkWidget *item;
92
93         item = gtk_check_menu_item_new_with_mnemonic(label);
94         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), active);
95         menu_item_finish(menu, item, func, data);
96
97         return item;
98 }
99
100 GtkWidget *menu_item_add_radio(GtkWidget *menu, GtkWidget *parent,
101                                const gchar *label, gint active,
102                                GCallback func, gpointer data)
103 {
104         GtkWidget *item;
105         GSList *group = NULL;
106
107         if (parent) group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(parent));
108
109         item = gtk_radio_menu_item_new_with_mnemonic(group, label);
110         if (active) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), active);
111         menu_item_finish(menu, item, func, data);
112
113         return item;
114 }
115
116 void menu_item_add_divider(GtkWidget *menu)
117 {
118         GtkWidget *item = gtk_menu_item_new();
119         gtk_widget_set_sensitive(item, FALSE);
120         gtk_menu_shell_append(GTK_MENU_SHELL(menu),item);
121         gtk_widget_show(item);
122 }
123
124 GtkWidget *menu_item_add_simple(GtkWidget *menu, const gchar *label,
125                                 GCallback func, gpointer data)
126 {
127         GtkWidget *item = gtk_menu_item_new_with_label(label);
128         menu_item_finish(menu, item, func, data);
129
130         return item;
131 }
132
133 /*
134  *-----------------------------------------------------------------------------
135  * popup menus
136  *-----------------------------------------------------------------------------
137  */
138
139 static void popup_menu_short_lived_cb(GtkWidget *widget, gpointer data)
140 {
141         /* destroy the menu */
142         g_object_unref(G_OBJECT(data));
143 }
144
145 GtkWidget *popup_menu_short_lived(void)
146 {
147         GtkWidget *menu;
148
149         menu = gtk_menu_new();
150
151         /* take ownership of menu */
152 #ifdef GTK_OBJECT_FLOATING
153         /* GTK+ < 2.10 */
154         g_object_ref(G_OBJECT(menu));
155         gtk_object_sink(GTK_OBJECT(menu));
156 #else
157         /* GTK+ >= 2.10 */
158         g_object_ref_sink(G_OBJECT(menu));
159 #endif
160
161         g_signal_connect(G_OBJECT(menu), "selection_done",
162                          G_CALLBACK(popup_menu_short_lived_cb), menu);
163         return menu;
164 }
165
166 gint popup_menu_position_clamp(GtkMenu *menu, gint *x, gint *y, gint height)
167 {
168         gint adjusted = FALSE;
169         gint w, h;
170         gint xw, xh;
171
172         w = GTK_WIDGET(menu)->requisition.width;
173         h = GTK_WIDGET(menu)->requisition.height;
174         xw = gdk_screen_width();
175         xh = gdk_screen_height();
176
177         if (*x + w > xw)
178                 {
179                 *x = xw - w;
180                 adjusted = TRUE;
181                 }
182         if (*y + h > xh)
183                 {
184                 if (height)
185                         {
186                         *y = MAX(0, *y - h - height);
187                         }
188                 else
189                         {
190                         *y = xh - h;
191                         }
192                 adjusted = TRUE;
193                 };
194
195         if (*x < 0)
196                 {
197                 *x = 0;
198                 adjusted = TRUE;
199                 }
200         if (*y < 0)
201                 {
202                 *y = 0;
203                 adjusted = TRUE;
204                 }
205
206         return adjusted;
207 }