1 |
ben |
1 |
/* |
2 |
|
|
* callbacks.c Copyright © 2009 by Benoît Rouits <brouits@free.fr> |
3 |
|
|
* Published under the terms of the GNU General Public License v2 (GPLv2). |
4 |
|
|
* |
5 |
|
|
* This program is free software; you can redistribute it and/or |
6 |
|
|
* modify it under the terms of the GNU General Public License |
7 |
|
|
* as published by the Free Software Foundation; either version 2 |
8 |
|
|
* of the License, or (at your option) any later version. |
9 |
|
|
* |
10 |
|
|
* This program is distributed in the hope that it will be useful, |
11 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
|
|
* GNU General Public License for more details. |
14 |
|
|
* |
15 |
|
|
* You should have received a copy of the GNU General Public License |
16 |
|
|
* along with this program; if not, write to the Free Software |
17 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 |
|
|
* Boston, MA 02110-1301, USA. |
19 |
|
|
* |
20 |
|
|
* see the COPYING file included in the jackie package or |
21 |
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt for the full licence |
22 |
|
|
* |
23 |
|
|
*/ |
24 |
|
|
|
25 |
|
|
#include <gtk/gtk.h> |
26 |
|
|
#include <libintl.h> |
27 |
|
|
#include <locale.h> |
28 |
|
|
#include "controller.h" |
29 |
|
|
#include "menu.h" |
30 |
|
|
#include "about.h" |
31 |
|
|
#include "version.h" |
32 |
|
|
#define _(string) gettext (string) |
33 |
|
|
|
34 |
|
|
/* refresh the tooltip */ |
35 |
|
|
gboolean tooltip_display (gpointer app_data) { |
36 |
|
|
AppData* d = (AppData*) app_data; |
37 |
|
|
gchar* tooltip; |
38 |
|
|
|
39 |
|
|
tooltip = mpd_get_song(d->sock); |
40 |
|
|
gtk_status_icon_set_tooltip(d->status_icon, tooltip); |
41 |
|
|
g_free(tooltip); |
42 |
|
|
return TRUE; |
43 |
|
|
} |
44 |
|
|
|
45 |
|
|
/* handler for the volume button drag */ |
46 |
ben |
19 |
void volume_on_change (GtkWidget* instance, gpointer app_data) { |
47 |
ben |
1 |
gchar* cmd = NULL; |
48 |
ben |
17 |
gdouble value = 0; |
49 |
ben |
1 |
AppData* d = (AppData*) app_data; |
50 |
|
|
|
51 |
ben |
17 |
value = gtk_range_get_value(GTK_RANGE(d->volume)); |
52 |
|
|
cmd = g_strdup_printf ("setvol %.0f", value); |
53 |
ben |
1 |
mpd_control (d->sock, cmd); |
54 |
|
|
g_free (cmd); |
55 |
|
|
instance = NULL; |
56 |
|
|
} |
57 |
|
|
|
58 |
ben |
19 |
/* handler for volume slider leaving (close) */ |
59 |
ben |
21 |
gboolean volume_on_leave (GtkWidget* instance, GdkEventFocus* event, gpointer app_data) |
60 |
ben |
19 |
{ |
61 |
|
|
AppData* d = (AppData*) app_data; |
62 |
|
|
|
63 |
|
|
gtk_widget_hide (d->vol_window); |
64 |
|
|
gtk_widget_destroy (d->vol_window); |
65 |
|
|
d->vol_window = NULL; |
66 |
|
|
instance = NULL; |
67 |
|
|
event = NULL; |
68 |
|
|
return FALSE; |
69 |
|
|
} |
70 |
|
|
|
71 |
ben |
1 |
/* handler for left-button click */ |
72 |
|
|
void status_icon_on_left_click(GtkStatusIcon* instance, gpointer app_data) { |
73 |
|
|
AppData* d = (AppData*) app_data; |
74 |
ben |
17 |
gdouble curvol; |
75 |
ben |
1 |
|
76 |
ben |
19 |
if (NULL != d->vol_window) /* already set up */ |
77 |
|
|
return; |
78 |
|
|
d->vol_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
79 |
|
|
gtk_window_set_decorated (GTK_WINDOW(d->vol_window), FALSE); |
80 |
|
|
gtk_window_set_default_size(GTK_WINDOW(d->vol_window), 25, 128); |
81 |
ben |
22 |
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(d->vol_window), TRUE); |
82 |
ben |
19 |
gtk_window_set_position(GTK_WINDOW(d->vol_window), GTK_WIN_POS_MOUSE); |
83 |
ben |
17 |
d->volume = gtk_vscale_new_with_range (0, 100, 1); |
84 |
|
|
gtk_range_set_inverted(GTK_RANGE(d->volume), TRUE); |
85 |
|
|
curvol = mpd_get_vol(d->sock); |
86 |
|
|
gtk_range_set_value(GTK_RANGE(d->volume), curvol); |
87 |
ben |
19 |
gtk_container_add (GTK_CONTAINER(d->vol_window), d->volume); |
88 |
|
|
g_signal_connect(G_OBJECT(d->volume), "value-changed", G_CALLBACK(volume_on_change), app_data); |
89 |
ben |
21 |
g_signal_connect(G_OBJECT(d->volume), "focus-out-event", G_CALLBACK(volume_on_leave), app_data); |
90 |
ben |
19 |
gtk_widget_show_all(d->vol_window); |
91 |
ben |
17 |
instance = NULL; |
92 |
ben |
1 |
} |
93 |
|
|
|
94 |
|
|
/* handler for right-button click */ |
95 |
|
|
void status_icon_on_right_click(GtkStatusIcon* instance, guint button, guint activate_time, gpointer app_data) { |
96 |
|
|
AppData* d = (AppData*) app_data; |
97 |
|
|
|
98 |
|
|
if (app_data) |
99 |
|
|
menu_show (GTK_MENU(d->right_menu), button, activate_time); |
100 |
|
|
instance = NULL; |
101 |
|
|
} |
102 |
|
|
|
103 |
|
|
/* handler for the "Play" menu item */ |
104 |
|
|
void menu_item_on_play(GtkMenuItem* instance, gpointer app_data) { |
105 |
|
|
AppData* d = (AppData*) app_data; |
106 |
|
|
|
107 |
|
|
mpd_control(d->sock, "play"); |
108 |
|
|
instance = NULL; |
109 |
|
|
} |
110 |
|
|
|
111 |
|
|
/* handler for the "Pause" menu item */ |
112 |
|
|
void menu_item_on_pause(GtkMenuItem* instance, gpointer app_data) { |
113 |
|
|
AppData* d = (AppData*) app_data; |
114 |
|
|
|
115 |
|
|
mpd_control(d->sock, "pause"); |
116 |
|
|
instance = NULL; |
117 |
|
|
} |
118 |
|
|
|
119 |
|
|
void menu_item_on_next(GtkMenuItem* instance, gpointer app_data) { |
120 |
|
|
AppData* d = (AppData*) app_data; |
121 |
|
|
|
122 |
|
|
mpd_control(d->sock, "next"); |
123 |
|
|
instance = NULL; |
124 |
|
|
} |
125 |
|
|
|
126 |
|
|
void menu_item_on_prev(GtkMenuItem* instance, gpointer app_data) { |
127 |
|
|
AppData* d = (AppData*) app_data; |
128 |
|
|
|
129 |
|
|
mpd_control(d->sock, "previous"); |
130 |
|
|
instance = NULL; |
131 |
|
|
} |
132 |
|
|
|
133 |
|
|
void menu_item_on_stop(GtkMenuItem* instance, gpointer app_data) { |
134 |
|
|
AppData* d = (AppData*) app_data; |
135 |
|
|
|
136 |
|
|
mpd_control(d->sock, "stop"); |
137 |
|
|
instance = NULL; |
138 |
|
|
} |
139 |
|
|
|
140 |
|
|
void menu_item_on_shuffle(GtkMenuItem* instance, gpointer app_data) { |
141 |
|
|
AppData* d = (AppData*) app_data; |
142 |
|
|
|
143 |
|
|
mpd_control(d->sock, "shuffle"); |
144 |
|
|
instance = NULL; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
/* handler for the "About" menu item (see version.h) */ |
148 |
|
|
void menu_item_on_about(GtkMenuItem* instance, gpointer unused) { |
149 |
|
|
GtkAboutDialog* about; |
150 |
|
|
const gchar* authors [] = { |
151 |
|
|
PROG_AUTHOR0, |
152 |
|
|
NULL |
153 |
|
|
}; |
154 |
|
|
|
155 |
|
|
about = about_create (PROG_NAME, PROG_VERSION, PROG_COPYRIGHT, |
156 |
|
|
PROG_COMMENT, PROG_LICENSE, PROG_WEBSITE, |
157 |
|
|
authors); |
158 |
|
|
about_show (about); |
159 |
|
|
unused = NULL; /* avoid compiler warnings */ |
160 |
|
|
instance = NULL; /* _ */ |
161 |
|
|
return; |
162 |
|
|
} |
163 |
|
|
|
164 |
|
|
/* callback on Preferences window closed */ |
165 |
|
|
void pref_window_on_close (gpointer app_data) { |
166 |
|
|
AppData* d = (AppData*) app_data; |
167 |
|
|
|
168 |
|
|
g_free(d->ip); |
169 |
|
|
d->ip = g_strdup (gtk_entry_get_text(d->ip_entry)); |
170 |
|
|
|
171 |
|
|
d->port = gtk_spin_button_get_value_as_int (d->port_spin); |
172 |
|
|
|
173 |
|
|
/* write it to $HOME/.fala */ |
174 |
|
|
write_config (d); |
175 |
|
|
gtk_widget_hide (GTK_WIDGET(d->pref_window)); |
176 |
|
|
gtk_widget_destroy (GTK_WIDGET(d->pref_window)); |
177 |
|
|
gtk_widget_set_sensitive (GTK_WIDGET(d->pref_item), TRUE); |
178 |
|
|
d->pref_window = NULL; |
179 |
|
|
mpd_disconnect (d->sock); |
180 |
|
|
d->sock = -1; |
181 |
|
|
d->sock = mpd_connect (d->ip, d->port); |
182 |
|
|
} |
183 |
|
|
|
184 |
|
|
/* handler for the "Preference" menu item */ |
185 |
|
|
void menu_item_on_pref(GtkMenuItem* instance, gpointer app_data) { |
186 |
|
|
AppData* d = (AppData*) app_data; |
187 |
|
|
GtkVBox* vbox; |
188 |
|
|
GtkHBox* hbox1; |
189 |
|
|
GtkHBox* hbox2; |
190 |
|
|
GtkHBox* hbox3; |
191 |
|
|
GtkLabel* ip_label; |
192 |
|
|
GtkLabel* port_label; |
193 |
|
|
GtkLabel* empty_label; |
194 |
|
|
GtkButton* close_button; |
195 |
|
|
|
196 |
|
|
d->pref_window = GTK_WINDOW(gtk_window_new (GTK_WINDOW_TOPLEVEL)); |
197 |
|
|
gtk_window_set_title (GTK_WINDOW(d->pref_window), _("Preferences")); |
198 |
|
|
gtk_window_set_default_size (GTK_WINDOW(d->pref_window), 300, 200); |
199 |
|
|
gtk_window_set_resizable (GTK_WINDOW(d->pref_window), TRUE); |
200 |
|
|
|
201 |
|
|
vbox = GTK_VBOX(gtk_vbox_new (TRUE, 0)); |
202 |
|
|
gtk_container_add (GTK_CONTAINER(d->pref_window), GTK_WIDGET(vbox)); |
203 |
|
|
|
204 |
|
|
hbox1 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
205 |
|
|
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox1), TRUE, FALSE, 10); |
206 |
|
|
|
207 |
|
|
hbox2 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
208 |
|
|
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox2), TRUE, FALSE, 10); |
209 |
|
|
|
210 |
|
|
hbox3 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
211 |
|
|
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox3), TRUE, FALSE, 10); |
212 |
|
|
|
213 |
|
|
ip_label = GTK_LABEL(gtk_label_new (_("MPD IP Address:"))); |
214 |
|
|
gtk_box_pack_start (GTK_BOX(hbox1), GTK_WIDGET(ip_label), TRUE, FALSE, 10); |
215 |
|
|
port_label = GTK_LABEL(gtk_label_new (_("MPD TCP Port:"))); |
216 |
|
|
gtk_box_pack_start (GTK_BOX(hbox2), GTK_WIDGET(port_label), TRUE, FALSE, 10); |
217 |
|
|
|
218 |
|
|
d->ip_entry = GTK_ENTRY(gtk_entry_new ()); |
219 |
|
|
gtk_entry_set_max_length (d->ip_entry, 15); |
220 |
|
|
gtk_entry_set_width_chars (d->ip_entry, 15); |
221 |
|
|
gtk_entry_set_text (d->ip_entry, d->ip); /* MPD ip address */ |
222 |
|
|
gtk_box_pack_start( GTK_BOX(hbox1), GTK_WIDGET(d->ip_entry), TRUE, FALSE, 10); |
223 |
|
|
d->port_spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range (1, 65535, 1)); |
224 |
|
|
gtk_spin_button_set_value (d->port_spin, (gdouble)d->port); /* MPD tcp port */ |
225 |
|
|
gtk_box_pack_start (GTK_BOX(hbox2), GTK_WIDGET(d->port_spin), TRUE, FALSE, 10); |
226 |
|
|
|
227 |
|
|
empty_label = GTK_LABEL(gtk_label_new ("")); |
228 |
|
|
gtk_box_pack_start (GTK_BOX(hbox3), GTK_WIDGET(empty_label), TRUE, FALSE, 10); |
229 |
|
|
|
230 |
|
|
close_button = GTK_BUTTON(gtk_button_new_from_stock (GTK_STOCK_CLOSE)); |
231 |
|
|
gtk_box_pack_start (GTK_BOX(hbox3), GTK_WIDGET(close_button), FALSE, FALSE, 10); |
232 |
|
|
|
233 |
|
|
g_signal_connect_swapped (G_OBJECT(close_button), "clicked", G_CALLBACK(pref_window_on_close), (gpointer)d); |
234 |
|
|
g_signal_connect_swapped (G_OBJECT(d->pref_window), "delete-event", G_CALLBACK(pref_window_on_close), (gpointer)d); |
235 |
|
|
|
236 |
|
|
gtk_widget_show_all (GTK_WIDGET(d->pref_window)); |
237 |
|
|
gtk_widget_set_sensitive (GTK_WIDGET(instance), FALSE); |
238 |
|
|
} |
239 |
|
|
|
240 |
|
|
/* handler for the "Quit" menu item */ |
241 |
|
|
void menu_item_on_quit(GtkMenuItem* instance, gpointer app_data) { |
242 |
|
|
AppData* d = (AppData*) app_data; |
243 |
|
|
quit (d); |
244 |
|
|
instance = NULL; /* useless but does not warn at compile time */ |
245 |
|
|
} |
246 |
|
|
|