~jroose/cairo-dock-plug-ins/Messaging-Menu-alaric-devel

« back to all changes in this revision

Viewing changes to Messaging-Menu/src/applet-menu.c

  • Committer: jroose at gmail
  • Date: 2010-11-18 14:43:40 UTC
  • Revision ID: jroose@gmail.com-20101118144340-qvrs0rmanr5lr1mj
Messaging-Menu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* based on indicator-messages.c written by :
 
6
*  Ted Gould <ted@canonical.com>
 
7
*  Cody Russell <cody.russell@canonical.com>
 
8
* E-mail    : see the 'copyright' file.
 
9
*
 
10
* This program is free software; you can redistribute it and/or
 
11
* modify it under the terms of the GNU General Public License
 
12
* as published by the Free Software Foundation; either version 3
 
13
* of the License, or (at your option) any later version.
 
14
*
 
15
* This program is distributed in the hope that it will be useful,
 
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
* GNU General Public License for more details.
 
19
* You should have received a copy of the GNU General Public License
 
20
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*/
 
22
 
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <stdio.h>
 
26
 
 
27
#include <libdbusmenu-gtk/menuitem.h>
 
28
#include <libdbusmenu-gtk/menu.h>
 
29
 
 
30
#include "applet-struct.h"
 
31
#include "dbus-data.h"
 
32
#include "applet-menu.h"
 
33
 
 
34
  //////////////////////
 
35
 // APPLICATION ITEM //
 
36
//////////////////////
 
37
 
 
38
/* Sets the icon when it changes. 
 
39
static void
 
40
application_icon_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, gpointer user_data)
 
41
{
 
42
        g_print("Me-Messaging: (app_icon_change_cb)\n");
 
43
        if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_ICON)) {
 
44
                /* Set the main icon 
 
45
                if (GTK_IS_IMAGE(user_data)) {
 
46
                        gtk_image_set_from_icon_name(GTK_IMAGE(user_data), g_value_get_string(value), GTK_ICON_SIZE_MENU);
 
47
                }
 
48
        }
 
49
 
 
50
        return;
 
51
}
 
52
 
 
53
/* Sets the label when it changes. 
 
54
static void
 
55
application_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, gpointer user_data)
 
56
{
 
57
        g_print("Me-Messaging: (app_prop_change_cb)\n");
 
58
        if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_NAME)) {
 
59
                if (GTK_IS_LABEL(user_data)) {
 
60
                        gtk_label_set_text(GTK_LABEL(user_data), g_value_get_string(value));
 
61
                }
 
62
        }
 
63
 
 
64
        return;
 
65
}*/
 
66
 
 
67
void menu_item_set_icon_from_dmi
 
68
(DbusmenuMenuitem * mi, menu_item_t * mmi)
 
69
{
 
70
        GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(mi, DBUSMENU_MENUITEM_PROP_ICON_DATA);
 
71
        const char* icon_name;
 
72
        if(icon_name = dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_ICON_NAME)) {
 
73
                
 
74
                gtk_image_set_from_icon_name(mmi->icon, (gchar*)icon_name, GTK_ICON_SIZE_MENU);
 
75
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mmi->gmi), GTK_WIDGET(mmi->icon));
 
76
        }
 
77
        
 
78
        if (pixbuf != NULL) {
 
79
                /* If we've got a pixbuf we need to make sure it's of a reasonable
 
80
                   size to fit in the menu.  If not, rescale it. */
 
81
                GdkPixbuf * resized_pixbuf;
 
82
                gint width, height;
 
83
                gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
 
84
                if (gdk_pixbuf_get_width(pixbuf) > width ||
 
85
                                gdk_pixbuf_get_height(pixbuf) > height) {
 
86
                        g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height);
 
87
                        resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf,
 
88
                                                                 width,
 
89
                                                                 height,
 
90
                                                                 GDK_INTERP_BILINEAR);
 
91
                } else {
 
92
                        g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
 
93
                        resized_pixbuf = pixbuf;
 
94
                }
 
95
  
 
96
                gtk_image_set_from_pixbuf(GTK_IMAGE(mmi->icon), resized_pixbuf);
 
97
 
 
98
                /* The other pixbuf should be free'd by the dbusmenu. */
 
99
                if (resized_pixbuf != pixbuf) {
 
100
                        g_object_unref(resized_pixbuf);
 
101
                }
 
102
        }
 
103
}
 
104
 
 
105
/* Whenever we have a property change on a DbusmenuMenuitem
 
106
   we need to be responsive to that. */
 
