Mercurial > audlegacy
comparison src/audlegacy/ui_new.c @ 4811:7bf7f83a217e
rename src/audacious src/audlegacy so that both audlegacy and audacious can coexist.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Wed, 26 Nov 2008 00:44:56 +0900 |
parents | src/audacious/ui_new.c@3e188277c4ed |
children | 53dd85fdf42b |
comparison
equal
deleted
inserted
replaced
4810:c10e53092037 | 4811:7bf7f83a217e |
---|---|
1 /* Audacious - Cross-platform multimedia player | |
2 * Copyright (C) 2005-2008 Audacious development team | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; under version 3 of the License. | |
7 * | |
8 * This program is distributed in the hope that it will be useful, | |
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 * GNU General Public License for more details. | |
12 * | |
13 * You should have received a copy of the GNU General Public License | |
14 * along with this program. If not, see <http://www.gnu.org/licenses>. | |
15 * | |
16 * The Audacious team does not consider modular code linking to | |
17 * Audacious or using our public API to be a derived work. | |
18 */ | |
19 | |
20 #include <glib/gi18n.h> | |
21 #include <gtk/gtk.h> | |
22 | |
23 #include "interface.h" | |
24 #include "playback.h" | |
25 #include "playlist.h" | |
26 #include "ui_fileopener.h" | |
27 #include "ui_new.h" | |
28 #include "ui_playlist_widget.h" | |
29 | |
30 static GtkWidget *label_time; | |
31 static GtkWidget *slider; | |
32 static GtkWidget *treeview; | |
33 | |
34 static gulong slider_change_handler_id; | |
35 static gboolean slider_is_moving = FALSE; | |
36 static gint update_song_timeout_source = 0; | |
37 | |
38 static gboolean | |
39 window_delete() | |
40 { | |
41 return FALSE; | |
42 } | |
43 | |
44 static void | |
45 window_destroy(GtkWidget *widget, gpointer data) | |
46 { | |
47 gtk_main_quit(); | |
48 } | |
49 | |
50 static void | |
51 button_open_pressed() | |
52 { | |
53 run_filebrowser(TRUE); | |
54 } | |
55 | |
56 static void | |
57 button_add_pressed() | |
58 { | |
59 run_filebrowser(FALSE); | |
60 } | |
61 | |
62 static void | |
63 button_play_pressed() | |
64 { | |
65 if (playlist_get_length(playlist_get_active())) | |
66 playback_initiate(); | |
67 else | |
68 button_open_pressed(); | |
69 } | |
70 | |
71 static void | |
72 button_pause_pressed() | |
73 { | |
74 playback_pause(); | |
75 } | |
76 | |
77 static void | |
78 button_stop_pressed() | |
79 { | |
80 playback_stop(); | |
81 } | |
82 | |
83 static void | |
84 button_previous_pressed() | |
85 { | |
86 playlist_prev(playlist_get_active()); | |
87 } | |
88 | |
89 static void | |
90 button_next_pressed() | |
91 { | |
92 playlist_next(playlist_get_active()); | |
93 } | |
94 | |
95 static void | |
96 ui_set_song_info(gchar *text, gpointer user_data) | |
97 { | |
98 gint length = playback_get_length(); | |
99 | |
100 /* block "value-changed" signal handler to prevent skipping track | |
101 if the next track is shorter than the previous one --desowin */ | |
102 g_signal_handler_block(slider, slider_change_handler_id); | |
103 gtk_range_set_range(GTK_RANGE(slider), 0.0, (gdouble)length); | |
104 g_signal_handler_unblock(slider, slider_change_handler_id); | |
105 | |
106 gtk_widget_show(label_time); | |
107 | |
108 ui_playlist_widget_set_current(treeview, playlist_get_position(playlist_get_active())); | |
109 } | |
110 | |
111 static void | |
112 ui_playlist_update(Playlist *playlist, gpointer user_data) | |
113 { | |
114 gchar *text = playlist_get_info_text(playlist); | |
115 ui_set_song_info(text, NULL); | |
116 g_free(text); | |
117 | |
118 ui_playlist_widget_update(treeview); | |
119 } | |
120 | |
121 static void | |
122 ui_update_time_info(gint time) | |
123 { | |
124 gchar text[128]; | |
125 gint length = playback_get_length(); | |
126 | |
127 time /= 1000; | |
128 length /= 1000; | |
129 | |
130 g_snprintf(text, sizeof(text)/sizeof(gchar), | |
131 "<tt><b>%d:%.2d/%d:%.2d</b></tt>", | |
132 time / 60, time % 60, | |
133 length / 60, length % 60); | |
134 gtk_label_set_markup(GTK_LABEL(label_time), text); | |
135 } | |
136 | |
137 static gboolean | |
138 ui_update_song_info(gpointer hook_data, gpointer user_data) | |
139 { | |
140 if (!playback_get_playing()) | |
141 { | |
142 gtk_range_set_value(GTK_RANGE(slider), 0.0); | |
143 return FALSE; | |
144 } | |
145 | |
146 if (slider_is_moving) | |
147 return TRUE; | |
148 | |
149 gint time = playback_get_time(); | |
150 | |
151 g_signal_handler_block(slider, slider_change_handler_id); | |
152 gtk_range_set_value(GTK_RANGE(slider), (gdouble)time); | |
153 g_signal_handler_unblock(slider, slider_change_handler_id); | |
154 | |
155 ui_update_time_info(time); | |
156 | |
157 return TRUE; | |
158 } | |
159 | |
160 static void | |
161 ui_clear_song_info() | |
162 { | |
163 gtk_widget_hide(label_time); | |
164 gtk_range_set_value(GTK_RANGE(slider), 0); | |
165 } | |
166 | |
167 static gboolean | |
168 ui_slider_value_changed_cb(GtkRange *range, gpointer user_data) | |
169 { | |
170 gint seek_; | |
171 | |
172 seek_ = gtk_range_get_value(range) / 1000; | |
173 | |
174 /* XXX: work around a horrible bug in playback_seek(), also | |
175 we should do mseek here. --nenolod */ | |
176 playback_seek(seek_ != 0 ? seek_ : 1); | |
177 | |
178 return TRUE; | |
179 } | |
180 | |
181 static gboolean | |
182 ui_slider_change_value_cb(GtkRange *range, GtkScrollType scroll) | |
183 { | |
184 ui_update_time_info(gtk_range_get_value(range)); | |
185 return FALSE; | |
186 } | |
187 | |
188 static gboolean | |
189 ui_slider_button_press_cb(GtkWidget *widget, GdkEventButton *event, | |
190 gpointer user_data) | |
191 { | |
192 slider_is_moving = TRUE; | |
193 return FALSE; | |
194 } | |
195 | |
196 static gboolean | |
197 ui_slider_button_release_cb(GtkWidget *widget, GdkEventButton *event, | |
198 gpointer user_data) | |
199 { | |
200 slider_is_moving = FALSE; | |
201 return FALSE; | |
202 } | |
203 | |
204 static void | |
205 ui_playback_begin(gpointer hook_data, gpointer user_data) | |
206 { | |
207 ui_update_song_info(NULL, NULL); | |
208 | |
209 /* update song info 4 times a second */ | |
210 update_song_timeout_source = | |
211 g_timeout_add(250, (GSourceFunc) ui_update_song_info, NULL); | |
212 } | |
213 | |
214 static void | |
215 ui_playback_stop(gpointer hook_data, gpointer user_data) | |
216 { | |
217 if (update_song_timeout_source) { | |
218 g_source_remove(update_song_timeout_source); | |
219 update_song_timeout_source = 0; | |
220 } | |
221 | |
222 ui_clear_song_info(); | |
223 ui_playlist_widget_set_current(treeview, -1); | |
224 } | |
225 | |
226 static void | |
227 ui_playback_end(gpointer hook_data, gpointer user_data) | |
228 { | |
229 ui_update_song_info(NULL, NULL); | |
230 } | |
231 | |
232 static GtkWidget * | |
233 gtk_toolbar_button_add(GtkWidget *toolbar, void(*callback)(), | |
234 const gchar *stock_id) | |
235 { | |
236 GtkWidget *button = gtk_button_new(); | |
237 gtk_button_set_label(GTK_BUTTON(button), stock_id); | |
238 gtk_button_set_use_stock(GTK_BUTTON(button), TRUE); | |
239 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
240 | |
241 /* remove label */ | |
242 GtkBox *box = GTK_BOX(gtk_bin_get_child(GTK_BIN(gtk_bin_get_child(GTK_BIN(button))))); | |
243 GList *iter; | |
244 for (iter = box->children; iter; iter = g_list_next(iter)) { | |
245 GtkBoxChild *child = (GtkBoxChild *) iter->data; | |
246 if (GTK_IS_LABEL(child->widget)) { | |
247 gtk_label_set_text(GTK_LABEL(child->widget), NULL); | |
248 break; | |
249 } | |
250 } | |
251 | |
252 gtk_box_pack_start(GTK_BOX(toolbar), button, TRUE, TRUE, 0); | |
253 g_signal_connect(G_OBJECT(button), "clicked", | |
254 G_CALLBACK(callback), NULL); | |
255 return button; | |
256 } | |
257 | |
258 static GtkWidget * | |
259 gtk_markup_label_new(const gchar *str) | |
260 { | |
261 GtkWidget *label = gtk_label_new(str); | |
262 g_object_set(G_OBJECT(label), "use-markup", TRUE, NULL); | |
263 return label; | |
264 } | |
265 | |
266 static void | |
267 ui_hooks_associate() | |
268 { | |
269 hook_associate("title change", (HookFunction) ui_set_song_info, NULL); | |
270 hook_associate("playback seek", (HookFunction) ui_update_song_info, NULL); | |
271 hook_associate("playback begin", (HookFunction) ui_playback_begin, NULL); | |
272 hook_associate("playback stop", (HookFunction) ui_playback_stop, NULL); | |
273 hook_associate("playback end", (HookFunction) ui_playback_end, NULL); | |
274 hook_associate("playlist update", (HookFunction) ui_playlist_update, NULL); | |
275 } | |
276 | |
277 static void | |
278 ui_hooks_disassociate() | |
279 { | |
280 hook_dissociate("title change", (HookFunction) ui_set_song_info); | |
281 hook_dissociate("playback seek", (HookFunction) ui_update_song_info); | |
282 hook_dissociate("playback begin", (HookFunction) ui_playback_begin); | |
283 hook_dissociate("playback stop", (HookFunction) ui_playback_stop); | |
284 hook_dissociate("playback end", (HookFunction) ui_playback_end); | |
285 hook_dissociate("playlist update", (HookFunction) ui_playlist_update); | |
286 } | |
287 | |
288 static gboolean | |
289 _ui_initialize(void) | |
290 { | |
291 GtkWidget *window; /* the main window */ | |
292 GtkWidget *vbox; /* the main vertical box */ | |
293 GtkWidget *tophbox; /* box to contain toolbar and shbox */ | |
294 GtkWidget *scrollwin; /* widget to hold playlist widget */ | |
295 GtkWidget *buttonbox; /* contains buttons like "open", "next" */ | |
296 GtkWidget *shbox; /* box for slider + time combo --nenolod */ | |
297 GtkWidget *button_open, *button_add, | |
298 *button_play, *button_pause, *button_stop, | |
299 *button_previous, *button_next; | |
300 | |
301 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
302 gtk_window_set_default_size(GTK_WINDOW(window), 450, 150); | |
303 g_signal_connect(G_OBJECT(window), "delete_event", | |
304 G_CALLBACK(window_delete), NULL); | |
305 g_signal_connect(G_OBJECT(window), "destroy", | |
306 G_CALLBACK(window_destroy), NULL); | |
307 | |
308 | |
309 vbox = gtk_vbox_new(FALSE, 0); | |
310 gtk_container_add(GTK_CONTAINER(window), vbox); | |
311 | |
312 tophbox = gtk_hbox_new(FALSE, 0); | |
313 gtk_box_pack_start(GTK_BOX(vbox), tophbox, FALSE, TRUE, 0); | |
314 | |
315 buttonbox = gtk_hbox_new(FALSE, 0); | |
316 button_open = gtk_toolbar_button_add(buttonbox, button_open_pressed, | |
317 GTK_STOCK_OPEN); | |
318 button_add = gtk_toolbar_button_add(buttonbox, button_add_pressed, | |
319 GTK_STOCK_ADD); | |
320 button_play = gtk_toolbar_button_add(buttonbox, button_play_pressed, | |
321 GTK_STOCK_MEDIA_PLAY); | |
322 button_pause = gtk_toolbar_button_add(buttonbox, button_pause_pressed, | |
323 GTK_STOCK_MEDIA_PAUSE); | |
324 button_stop = gtk_toolbar_button_add(buttonbox, button_stop_pressed, | |
325 GTK_STOCK_MEDIA_STOP); | |
326 button_previous = gtk_toolbar_button_add(buttonbox, button_previous_pressed, | |
327 GTK_STOCK_MEDIA_PREVIOUS); | |
328 button_next = gtk_toolbar_button_add(buttonbox, button_next_pressed, | |
329 GTK_STOCK_MEDIA_NEXT); | |
330 | |
331 gtk_box_pack_start(GTK_BOX(tophbox), buttonbox, FALSE, FALSE, 0); | |
332 | |
333 shbox = gtk_hbox_new(FALSE, 0); | |
334 gtk_box_pack_start(GTK_BOX(tophbox), shbox, TRUE, TRUE, 0); | |
335 | |
336 slider = gtk_hscale_new(NULL); | |
337 gtk_scale_set_draw_value(GTK_SCALE(slider), FALSE); | |
338 /* TODO: make this configureable */ | |
339 gtk_range_set_update_policy(GTK_RANGE(slider), GTK_UPDATE_DISCONTINUOUS); | |
340 gtk_box_pack_start(GTK_BOX(shbox), slider, TRUE, TRUE, 0); | |
341 | |
342 label_time = gtk_markup_label_new(NULL); | |
343 gtk_box_pack_start(GTK_BOX(shbox), label_time, FALSE, FALSE, 0); | |
344 | |
345 treeview = ui_playlist_widget_new(); | |
346 scrollwin = gtk_scrolled_window_new(NULL, NULL); | |
347 gtk_container_add(GTK_CONTAINER(scrollwin), treeview); | |
348 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), | |
349 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); | |
350 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwin), | |
351 GTK_SHADOW_IN); | |
352 | |
353 gtk_box_pack_end(GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0); | |
354 | |
355 ui_hooks_associate(); | |
356 | |
357 slider_change_handler_id = | |
358 g_signal_connect(slider, "value-changed", | |
359 G_CALLBACK(ui_slider_value_changed_cb), NULL); | |
360 | |
361 g_signal_connect(slider, "change-value", | |
362 G_CALLBACK(ui_slider_change_value_cb), NULL); | |
363 g_signal_connect(slider, "button-press-event", | |
364 G_CALLBACK(ui_slider_button_press_cb), NULL); | |
365 g_signal_connect(slider, "button-release-event", | |
366 G_CALLBACK(ui_slider_button_release_cb), NULL); | |
367 | |
368 ui_playlist_update(playlist_get_active(), NULL); | |
369 | |
370 gtk_widget_show_all(window); | |
371 | |
372 ui_clear_song_info(); | |
373 | |
374 gtk_main(); | |
375 | |
376 return TRUE; | |
377 } | |
378 | |
379 static gboolean | |
380 _ui_finalize(void) | |
381 { | |
382 ui_hooks_disassociate(); | |
383 return TRUE; | |
384 } | |
385 | |
386 static Interface default_interface = { | |
387 .id = "default", | |
388 .desc = N_("Default Interface"), | |
389 .init = _ui_initialize, | |
390 .fini = _ui_finalize, | |
391 }; | |
392 | |
393 Interface * | |
394 ui_populate_default_interface(void) | |
395 { | |
396 interface_register(&default_interface); | |
397 | |
398 return &default_interface; | |
399 } |