]> git.sur5r.net Git - glabels/blob - src/field-button-menu.c
Imported Upstream version 3.0.0
[glabels] / src / field-button-menu.c
1 /*
2  *  field-button-menu.c
3  *  Copyright (C) 2008-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels 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
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "field-button-menu.h"
24
25 #include <string.h>
26 #include <gtk/gtk.h>
27
28 #include "marshal.h"
29
30 #include "debug.h"
31
32 #define MAX_MENU_ROWS 25
33
34 /*===========================================*/
35 /* Private types                             */
36 /*===========================================*/
37
38
39 struct _glFieldButtonMenuPrivate {
40
41         GList *menu_items;
42 };
43
44 enum {
45         KEY_SELECTED,
46         LAST_SIGNAL
47 };
48
49 typedef void (*glFieldButtonMenuSignal) (GObject * object, gpointer data);
50
51
52 /*===========================================*/
53 /* Private globals                           */
54 /*===========================================*/
55
56 static gint signals[LAST_SIGNAL] = { 0 };
57
58
59 /*===========================================*/
60 /* Local function prototypes                 */
61 /*===========================================*/
62
63 static void gl_field_button_menu_finalize      (GObject              *object);
64
65
66 /****************************************************************************/
67 /* Boilerplate Object stuff.                                                */
68 /****************************************************************************/
69 G_DEFINE_TYPE (glFieldButtonMenu, gl_field_button_menu, GTK_TYPE_MENU)
70
71
72 static void
73 gl_field_button_menu_class_init (glFieldButtonMenuClass *class)
74 {
75         GObjectClass *object_class = G_OBJECT_CLASS (class);
76
77         gl_debug (DEBUG_FIELD_BUTTON, "START");
78
79         gl_field_button_menu_parent_class = g_type_class_peek_parent (class);
80
81         object_class->finalize = gl_field_button_menu_finalize;
82
83         signals[KEY_SELECTED] =
84             g_signal_new ("key_selected",
85                           G_OBJECT_CLASS_TYPE(object_class),
86                           G_SIGNAL_RUN_LAST,
87                           G_STRUCT_OFFSET (glFieldButtonMenuClass, key_selected),
88                           NULL, NULL,
89                           gl_marshal_VOID__STRING,
90                           G_TYPE_NONE, 1, G_TYPE_STRING);
91
92         gl_debug (DEBUG_FIELD_BUTTON, "END");
93 }
94
95
96 static void
97 gl_field_button_menu_init (glFieldButtonMenu *this)
98 {
99         gl_debug (DEBUG_FIELD_BUTTON, "START");
100
101         this->priv = g_new0 (glFieldButtonMenuPrivate, 1);
102
103         gl_debug (DEBUG_FIELD_BUTTON, "END");
104 }
105
106
107 static void
108 gl_field_button_menu_finalize (GObject *object)
109 {
110         glFieldButtonMenu *this = GL_FIELD_BUTTON_MENU (object);
111         GList           *p;
112         GtkWidget       *menu_item;
113         gchar           *key;
114
115         gl_debug (DEBUG_FIELD_BUTTON, "START");
116
117         g_return_if_fail (object != NULL);
118         g_return_if_fail (GL_IS_FIELD_BUTTON_MENU (object));
119
120         for ( p = this->priv->menu_items; p != NULL; p = p->next )
121         {
122                 menu_item = GTK_WIDGET (p->data);
123                 key = g_object_get_data (G_OBJECT (menu_item), "key");
124                 g_free (key);
125         }
126         g_list_free (this->priv->menu_items);
127         g_free (this->priv);
128
129         G_OBJECT_CLASS (gl_field_button_menu_parent_class)->finalize (object);
130
131         gl_debug (DEBUG_FIELD_BUTTON, "END");
132 }
133
134
135 GtkWidget *
136 gl_field_button_menu_new (void)
137 {
138         glFieldButtonMenu *this;
139
140         gl_debug (DEBUG_FIELD_BUTTON, "START");
141
142         this = g_object_new (gl_field_button_menu_get_type (), NULL);
143
144         gl_debug (DEBUG_FIELD_BUTTON, "END");
145
146         return GTK_WIDGET (this);
147 }
148
149
150 /*--------------------------------------------------------------------------*/
151 /* PRIVATE.  Menu item activation callback.                                 */
152 /*--------------------------------------------------------------------------*/
153 static void
154 activate_cb (GtkMenuItem       *menu_item,
155              glFieldButtonMenu *this)
156 {
157         gchar *key;
158
159         gl_debug (DEBUG_FIELD_BUTTON, "START");
160
161         key = g_object_get_data (G_OBJECT (menu_item), "key");
162         gl_debug (DEBUG_FIELD_BUTTON, "Key activated: \"%s\"\n", key );
163
164         g_signal_emit (G_OBJECT (this), signals[KEY_SELECTED], 0, key);
165
166         gl_debug (DEBUG_FIELD_BUTTON, "END");
167 }
168
169
170 /****************************************************************************/
171 /* set key names.                                                           */
172 /****************************************************************************/
173 void
174 gl_field_button_menu_set_keys (glFieldButtonMenu *this,
175                                GList             *key_list)
176 {
177         GList     *p;
178         GtkWidget *menu_item;
179         gchar     *key;
180         gint       i, i_row, i_col;
181
182         gl_debug (DEBUG_FIELD_BUTTON, "START");
183
184         /*
185          * Remove all old menu items.
186          */
187         for ( p = this->priv->menu_items; p != NULL; p = p->next )
188         {
189                 menu_item = GTK_WIDGET (p->data);
190                 key = g_object_get_data (G_OBJECT (menu_item), "key");
191                 g_free (key);
192                 gtk_container_remove (GTK_CONTAINER (this), menu_item);
193         }
194         g_list_free (this->priv->menu_items);
195         this->priv->menu_items = NULL;
196         gtk_widget_unrealize (GTK_WIDGET (this)); /* Start over with new Gdk resources. */
197
198         /*
199          * Add new menu items.
200          */
201         for ( p = key_list, i = 0; p != NULL; p = p->next, i++ )
202         {
203                 if ( p->data && strlen (p->data) )
204                 {
205
206                         gl_debug (DEBUG_FIELD_BUTTON, "Adding key: %s", p->data);
207
208                         menu_item = gtk_menu_item_new_with_label (p->data);
209                         gtk_widget_show (menu_item);
210                         g_object_set_data (G_OBJECT (menu_item), "key", g_strdup (p->data));
211                         g_signal_connect (G_OBJECT (menu_item), "activate", 
212                                           G_CALLBACK (activate_cb), this);
213                         this->priv->menu_items =
214                                 g_list_append (this->priv->menu_items, menu_item);
215
216                         i_row = i % MAX_MENU_ROWS;
217                         i_col = i / MAX_MENU_ROWS;
218                         gtk_menu_attach (GTK_MENU (this), menu_item, i_col, i_col+1, i_row, i_row+1);
219                 }
220         }
221
222         gl_debug (DEBUG_FIELD_BUTTON, "END");
223 }
224
225
226
227 /*
228  * Local Variables:       -- emacs
229  * mode: C                -- emacs
230  * c-basic-offset: 8      -- emacs
231  * tab-width: 8           -- emacs
232  * indent-tabs-mode: nil  -- emacs
233  * End:                   -- emacs
234  */