107
static void
 
108
indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, menu_item_t * mmi)
 
109
{
 
110
        if(GTK_IS_LABEL(mmi->label)) {
 
111
                g_print ("Me-Messaging: (PropChange) %s (%s) [%s] '%s'\n", 
 
112
                        gtk_label_get_text(GTK_LABEL(mmi->label)),
 
113
                        prop,
 
114
                        dbusmenu_menuitem_property_get(mi, "type"),
 
115
                        g_value_get_string(value)
 
116
                );
 
117
        } else {
 
118
                g_print("Me-Messaging: (PropChange) %s\n", prop);
 
119
        }
 
120
        
 
121
        if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_LABEL)) {
 
122
                if(GTK_IS_LABEL(mmi->label)) {
 
123
                        gtk_label_set_text(GTK_LABEL(mmi->label), g_value_get_string(value));
 
124
                }
 
125
        } else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_RIGHT)) {
 
126
                if(GTK_IS_LABEL(mmi->right)) {
 
127
                        gtk_label_set_text(GTK_LABEL(mmi->right), g_value_get_string(value));
 
128
                }
 
129
        } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
 
130
                g_print("Setting Visible\n");
 
131
                if(g_value_get_boolean(value))
 
132
                {
 
133
                        gtk_widget_set_child_visible(mmi->gmi,TRUE);
 
134
                        gtk_widget_set_visible(GTK_WIDGET(mmi->gmi),TRUE);
 
135
                } else {
 
136
                        gtk_widget_set_child_visible(mmi->gmi,FALSE);
 
137
                        gtk_widget_set_visible(GTK_WIDGET(mmi->gmi),FALSE);
 
138
                }
 
139
        } else if (!g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_ICON_NAME)) {
 
140
                /* We don't use the value here, which is probably less efficient, 
 
141
                   but it's easier to use the easy function.  And since th value
 
142
                   is already cached, shouldn't be a big deal really.  */
 
143
                
 
144
                gtk_image_set_from_icon_name(mmi->icon, g_value_get_string(value), GTK_ICON_SIZE_MENU);
 
145
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mmi->gmi), GTK_WIDGET(mmi->icon));       
 
146
                
 
147
//              menu_item_set_icon_from_dmi(mi,mmi);
 
148
                
 
149
        }
 
150
 
 
151
        return;
 
152
}
 
153
 
 
154
void menu_item_set_label_from_dmi(menu_item_t* mmi, DbusmenuMenuitem * dbus_mi)
 
155
{
 
156
        g_print("Creating Label\n");
 
157
        const char* label_text = "<Unknown>";
 
158
        
 
159
        if(!GTK_IS_LABEL(mmi->label)) {
 
160
                mmi->label = gtk_label_new(NULL);
 
161
                gtk_misc_set_alignment(GTK_MISC(mmi->label), 0.0, 0.0);
 
162
                gtk_box_pack_start(GTK_BOX(mmi->hbox), mmi->label, TRUE, TRUE, 0.0);
 
163
        } else {
 
164
                label_text = gtk_label_get_text(GTK_LABEL(mmi->label));
 
165
        }
 
166
        
 
167
        if(dbusmenu_menuitem_property_get(dbus_mi, INDICATOR_MENUITEM_PROP_LABEL)) {
 
168
                label_text = dbusmenu_menuitem_property_get(dbus_mi, INDICATOR_MENUITEM_PROP_LABEL);
 
169
        } else if(dbusmenu_menuitem_property_get(dbus_mi, DBUSMENU_MENUITEM_PROP_LABEL)) {
 
170
                label_text = dbusmenu_menuitem_property_get(dbus_mi, DBUSMENU_MENUITEM_PROP_LABEL);
 
171
        } else if(dbusmenu_menuitem_property_get(dbus_mi, APPLICATION_MENUITEM_PROP_NAME)) {
 
172
                label_text = dbusmenu_menuitem_property_get(dbus_mi, APPLICATION_MENUITEM_PROP_NAME);
 
173
        }
 
174
        
 
175
        gtk_label_set_text(GTK_LABEL(mmi->label),label_text);
 
176
        
 
177
        return;
 
178
}
 
179
 
 
180
static gboolean
 
