Merge lp:~cjcurran/indicator-sound/keyboard-ui-controls into lp:indicator-sound/0.1

Proposed by Conor Curran
Status: Merged
Merged at revision: not available
Proposed branch: lp:~cjcurran/indicator-sound/keyboard-ui-controls
Merge into: lp:indicator-sound/0.1
Diff against target: 312 lines (+125/-49)
4 files modified
src/indicator-sound.c (+112/-29)
src/pulse-manager.c (+10/-17)
src/sound-service-dbus.c (+1/-1)
src/sound-service.c (+2/-2)
To merge this branch: bzr merge lp:~cjcurran/indicator-sound/keyboard-ui-controls
Reviewer Review Type Date Requested Status
David Barth Approve
Review via email: mp+19430@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Conor Curran (cjcurran) wrote :

In this branch:

Keyboard controls of the sound menu.
 - +/- 5% inc/dec
 - Arrow left/right 5% inc/dec
 - Ctlr left arrow - volume 0
 - Ctlr right arrow - Max vol

New slider.

volume control far smoother - proper use of the API for the current UI spec.

New icons now being pulled in.

Revision history for this message
David Barth (dbarth) wrote :

LGTM, improvements and simplifications. Caution with the GtkRange cast.

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/indicator-sound.c'
--- src/indicator-sound.c 2010-02-15 15:23:54 +0000
+++ src/indicator-sound.c 2010-02-16 18:00:37 +0000
@@ -20,10 +20,11 @@
20You should have received a copy of the GNU General Public License along 20You should have received a copy of the GNU General Public License along
21with this program. If not, see <http://www.gnu.org/licenses/>.21with this program. If not, see <http://www.gnu.org/licenses/>.
22*/22*/
2323#include <math.h>
24#include <glib.h>24#include <glib.h>
25#include <glib-object.h>25#include <glib-object.h>
26#include <gtk/gtk.h>26#include <gtk/gtk.h>
27#include <gdk/gdkkeysyms.h>
27#include <libdbusmenu-gtk/menu.h>28#include <libdbusmenu-gtk/menu.h>
28#include <libido/idoscalemenuitem.h>29#include <libido/idoscalemenuitem.h>
2930
@@ -83,6 +84,7 @@
83static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget);84static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget);
84static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data);85static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data);
85static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data);86static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data);
87static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data);
8688
87// DBUS communication89// DBUS communication
88static DBusGProxy *sound_dbus_proxy = NULL;90static DBusGProxy *sound_dbus_proxy = NULL;
@@ -162,14 +164,13 @@
162{164{
163 // TODO we need three more images165 // TODO we need three more images
164 volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);166 volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
165 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted"));167 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel"));
166 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup(/*"audio-volume-zero"*/"audio-volume-muted"));168 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-zero-panel"));
167 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low"));169 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel"));
168 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium"));170 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel"));
169 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high"));171 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel"));
170 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup(/*"audio-volume-muted-blocking"*/"audio-volume-muted"));172 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel"));
171 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup(/*"audio-output-none"*/"audio-volume-muted"));173 g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel"));
172 //test_images_hash();
173}174}
174175
175static void176static void
@@ -257,10 +258,20 @@
257258
258static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata)259static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata)
259{260{
260 g_debug("signal caught - update sink volume with value : %f", volume_percent);
261 GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);261 GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);
262 GtkRange *range = (GtkRange*)slider; 262 GtkRange *range = (GtkRange*)slider;
263 gtk_range_set_value(range, volume_percent); 263
264 // DEBUG
265 gdouble current_value = gtk_range_get_value(range);
266 g_debug("SIGNAL- update sink volume - current_value : %f and new value : %f", current_value, volume_percent);
267
268 // Don't like this solution - too fuzzy
269 // Need the ability to detect if the slider is grabbed
270 if(floor(current_value) != floor(volume_percent))
271 {
272 g_debug("Going to update slider value");
273 gtk_range_set_value(range, volume_percent);
274 }
264 determine_state_from_volume(volume_percent);275 determine_state_from_volume(volume_percent);
265}276}
266277
@@ -315,11 +326,11 @@
315326
316static void update_state(const gint state)327static void update_state(const gint state)
317{328{
318 g_debug("update state beginning - previous_state = %i", previous_state);329/* g_debug("update state beginning - previous_state = %i", previous_state);*/
319330
320 previous_state = current_state;331 previous_state = current_state;
321332
322 g_debug("update state 3rd line - previous_state = %i", previous_state);333/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/
323334
324 current_state = state;335 current_state = state;
325 gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));336 gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));
@@ -338,7 +349,7 @@
338349
339static void determine_state_from_volume(gdouble volume_percent)350static void determine_state_from_volume(gdouble volume_percent)
340{351{
341 g_debug("determine_state_from_volume - previous_state = %i", previous_state);352/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/
342 gint state = previous_state;353 gint state = previous_state;
343 if (volume_percent < 30.0 && volume_percent > 0){354 if (volume_percent < 30.0 && volume_percent > 0){
344 state = STATE_LOW;355 state = STATE_LOW;
@@ -366,6 +377,9 @@
366 DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); 377 DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu);
367 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);378 dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item);
368379
380 // register Key-press listening on the widget
381 g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL);
382
369 return GTK_MENU(menu);383 return GTK_MENU(menu);
370}384}
371385
@@ -378,22 +392,23 @@
378 g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL);392 g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL);
379393
380 GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider);394 GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider);
395
381 dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent);396 dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent);
382 g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);397 g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);
383 398
399 // register slider changes listening on the range
384 GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); 400 GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);
385 g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); 401 g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem);
386 g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); 402 g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem);
387 403
404 // Set images on the ido
388 primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); 405 primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider);
389 gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU);406 gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU);
390 GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); 407 GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider);
391 gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU);408 gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU);
392409
393/* GtkRange* range = (GtkRange*)slider; */
394/* gtk_range_set_value(range, initial_volume_percent); */
395
396 gtk_widget_show_all(volume_slider);410 gtk_widget_show_all(volume_slider);
411
397 return TRUE;412 return TRUE;
398}413}
399414
@@ -417,18 +432,86 @@
417static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data)432static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data)
418{433{
419 gdouble current_value = gtk_range_get_value(range); 434 gdouble current_value = gtk_range_get_value(range);
420 if(current_value == 0 || current_value == 100)435/* if(current_value == 0 || current_value == 100)*/
421 {436/* {*/
422 DbusmenuMenuitem *item = (DbusmenuMenuitem*)user_data;437 DbusmenuMenuitem *item = (DbusmenuMenuitem*)user_data;
423 GValue value = {0};438 GValue value = {0};
424 g_value_init(&value, G_TYPE_DOUBLE);439 g_value_init(&value, G_TYPE_DOUBLE);
425 g_value_set_double(&value, current_value);440 g_value_set_double(&value, current_value);
426 g_debug("Value changed listener - = %f", current_value);441 g_debug("Value changed callback - = %f", current_value);
427 dbusmenu_menuitem_handle_event (item, "slider_change", &value, 0); 442 dbusmenu_menuitem_handle_event (item, "slider_change", &value, 0);
428 }443/* }*/
429 return FALSE;444 return FALSE;
430}445}
431446
447/**
448key_press_cb:
449**/
450static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data)
451{
452
453 if(event->length > 0)
454 g_debug("The key event's string is '%s'\n", event->string);
455
456 GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);
457 GtkRange* range = (GtkRange*)slider;
458 gdouble current_value = gtk_range_get_value(range);
459 gdouble new_value = current_value;
460 const gdouble five_percent = 5;
461
462 switch(event->keyval)
463 {
464 case GDK_Right:
465 if(event->state & GDK_CONTROL_MASK)
466 {
467/* g_debug("right key was pressed with ctrl- volume set to 100"); */
468 new_value = 100;
469 }
470 else
471 {
472/* g_debug("right key was pressed - normal 5 percent increase"); */
473 new_value = current_value + five_percent;
474 }
475 break;
476 case GDK_Left:
477 if(event->state & GDK_CONTROL_MASK)
478 {
479/* g_debug("left key was pressed with ctrl- volume set to 0"); */
480 new_value = 0;
481 }
482 else
483 {
484/* g_debug("left key was pressed - normal 5 percent decrease"); */
485 new_value = current_value - five_percent;
486 }
487 break;
488 case GDK_plus:
489/* g_debug("Plus key was pressed");*/
490 new_value = current_value + five_percent;
491 break;
492 case GDK_minus:
493/* g_debug("minus key was pressed");*/
494 new_value = current_value - five_percent;
495 break;
496 default:
497 break;
498 }
499
500/* g_debug("new range value without being clamped = %f", new_value); */
501
502 new_value = CLAMP(new_value, 0, 100);
503 if(new_value != current_value)
504 {
505 g_debug("Attempting to set the range to %f", new_value);
506 gtk_range_set_value(range, new_value);
507 }
508 return FALSE;
509}
510
511/**
512This callback should only be called when the user actually drags the slider.
513Turned off for now in favour of the non descriminating call back.
514**/
432static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data)515static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data)
433{516{
434 DbusmenuMenuitem *item = (DbusmenuMenuitem*)user_data;517 DbusmenuMenuitem *item = (DbusmenuMenuitem*)user_data;
435518
=== modified file 'src/pulse-manager.c'
--- src/pulse-manager.c 2010-02-15 12:42:08 +0000
+++ src/pulse-manager.c 2010-02-16 18:00:37 +0000
@@ -189,18 +189,15 @@
189 g_warning("We have no default sink !!! - returning after not attempting to set any volume of any sink");189 g_warning("We have no default sink !!! - returning after not attempting to set any volume of any sink");
190 return;190 return;
191 }191 }
192 gdouble linear_input = (gdouble)(percent);192
193 linear_input /= 100.0;193 sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX));
194 g_debug("linear double input = %f", linear_input);194
195 pa_volume_t new_volume = pa_sw_volume_from_linear(linear_input); 195 pa_volume_t new_volume = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100);
196 // Use this to achieve more accurate scaling using the base volume (in the sink struct already!)196 g_debug("new_volume double check :%f", pa_sw_volume_to_linear(new_volume));
197 //pa_volume_t new_volume = (pa_volume_t) ((GPOINTER_TO_INT(linear_input) * s->base_volume) / 100);197 g_debug("new volume calculated :%f", (gdouble)new_volume);
198 g_debug("about to try to set the sw volume to a linear volume of %f", pa_sw_volume_to_linear(new_volume));
199 g_debug("and an actual volume of %f", (gdouble)new_volume);
200 pa_cvolume dev_vol;198 pa_cvolume dev_vol;
201 sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX));
202 pa_cvolume_set(&dev_vol, s->volume.channels, new_volume); 199 pa_cvolume_set(&dev_vol, s->volume.channels, new_volume);
203 200 // TODO why don't you update the sink_info here with the appropriate pa_cvolume (&dev_vol)
204 pa_operation_unref(pa_context_set_sink_volume_by_index(pulse_context, DEFAULT_SINK_INDEX, &dev_vol, NULL, NULL));201 pa_operation_unref(pa_context_set_sink_volume_by_index(pulse_context, DEFAULT_SINK_INDEX, &dev_vol, NULL, NULL));
205}202}
206203
@@ -321,7 +318,6 @@
321 if(position >= 0) // => index is within the keys of the hash.318 if(position >= 0) // => index is within the keys of the hash.
322 {319 {
323 sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(info->index));320 sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(info->index));
324 //g_debug("attempting to update sink with name %s", s->name);
325 s->name = g_strdup(info->name);321 s->name = g_strdup(info->name);
326 s->description = g_strdup(info->description);322 s->description = g_strdup(info->description);
327 s->icon_name = g_strdup(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_ICON_NAME));323 s->icon_name = g_strdup(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_ICON_NAME));
@@ -336,14 +332,11 @@
336 {332 {
337 //update the UI333 //update the UI
338 pa_volume_t vol = pa_cvolume_avg(&s->volume);334 pa_volume_t vol = pa_cvolume_avg(&s->volume);
339 // Use the base of the device to ensure maximum acceptable levels on the hardware335 gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM;
340 gdouble volume_percent = (vol/s->base_volume) * 100;336 g_debug("Updating volume from PA manager with volume = %f", volume_percent);
341 g_debug("When using base volume => volume = %f", volume_percent);337 sound_service_dbus_update_sink_volume(dbus_service, volume_percent);
342 g_debug("about to update ui with linear volume of %f", pa_sw_volume_to_linear(vol));
343 sound_service_dbus_update_sink_volume(dbus_service, pa_sw_volume_to_linear(vol));
344 if (mute_changed == TRUE) 338 if (mute_changed == TRUE)
345 sound_service_dbus_update_sink_mute(dbus_service, s->mute);339 sound_service_dbus_update_sink_mute(dbus_service, s->mute);
346
347 update_mute_ui(s->mute);340 update_mute_ui(s->mute);
348 }341 }
349 }342 }
350343
=== modified file 'src/sound-service-dbus.c'
--- src/sound-service-dbus.c 2010-02-10 12:45:23 +0000
+++ src/sound-service-dbus.c 2010-02-16 18:00:37 +0000
@@ -194,7 +194,7 @@
194void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume)194void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume)
195{195{
196 SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj);196 SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj);
197 priv->volume_percent = sink_volume * 100; 197 priv->volume_percent = sink_volume;
198198
199 g_debug("Emitting signal: SINK_VOLUME_UPDATE, with sink_volme %f", priv->volume_percent);199 g_debug("Emitting signal: SINK_VOLUME_UPDATE, with sink_volme %f", priv->volume_percent);
200 g_signal_emit(obj,200 g_signal_emit(obj,
201201
=== modified file 'src/sound-service.c'
--- src/sound-service.c 2010-02-10 18:12:23 +0000
+++ src/sound-service.c 2010-02-16 18:00:37 +0000
@@ -124,8 +124,8 @@
124 if (mainloop != NULL) {124 if (mainloop != NULL) {
125 g_debug("Service shutdown !");125 g_debug("Service shutdown !");
126 // TODO: uncomment for release !!126 // TODO: uncomment for release !!
127 close_pulse_activites();127/* close_pulse_activites();*/
128 g_main_loop_quit(mainloop);128/* g_main_loop_quit(mainloop);*/
129 }129 }
130 return;130 return;
131}131}

Subscribers

People subscribed via source and target branches