X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/812b526d127c6657e571db8b33a58137af6709cd..851bbc586215d48acb7575e784d09d0e0ce559df:/disobedience/control.c diff --git a/disobedience/control.c b/disobedience/control.c index c512059..7d96aa2 100644 --- a/disobedience/control.c +++ b/disobedience/control.c @@ -1,6 +1,6 @@ /* * This file is part of DisOrder. - * Copyright (C) 2006-2008 Richard Kettlewell + * Copyright (C) 2006-2009 Richard Kettlewell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,6 @@ */ #include "disobedience.h" -#include "mixer.h" /* Forward declarations ---------------------------------------------------- */ @@ -52,6 +51,9 @@ static void icon_changed(const char *event, static void volume_changed(const char *event, void *eventdata, void *callbackdata); +static void control_minimode(const char *event, + void *eventdata, + void *callbackdata); /* Control bar ------------------------------------------------------------- */ @@ -70,6 +72,9 @@ int suppress_actions = 1; * (All icons can be sensitive or insensitive, separately to the above.) */ struct icon { + /** @brief True to use GTK+ stock icons instead of filenames */ + gboolean stock; + /** @brief Filename for 'on' image */ const char *icon_on; @@ -79,7 +84,7 @@ struct icon { /** @brief Filename for 'off' image or NULL for an action icon */ const char *icon_off; - /** @brief Text for 'off tooltip */ + /** @brief Text for 'off' tooltip */ const char *tip_off; /** @brief Associated menu item or NULL */ @@ -131,7 +136,8 @@ static int pause_resume_on(void) { } static int pause_resume_sensitive(void) { - return !!(last_state & DISORDER_PLAYING) + return playing_track + && !!(last_state & DISORDER_PLAYING) && (last_rights & RIGHT_PAUSE); } @@ -148,6 +154,7 @@ static int random_enabled(void) { return !!(last_state & DISORDER_RANDOM_ENABLED); } +#if 0 static int playing_sensitive(void) { return !!(last_rights & RIGHT_GLOBAL_PREFS); } @@ -155,6 +162,7 @@ static int playing_sensitive(void) { static int playing_enabled(void) { return !!(last_state & DISORDER_PLAYING_ENABLED); } +#endif static int rtp_enabled(void) { return rtp_is_running; @@ -167,19 +175,21 @@ static int rtp_sensitive(void) { /** @brief Table of all icons */ static struct icon icons[] = { { - icon_on: "pause32.png", + stock: TRUE, + icon_on: GTK_STOCK_MEDIA_PAUSE, tip_on: "Pause playing track", - icon_off: "play32.png", + icon_off: GTK_STOCK_MEDIA_PLAY, tip_off: "Resume playing track", menuitem: "/Control/Playing", on: pause_resume_on, sensitive: pause_resume_sensitive, action_go_on: disorder_eclient_resume, action_go_off: disorder_eclient_pause, - events: "pause-changed playing-changed rights-changed", + events: "pause-changed playing-changed rights-changed playing-track-changed", }, { - icon_on: "cross32.png", + stock: TRUE, + icon_on: GTK_STOCK_STOP, tip_on: "Cancel playing track", menuitem: "/Control/Scratch", sensitive: scratch_sensitive, @@ -187,9 +197,10 @@ static struct icon icons[] = { events: "playing-track-changed rights-changed", }, { - icon_on: "randomenabled32.png", + stock: TRUE, + icon_on: GTK_STOCK_YES, tip_on: "Disable random play", - icon_off: "randomdisabled32.png", + icon_off: GTK_STOCK_NO, tip_off: "Enable random play", menuitem: "/Control/Random play", on: random_enabled, @@ -198,10 +209,12 @@ static struct icon icons[] = { action_go_off: disorder_eclient_random_disable, events: "random-changed rights-changed", }, +#if 0 { - icon_on: "playenabled32.png", + stock: TRUE, + icon_on: GTK_STOCK_YES, tip_on: "Disable play", - icon_off: "playdisabled32.png", + icon_off: GTK_STOCK_NO, tip_off: "Enable play", on: playing_enabled, sensitive: playing_sensitive, @@ -209,10 +222,12 @@ static struct icon icons[] = { action_go_off: disorder_eclient_disable, events: "enabled-changed rights-changed", }, +#endif { - icon_on: "rtpenabled32.png", + stock: TRUE, + icon_on: GTK_STOCK_CONNECT, tip_on: "Stop playing network stream", - icon_off: "rtpdisabled32.png", + icon_off: GTK_STOCK_DISCONNECT, tip_off: "Play network stream", menuitem: "/Control/Network player", on: rtp_enabled, @@ -242,15 +257,27 @@ GtkWidget *control_widget(void) { /* Create the button */ icons[n].button = gtk_button_new(); gtk_widget_set_style(icons[n].button, tool_style); - icons[n].image_on = gtk_image_new_from_pixbuf(find_image(icons[n].icon_on)); - gtk_widget_set_style(icons[n].image_on, tool_style); + if(icons[n].stock) { + /* We'll use the stock icons for this one */ + gtk_button_set_use_stock(GTK_BUTTON(icons[n].button), TRUE); + icons[n].image_on = gtk_image_new_from_stock(icons[n].icon_on, + GTK_ICON_SIZE_LARGE_TOOLBAR); + if(icons[n].icon_off) + icons[n].image_off = gtk_image_new_from_stock(icons[n].icon_off, + GTK_ICON_SIZE_LARGE_TOOLBAR); + } else { + /* Create the 'on' image */ + icons[n].image_on = gtk_image_new_from_pixbuf(find_image(icons[n].icon_on)); + gtk_widget_set_style(icons[n].image_on, tool_style); + /* If it's a toggle icon, create the 'off' half too */ + if(icons[n].icon_off) { + icons[n].image_off = gtk_image_new_from_pixbuf(find_image(icons[n].icon_off)); + gtk_widget_set_style(icons[n].image_off, tool_style); + } + } g_object_ref(icons[n].image_on); - /* If it's a toggle icon, create the 'off' half too */ - if(icons[n].icon_off) { - icons[n].image_off = gtk_image_new_from_pixbuf(find_image(icons[n].icon_off)); - gtk_widget_set_style(icons[n].image_off, tool_style); + if(icons[n].image_off) g_object_ref(icons[n].image_off); - } g_signal_connect(G_OBJECT(icons[n].button), "clicked", G_CALLBACK(clicked_icon), &icons[n]); /* pop the icon in a vbox so it doesn't get vertically stretch if there are @@ -290,8 +317,8 @@ GtkWidget *control_widget(void) { gtk_scale_set_digits(GTK_SCALE(balance_widget), 10); gtk_widget_set_size_request(volume_widget, 192, -1); gtk_widget_set_size_request(balance_widget, 192, -1); - gtk_tooltips_set_tip(tips, volume_widget, "Volume", ""); - gtk_tooltips_set_tip(tips, balance_widget, "Balance", ""); + gtk_widget_set_tooltip_text(volume_widget, "Volume"); + gtk_widget_set_tooltip_text(balance_widget, "Balance"); gtk_box_pack_start(GTK_BOX(hbox), volume_widget, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), balance_widget, FALSE, TRUE, 0); /* space updates rather than hammering the server */ @@ -309,29 +336,31 @@ GtkWidget *control_widget(void) { G_CALLBACK(format_balance), 0); event_register("volume-changed", volume_changed, 0); event_register("rtp-changed", volume_changed, 0); + event_register("mini-mode-changed", control_minimode, 0); return hbox; } +/** @brief Return TRUE if volume setting is supported */ +static int volume_supported(void) { + /* TODO: if the server doesn't know how to set the volume [but isn't using + * network play] then we should have volume_supported = FALSE */ + return (!rtp_supported + || (rtp_supported && backend && backend->set_volume)); +} + /** @brief Update the volume control when it changes */ static void volume_changed(const char attribute((unused)) *event, void attribute((unused)) *eventdata, void attribute((unused)) *callbackdata) { double l, r; - gboolean volume_supported; D(("volume_changed")); ++suppress_actions; /* Only display volume/balance controls if they will work */ - if(!rtp_supported - || (rtp_supported && mixer_supported(DEFAULT_BACKEND))) - volume_supported = TRUE; - else - volume_supported = FALSE; - /* TODO: if the server doesn't know how to set the volume [but isn't using - * network play] then we should have volume_supported = FALSE */ - if(volume_supported) { + if(volume_supported()) { gtk_widget_show(volume_widget); - gtk_widget_show(balance_widget); + if(full_mode) + gtk_widget_show(balance_widget); l = volume_l / 100.0; r = volume_r / 100.0; gtk_adjustment_set_value(volume_adj, volume(l, r) * goesupto); @@ -375,8 +404,8 @@ static void icon_changed(const char attribute((unused)) *event, * state is immediately displayed. sensitive and GTK_WIDGET_SENSITIVE show * it to be in the correct state, so I think this is may be a GTK+ bug. */ if(icon->tip_on) - gtk_tooltips_set_tip(tips, icon->button, - on ? icon->tip_on : icon->tip_off, ""); + gtk_widget_set_tooltip_text(icon->button, + on ? icon->tip_on : icon->tip_off); gtk_widget_set_sensitive(icon->button, sensitive); /* Icons with an associated menu item */ if(icon->item) { @@ -444,7 +473,8 @@ static void volume_adjusted(GtkAdjustment attribute((unused)) *a, * from the log. */ if(rtp_supported) { int l = nearbyint(left(v, b) * 100), r = nearbyint(right(v, b) * 100); - mixer_control(DEFAULT_BACKEND, &l, &r, 1); + if(backend && backend->set_volume) + backend->set_volume(&l, &r); } else disorder_eclient_volume(client, volume_completed, nearbyint(left(v, b) * 100), @@ -559,6 +589,18 @@ static int disable_rtp(disorder_eclient attribute((unused)) *c, return 0; } +static void control_minimode(const char attribute((unused)) *event, + void attribute((unused)) *evendata, + void attribute((unused)) *callbackdata) { + if(full_mode && volume_supported()) { + gtk_widget_show(balance_widget); + gtk_scale_set_value_pos(GTK_SCALE(volume_widget), GTK_POS_TOP); + } else { + gtk_widget_hide(balance_widget); + gtk_scale_set_value_pos(GTK_SCALE(volume_widget), GTK_POS_RIGHT); + } +} + /* Local Variables: c-basic-offset:2