181
menu_item_new(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
 
182
{
 
183
        g_print("Me-Messaging: Entering creation of item\n");
 
184
        gint padding = 4;
 
185
        GtkWidget * running_icon;
 
186
        GtkWidget* icon;
 
187
        gint icon_width, icon_height;
 
188
        
 
189
        //Note: not checking parent, it's reasonable for it to be NULL
 
190
        menu_item_t * ret = g_new0(menu_item_t, 1);
 
191
        ret->hbox = gtk_hbox_new(FALSE, 0);
 
192
        
 
193
        // Build the GMI
 
194
        if(!g_strcmp0(dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_TYPE), APPLICATION_MENUITEM_TYPE)) {
 
195
                ret->gmi = gtk_image_menu_item_new();
 
196
                
 
197
                ret->icon = gtk_image_new_from_icon_name((gchar*)dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_ICON_NAME), GTK_ICON_SIZE_MENU);
 
198
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(ret->gmi), GTK_WIDGET(ret->icon));
 
199
                gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(ret->gmi), TRUE);
 
200
                if(dbusmenu_menuitem_property_get_image(newitem, DBUSMENU_MENUITEM_PROP_ICON_DATA) != NULL)
 
201
                {
 
202
                        g_print("Loading Icon Data!\n");
 
203
                        menu_item_set_icon_from_dmi(newitem, ret);
 
204
                } else {
 
205
                        g_print("No data to load!\n");
 
206
                }
 
207
 
 
208
//              gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
 
209
//              gtk_widget_set_size_request(icon, icon_width, icon_height);
 
210
//              gtk_misc_set_alignment(GTK_MISC(icon), 0.0, 0.0);
 
211
//              gtk_box_pack_start(GTK_BOX(ret->hbox), icon, FALSE, FALSE, padding);
 
212
//              g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), ret);
 
213
        } else {
 
214
                ret->gmi = gtk_menu_item_new();
 
215
        }
 
216
        gtk_widget_style_get(ret->gmi, "horizontal-padding", &padding, NULL);
 
217
        
 
218
        //Label Creation
 
219
        menu_item_set_label_from_dmi(ret, newitem);
 
220
        
 
221
        //RightBox
 
222
        ret->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_RIGHT));
 
223
        gtk_size_group_add_widget(myData.indicator_right_group, ret->right);
 
224
        gtk_misc_set_alignment(GTK_MISC(ret->right), 1.0, 0.5);
 
225
        gtk_box_pack_start(GTK_BOX(ret->hbox), ret->right, FALSE, FALSE, padding);
 
226
        
 
227
        //Insert the HBox
 
228
        gtk_container_add(GTK_CONTAINER(ret->gmi), ret->hbox);
 
229
        
 
230
        //Show the menu item
 
231
        if(!dbusmenu_menuitem_property_get_bool(newitem, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
 
232
                gtk_widget_set_child_visible(ret->gmi,FALSE);
 
233
                gtk_widget_set_visible(GTK_WIDGET(ret->gmi),FALSE);
 
234
        } else {
 
235
                gtk_widget_show_all(ret->gmi);
 
236
                gtk_widget_set_child_visible(ret->gmi,TRUE);
 
237
                gtk_widget_set_visible(GTK_WIDGET(ret->gmi),TRUE);
 
238
        }
 
239
        
 
240
        gtk_widget_show_all(ret->gmi);
 
241
        
 
242
        g_print("Messaging-Menu: (App) New Menu Item %s %s\n",
 
243
                gtk_label_get_text(GTK_LABEL(ret->label)),
 
244
                dbusmenu_menuitem_property_get(newitem, DBUSMENU_MENUITEM_PROP_TYPE)
 
245
        );
 
246
 
 
247
        g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), ret);
 
248
        dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ret->gmi), parent);
 
249
        
 
250
        return TRUE;
 
251
}
 
252
 
 
253
/* We have a small little menuitem type that handles all
 
254
   of the fun stuff for indicators.  Mostly this is the
 
255
   shifting over and putting the icon in with some right
 
256
   side text that'll be determined by the service.  */
 
257
static gboolean
 
258
new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
 
259
{
 
260
        
 
261
        return menu_item_new(newitem,parent,client);
 
262
}
 
263
 
 
264
/* Builds a menu item representing a running application in the
 
265
   messaging menu */
 
266
static gboolean
 
267
new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client)
 
268
{       
 
269
        return menu_item_new(newitem,parent,client);
 
270
}
 
271
 
 
272
 
 
273
  ///////////////
 
274
 // MAKE MENU //
 
275
///////////////
 
276
 
 
277
void cd_messaging_add_menu_handler (DbusmenuGtkClient * client)
 
278
{
 
279
        dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), INDICATOR_MENUITEM_TYPE, new_indicator_item);
 
280
        dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPLICATION_MENUITEM_TYPE, new_application_item);
 
281
}