1 /*
2  * Copyright (C) 2007 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
3  *
4  * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 #include <string.h>
22 #include <stdlib.h>
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <gmodule.h>
27 
28 #include "gui.h"
29 #include "icons.h"
30 #include "upnp.h"
31 #include "main.h"
32 
33 #define UI_FILE   "/org/gupnp/Tools/Network-Light/gupnp-network-light.ui"
34 #define ICON_FILE "/org/gupnp/Tools/Network-Light/pixmaps/network-light.png"
35 #define OFF_FILE  "/org/gupnp/Tools/Network-Light/pixmaps/network-light-off.png"
36 #define ON_FILE   "/org/gupnp/Tools/Network-Light/pixmaps/network-light-on.png"
37 
38 static GtkBuilder *builder;
39 static GtkWidget  *main_window;
40 static GtkWidget  *about_dialog;
41 static GdkPixbuf  *on_pixbuf;
42 static GdkPixbuf  *off_pixbuf;
43 static gboolean    change_all = TRUE; // ui changes apply to all devices
44 
45 void
46 on_light_status_menuitem_activate (GtkCheckMenuItem *menuitem,
47                                    gpointer          user_data);
48 void
49 on_about_menuitem_activate (GtkMenuItem *menuitem,
50                             gpointer     user_data);
51 
52 void
53 on_increase_luminance_menuitem_activate (GtkMenuItem *menuitem,
54                                          gpointer     user_data);
55 
56 void
57 on_decrease_luminance_menuitem_activate (GtkMenuItem *menuitem,
58                                          gpointer     user_data);
59 gboolean
60 on_main_window_button_event (GtkWidget      *widget,
61                              GdkEventButton *event,
62                              gpointer        user_data);
63 
64 gboolean
65 on_delete_event (GtkWidget *widget,
66                  GdkEvent  *event,
67                  gpointer   user_data);
68 
69 void
update_image(void)70 update_image (void)
71 {
72         GtkWidget *image;
73         GdkPixbuf *pixbuf;
74         gfloat     alpha;
75 
76         image = GTK_WIDGET (gtk_builder_get_object (builder,
77                                                     "light-bulb-image"));
78         g_assert (image != NULL);
79 
80         if (get_status ()) {
81                 alpha = get_load_level () * 2.5;
82         } else {
83                 alpha = 0.0;
84         }
85 
86         pixbuf = gdk_pixbuf_copy (off_pixbuf);
87         gdk_pixbuf_composite (on_pixbuf,
88                               pixbuf,
89                               0, 0,
90                               gdk_pixbuf_get_width (pixbuf),
91                               gdk_pixbuf_get_height (pixbuf),
92                               0.0, 0.0, 1.0, 1.0,
93                               GDK_INTERP_HYPER,
94                               (int) alpha);
95         gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
96         g_object_unref (pixbuf);
97 }
98 
99 G_MODULE_EXPORT
100 void
on_light_status_menuitem_activate(GtkCheckMenuItem * menuitem,gpointer user_data)101 on_light_status_menuitem_activate (GtkCheckMenuItem *menuitem,
102                                    gpointer          user_data)
103 {
104         if (change_all) {
105                 set_all_status (gtk_check_menu_item_get_active (menuitem));
106         } else {
107                 set_status (gtk_check_menu_item_get_active (menuitem));
108         }
109 }
110 
111 G_MODULE_EXPORT
112 void
on_about_menuitem_activate(GtkMenuItem * menuitem,gpointer user_data)113 on_about_menuitem_activate (GtkMenuItem *menuitem,
114                             gpointer     user_data)
115 {
116         gtk_widget_show (about_dialog);
117 }
118 
119 G_MODULE_EXPORT
120 void
on_increase_luminance_menuitem_activate(GtkMenuItem * menuitem,gpointer user_data)121 on_increase_luminance_menuitem_activate (GtkMenuItem *menuitem,
122                                          gpointer     user_data)
123 {
124         if (change_all) {
125                 set_all_load_level (get_load_level () + 20);
126         } else {
127                 set_load_level (get_load_level () + 20);
128         }
129 }
130 
131 G_MODULE_EXPORT
132 void
on_decrease_luminance_menuitem_activate(GtkMenuItem * menuitem,gpointer user_data)133 on_decrease_luminance_menuitem_activate (GtkMenuItem *menuitem,
134                                          gpointer     user_data)
135 {
136         if (change_all) {
137                 set_all_load_level (get_load_level () - 20);
138         } else {
139                 set_load_level (get_load_level () - 20);
140         }
141 }
142 
143 static void
prepare_popup(void)144 prepare_popup (void)
145 {
146         GtkWidget *status_menuitem;
147 
148         status_menuitem = GTK_WIDGET (gtk_builder_get_object (
149                                                 builder,
150                                                 "light-status-menuitem"));
151         g_assert (status_menuitem != NULL);
152 
153         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (status_menuitem),
154                                         get_status ());
155 }
156 
157 static void
on_main_window_right_clicked(GdkEventButton * event)158 on_main_window_right_clicked (GdkEventButton *event)
159 {
160         GtkWidget *popup;
161 
162         popup = GTK_WIDGET (gtk_builder_get_object (builder, "popup-menu"));
163         g_assert (popup != NULL);
164 
165         prepare_popup ();
166 
167 #if GTK_CHECK_VERSION(3,22,0)
168         gtk_menu_popup_at_pointer (GTK_MENU (popup), (GdkEvent *)event);
169 #else
170         gtk_menu_popup (GTK_MENU (popup),
171                         NULL,
172                         NULL,
173                         NULL,
174                         NULL,
175                         event->button,
176                         event->time);
177 #endif
178 }
179 
180 G_MODULE_EXPORT
181 gboolean
on_main_window_button_event(GtkWidget * widget,GdkEventButton * event,gpointer user_data)182 on_main_window_button_event (GtkWidget      *widget,
183                              GdkEventButton *event,
184                              gpointer        user_data)
185 {
186         if (event->type == GDK_BUTTON_RELEASE &&
187             event->button == 3) {
188                 on_main_window_right_clicked (event);
189 
190                 return TRUE;
191         } else if (event->type == GDK_2BUTTON_PRESS &&
192                    event->button == 1) {
193                 set_status (!get_status ());
194 
195                 return TRUE;
196         } else {
197                 return FALSE;
198         }
199 }
200 
201 G_MODULE_EXPORT
202 gboolean
on_delete_event(GtkWidget * widget,GdkEvent * event,gpointer user_data)203 on_delete_event (GtkWidget *widget,
204                  GdkEvent  *event,
205                  gpointer   user_data)
206 {
207         gtk_main_quit ();
208         return TRUE;
209 }
210 
211 gboolean
init_ui(gint * argc,gchar ** argv[],gchar * name,gboolean exclusive)212 init_ui (gint   *argc,
213          gchar **argv[],
214          gchar *name,
215          gboolean exclusive)
216 {
217         GdkPixbuf *icon_pixbuf;
218         GError *error = NULL;
219 
220         change_all = !exclusive;
221 
222         gtk_init (argc, argv);
223         init_icons ();
224 
225         builder = gtk_builder_new ();
226         g_assert (builder != NULL);
227         gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
228 
229         if (!gtk_builder_add_from_resource (builder, UI_FILE, &error)) {
230                 g_critical ("Unable to load the GUI file %s: %s",
231                             UI_FILE,
232                             error->message);
233 
234                 g_error_free (error);
235                 return FALSE;
236         }
237 
238         main_window = GTK_WIDGET (gtk_builder_get_object (builder,
239                                                           "main-window"));
240         g_assert (main_window != NULL);
241 
242         if (name && (strlen(name) > 0)) {
243             gtk_window_set_title (GTK_WINDOW (main_window), name);
244         }
245 
246         about_dialog = GTK_WIDGET (gtk_builder_get_object (builder,
247                                                            "about-dialog"));
248         g_assert (about_dialog != NULL);
249 
250         on_pixbuf = gdk_pixbuf_new_from_resource (ON_FILE, NULL);
251         if (on_pixbuf == NULL)
252                 return FALSE;
253 
254         off_pixbuf = gdk_pixbuf_new_from_resource (OFF_FILE, NULL);
255         if (off_pixbuf == NULL) {
256                 g_object_unref (on_pixbuf);
257                 return FALSE;
258         }
259 
260         icon_pixbuf = gdk_pixbuf_new_from_resource (ICON_FILE, NULL);
261         if (icon_pixbuf == NULL) {
262                 g_object_unref (on_pixbuf);
263                 g_object_unref (off_pixbuf);
264                 return FALSE;
265         }
266 
267         gtk_window_set_icon (GTK_WINDOW (main_window), icon_pixbuf);
268         gtk_window_set_icon (GTK_WINDOW (about_dialog), icon_pixbuf);
269         gtk_about_dialog_set_logo (GTK_ABOUT_DIALOG (about_dialog),
270                                    icon_pixbuf);
271         gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (about_dialog),
272                                       VERSION);
273 
274         g_object_unref (icon_pixbuf);
275 
276         gtk_builder_connect_signals (builder, NULL);
277         g_signal_connect (G_OBJECT (about_dialog), "delete-event",
278                           G_CALLBACK (gtk_widget_hide_on_delete), NULL);
279 
280         update_image ();
281 
282         gtk_widget_show_all (main_window);
283 
284         return TRUE;
285 }
286 
287 void
deinit_ui(void)288 deinit_ui (void)
289 {
290         g_object_unref (builder);
291         gtk_widget_destroy (main_window);
292         gtk_widget_destroy (about_dialog);
293         g_object_unref (on_pixbuf);
294         g_object_unref (off_pixbuf);
295         deinit_icons ();
296 }
297 
298