Fix volume button
[gmpc.git] / src / GUI / control_window.c
blobbda20bb65671f35009271e08941850a0c9498f37
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <gtk/gtk.h>
20 #include "control_window.h"
21 #include "gmpc-extras.h"
22 #include "main.h"
24 /**
25 * Reuse code from playlist3.
27 extern GtkBuilder *pl3_xml;
28 gboolean playlist_player_volume_changed(GtkWidget * vol_but, double new_vol);
29 void pl3_pb_seek_event(GtkWidget * pb, guint seek_time, gpointer user_data);
31 /**
32 * Draw background of control box.
34 static gboolean
35 expose_window(GtkWidget *widget, cairo_t *cr, gpointer date)
37 GtkAllocation allocation;
38 gtk_widget_get_allocation(widget, &allocation);
39 /* Paint background */
40 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, .7);
41 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
42 cairo_paint(cr); /* paint source */
44 /* Paint border */
45 cairo_set_source_rgba(cr, .8, .8, .8, .7);
46 cairo_rectangle(cr, 0.5,0.5,
47 allocation.width-1.0,
48 allocation.height-1.0);
49 cairo_stroke(cr);
51 return FALSE;
55 /**
56 * change the colors recursively.
57 * Background black, text/fg white.
59 static void control_window_modify_colors(GtkWidget *base)
61 GList *iter;
62 if(GTK_IS_HSCALE(base) == FALSE)
64 /* TODO:
65 gtk_widget_modify_bg(base,
66 GTK_STATE_NORMAL,&(base->style->black));
67 gtk_widget_modify_fg(base,
68 GTK_STATE_NORMAL,&(base->style->white));
69 gtk_widget_modify_text(base,
70 GTK_STATE_NORMAL,&(base->style->white));
73 if(GTK_IS_CONTAINER(base))
75 for (iter = gtk_container_get_children(GTK_CONTAINER(base));
76 iter != NULL;
77 iter = g_list_next(iter))
79 control_window_modify_colors(iter->data);
85 /**
86 * Leave fullscreen
88 static void control_window_leave_fullscreen(GtkWidget *button, GtkWidget *parent)
90 gtk_window_unfullscreen(GTK_WINDOW(parent));
93 /**
94 * Hiding code
96 static guint timeout = 0;
97 static gboolean control_window_leave_notify_event(GtkWidget *base,
98 GdkEventCrossing *ev, gpointer data)
100 GtkWidget *hbox = (GtkWidget *)g_object_get_data(G_OBJECT(base), "hbox");
101 if(timeout > 0) {
102 g_source_remove(timeout);
103 timeout = 0;
105 timeout = g_timeout_add_seconds(5, (GSourceFunc) gtk_widget_hide, hbox);
106 return TRUE;
108 static gboolean control_window_enter_notify_event(GtkWidget *base,
109 GdkEventCrossing *ev, gpointer data)
111 GtkWidget *hbox = (GtkWidget *)g_object_get_data(G_OBJECT(base), "hbox");
112 if(timeout > 0) {
113 g_source_remove(timeout);
114 timeout = 0;
116 gtk_widget_show(hbox);
117 return TRUE;
121 * Constructor
123 GtkWidget *create_control_window(GtkWidget *parent)
125 GtkWidget *pp_button, *next_button, *prev_button, *ff_button;
126 GtkWidget *vol, *progress, *hbox, *play_image;
127 int new_volume;
128 /* Create window */
129 GtkWidget *base = gtk_event_box_new();
130 GtkWidget *ali = gtk_alignment_new(0.5,0,0.6,1);
131 g_signal_connect(G_OBJECT(base), "enter-notify-event" ,
132 G_CALLBACK(control_window_enter_notify_event), NULL);
133 g_signal_connect(G_OBJECT(base), "leave-notify-event" ,
134 G_CALLBACK(control_window_leave_notify_event), NULL);
135 /* Overwrite background drawing */
136 gtk_widget_set_app_paintable(base, TRUE);
137 g_signal_connect(G_OBJECT(base), "draw",
138 G_CALLBACK(expose_window), NULL);
140 hbox = gtk_hbox_new(FALSE, 6);
141 g_object_set_data(G_OBJECT(base), "hbox" , hbox);
142 gtk_container_add(GTK_CONTAINER(base), ali);
143 gtk_container_add(GTK_CONTAINER(ali), hbox);
144 gtk_container_set_border_width(GTK_CONTAINER(ali), 1);
146 /* Previous button */
147 ff_button = gtk_button_new();
148 gtk_container_add(GTK_CONTAINER(ff_button),
149 gtk_image_new_from_stock(GTK_STOCK_LEAVE_FULLSCREEN,
150 GTK_ICON_SIZE_BUTTON));
151 gtk_button_set_relief(GTK_BUTTON(ff_button), GTK_RELIEF_NONE);
152 gtk_box_pack_start(GTK_BOX(hbox), ff_button, FALSE, FALSE, 0);
153 g_signal_connect(G_OBJECT(ff_button), "clicked",
154 G_CALLBACK(control_window_leave_fullscreen), parent);
155 /* Volume button */
156 vol = (GtkWidget *)gtk_volume_button_new();
157 gtk_box_pack_end(GTK_BOX(hbox), vol, FALSE, FALSE, 0);
158 new_volume = mpd_status_get_volume(connection);
159 gtk_scale_button_set_value(GTK_SCALE_BUTTON(vol), new_volume/100.0);
160 g_object_set_data(G_OBJECT(base), "vol", vol);
161 g_signal_connect(G_OBJECT(vol), "value_changed",
162 G_CALLBACK(playlist_player_volume_changed), NULL);
163 /* Progress */
164 progress = (GtkWidget *)gmpc_progress_new();
165 gmpc_progress_set_hide_text(GMPC_PROGRESS(progress), FALSE);
166 gtk_box_pack_start(GTK_BOX(hbox), progress, TRUE, TRUE, 0);
167 g_object_set_data(G_OBJECT(base), "progress", progress);
168 g_signal_connect(G_OBJECT(progress), "seek-event", G_CALLBACK(pl3_pb_seek_event),
169 NULL);
171 /* Previous button */
172 prev_button = gtk_button_new();
173 gtk_container_add(GTK_CONTAINER(prev_button),
174 gtk_image_new_from_stock("gtk-media-previous", GTK_ICON_SIZE_BUTTON));
175 gtk_activatable_set_related_action(GTK_ACTIVATABLE(prev_button),
176 GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPrevious")));
177 gtk_button_set_relief(GTK_BUTTON(prev_button), GTK_RELIEF_NONE);
178 gtk_box_pack_start(GTK_BOX(hbox), prev_button, FALSE, FALSE, 0);
180 /* Play button */
181 pp_button = gtk_button_new();
182 if(mpd_player_get_state(connection) == MPD_PLAYER_PLAY)
184 play_image = gtk_image_new_from_stock("gtk-media-pause", GTK_ICON_SIZE_BUTTON);
186 else
188 play_image = gtk_image_new_from_stock("gtk-media-play", GTK_ICON_SIZE_BUTTON);
190 gtk_container_add(GTK_CONTAINER(pp_button), play_image);
191 g_object_set_data(G_OBJECT(base), "play_image", play_image);
193 gtk_activatable_set_related_action(GTK_ACTIVATABLE(pp_button),
194 GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDPlayPause")));
195 gtk_button_set_relief(GTK_BUTTON(pp_button), GTK_RELIEF_NONE);
196 gtk_box_pack_start(GTK_BOX(hbox), pp_button, FALSE, FALSE, 0);
198 /* Next */
199 next_button = gtk_button_new();
200 gtk_container_add(GTK_CONTAINER(next_button),
201 gtk_image_new_from_stock("gtk-media-next", GTK_ICON_SIZE_BUTTON));
202 gtk_activatable_set_related_action(GTK_ACTIVATABLE(next_button),
203 GTK_ACTION(gtk_builder_get_object(pl3_xml, "MPDNext")));
204 gtk_button_set_relief(GTK_BUTTON(next_button), GTK_RELIEF_NONE);
205 gtk_box_pack_start(GTK_BOX(hbox), next_button, FALSE, FALSE, 0);
207 /* Change colors */
208 control_window_modify_colors(base);
209 gtk_widget_show_all(base);
211 timeout = g_timeout_add_seconds(5, (GSourceFunc) gtk_widget_hide, hbox);
212 return base;
216 void control_window_status_update(MpdObj * mi, ChangedStatusType what, GtkWidget *base)
218 GtkWidget *volume_button, *progress, *play_image;
219 /* Bail out of base == NULL */
220 if(base == NULL) return;
221 /* Get the different subwidgets from the parent */
222 volume_button = g_object_get_data(G_OBJECT(base), "vol");
223 progress = g_object_get_data(G_OBJECT(base), "progress");
224 play_image = g_object_get_data(G_OBJECT(base), "play_image");
226 if (what & MPD_CST_STATE)
228 int state = mpd_player_get_state(mi);
229 switch (state)
231 case MPD_PLAYER_PLAY:
232 gtk_image_set_from_stock(GTK_IMAGE(play_image),
233 "gtk-media-pause", GTK_ICON_SIZE_BUTTON);
234 break;
235 case MPD_PLAYER_PAUSE:
236 gtk_image_set_from_stock(GTK_IMAGE(play_image),
237 "gtk-media-play", GTK_ICON_SIZE_BUTTON);
238 break;
239 default:
240 gtk_image_set_from_stock(GTK_IMAGE(play_image),
241 "gtk-media-play", GTK_ICON_SIZE_BUTTON);
242 /* Make sure it's reset correctly */
243 gmpc_progress_set_time(GMPC_PROGRESS(progress), 0, 0);
246 if (what & MPD_CST_ELAPSED_TIME)
248 if (mpd_check_connected(connection))
250 int totalTime = mpd_status_get_total_song_time(connection);
251 int elapsedTime = mpd_status_get_elapsed_song_time(connection);
252 gmpc_progress_set_time(GMPC_PROGRESS(progress), totalTime, elapsedTime);
253 } else
255 gmpc_progress_set_time(GMPC_PROGRESS(progress), 0, 0);
258 if (what & MPD_CST_VOLUME)
260 int volume = gtk_scale_button_get_value(GTK_SCALE_BUTTON(volume_button))*100;
261 int new_volume = mpd_status_get_volume(connection);
262 if (new_volume >= 0 &&
263 mpd_server_check_command_allowed(connection, "setvol") ==
264 MPD_SERVER_COMMAND_ALLOWED
267 gtk_widget_set_sensitive(volume_button, TRUE);
268 /* don't do anything if nothing is changed */
269 if (new_volume != volume)
271 gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume_button), new_volume/100.0);
273 } else
275 gtk_widget_set_sensitive(volume_button, FALSE);
282 * Destructor
284 void control_window_destroy(GtkWidget *cw)
286 if(cw == NULL) return;
288 if(timeout > 0) {
289 g_source_remove(timeout);
290 timeout = 0;
292 gtk_widget_destroy(cw);