diff options
| author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2014-03-24 22:22:49 +0100 |
|---|---|---|
| committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2014-03-24 22:30:18 +0100 |
| commit | ed5035680eb2d364734463b2a08c4ea45fe2f30c (patch) | |
| tree | a930245581641c126b5310bd848947d9ae568250 /shell | |
| parent | d04d8be6be1bff80191e1f2ef9d4b500b8015e7d (diff) | |
| download | graynard-ed5035680eb2d364734463b2a08c4ea45fe2f30c.tar.gz graynard-ed5035680eb2d364734463b2a08c4ea45fe2f30c.zip | |
panel,clock: implement setting volume by showing a scale over the clock
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/clock.c | 132 | ||||
| -rw-r--r-- | shell/clock.h | 3 | ||||
| -rw-r--r-- | shell/gtk-shell.c | 35 | ||||
| -rw-r--r-- | shell/panel.c | 84 | ||||
| -rw-r--r-- | shell/panel.h | 5 | ||||
| -rw-r--r-- | shell/style.css | 2 |
6 files changed, 252 insertions, 9 deletions
diff --git a/shell/clock.c b/shell/clock.c index 8f75451..c649931 100644 --- a/shell/clock.c +++ b/shell/clock.c @@ -26,9 +26,21 @@ #define GNOME_DESKTOP_USE_UNSTABLE_API #include <libgnome-desktop/gnome-wall-clock.h> +enum { + VOLUME_CHANGED, + N_SIGNALS +}; +static guint signals[N_SIGNALS] = { 0 }; + struct MaynardClockPrivate { + GtkWidget *revealer_clock; + GtkWidget *revealer_volume; + GtkWidget *label; + GtkWidget *volume_scale; + GtkWidget *volume_image; + GnomeWallClock *wall_clock; }; @@ -43,6 +55,76 @@ maynard_clock_init (MaynardClock *self) } static void +volume_changed_cb (GtkRange *range, + MaynardClock *self) +{ + GError *error = NULL; + gdouble value; + gchar *cmd; + const gchar *icon_name; + GtkWidget *box; + + value = gtk_range_get_value (range); + + cmd = g_strdup_printf ("amixer set PCM %d%%", (int) value); + + g_spawn_command_line_async (cmd, &error); + + if (error) + { + g_print ("failed to set volume: %s\n", error->message); + g_clear_error (&error); + } + + g_free (cmd); + + /* update the icon */ + if (value > 75) + icon_name = "audio-volume-high-symbolic"; + else if (value > 50) + icon_name = "audio-volume-medium-symbolic"; + else if (value > 25) + icon_name = "audio-volume-low-symbolic"; + else if (value == 0) + icon_name = "audio-volume-muted-symbolic"; + + box = gtk_widget_get_parent (self->priv->volume_image); + gtk_widget_destroy (self->priv->volume_image); + self->priv->volume_image = gtk_image_new_from_icon_name ( + icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_box_pack_start (GTK_BOX (box), self->priv->volume_image, + FALSE, FALSE, 0); + gtk_widget_show (self->priv->volume_image); + + g_signal_emit (self, signals[VOLUME_CHANGED], 0, value, icon_name); +} + +static GtkWidget * +create_volume_box (MaynardClock *self) +{ + GtkWidget *box; + + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + self->priv->volume_image = gtk_image_new_from_icon_name ( + "audio-volume-high-symbolic", + GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_box_pack_start (GTK_BOX (box), self->priv->volume_image, + FALSE, FALSE, 0); + + self->priv->volume_scale = gtk_scale_new_with_range ( + GTK_ORIENTATION_HORIZONTAL, 0, 100, 1); + gtk_scale_set_draw_value (GTK_SCALE (self->priv->volume_scale), FALSE); + gtk_widget_set_size_request (self->priv->volume_scale, 100, -1); + gtk_box_pack_end (GTK_BOX (box), self->priv->volume_scale, TRUE, TRUE, 0); + + g_signal_connect (self->priv->volume_scale, "value-changed", + G_CALLBACK (volume_changed_cb), self); + + return box; +} + +static void wall_clock_notify_cb (GnomeWallClock *wall_clock, GParamSpec *pspec, MaynardClock *self) @@ -65,6 +147,7 @@ static void maynard_clock_constructed (GObject *object) { MaynardClock *self = MAYNARD_CLOCK (object); + GtkWidget *box, *volume_box; G_OBJECT_CLASS (maynard_clock_parent_class)->constructed (object); @@ -80,9 +163,38 @@ maynard_clock_constructed (GObject *object) gtk_widget_get_style_context (GTK_WIDGET (self)), "maynard-clock"); + /* the box for the revealers */ + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_container_add (GTK_CONTAINER (self), box); + + /* volume */ + self->priv->revealer_volume = gtk_revealer_new (); + gtk_revealer_set_transition_type ( + GTK_REVEALER (self->priv->revealer_volume), + GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); + gtk_revealer_set_reveal_child ( + GTK_REVEALER (self->priv->revealer_volume), FALSE); + gtk_box_pack_start (GTK_BOX (box), self->priv->revealer_volume, + TRUE, TRUE, 0); + + volume_box = create_volume_box (self); + gtk_container_add (GTK_CONTAINER (self->priv->revealer_volume), + volume_box); + + /* clock */ + self->priv->revealer_clock = gtk_revealer_new (); + gtk_revealer_set_transition_type ( + GTK_REVEALER (self->priv->revealer_clock), + GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT); + gtk_revealer_set_reveal_child ( + GTK_REVEALER (self->priv->revealer_clock), TRUE); + gtk_box_pack_start (GTK_BOX (box), self->priv->revealer_clock, + TRUE, TRUE, 0); + self->priv->label = gtk_label_new (""); gtk_label_set_justify (GTK_LABEL (self->priv->label), GTK_JUSTIFY_CENTER); - gtk_container_add (GTK_CONTAINER (self), self->priv->label); + gtk_container_add (GTK_CONTAINER (self->priv->revealer_clock), + self->priv->label); wall_clock_notify_cb (self->priv->wall_clock, NULL, self); } @@ -92,9 +204,7 @@ maynard_clock_dispose (GObject *object) { MaynardClock *self = MAYNARD_CLOCK (object); - if (self->priv->wall_clock) - g_object_unref (self->priv->wall_clock); - self->priv->wall_clock = NULL; + g_clear_object (&self->priv->wall_clock); G_OBJECT_CLASS (maynard_clock_parent_class)->dispose (object); } @@ -107,6 +217,10 @@ maynard_clock_class_init (MaynardClockClass *klass) object_class->constructed = maynard_clock_constructed; object_class->dispose = maynard_clock_dispose; + signals[VOLUME_CHANGED] = g_signal_new ("volume-changed", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, + NULL, G_TYPE_NONE, 2, G_TYPE_DOUBLE, G_TYPE_STRING); + g_type_class_add_private (object_class, sizeof (MaynardClockPrivate)); } @@ -116,3 +230,13 @@ maynard_clock_new (void) return g_object_new (MAYNARD_CLOCK_TYPE, NULL); } + +void +maynard_clock_show_volume (MaynardClock *self, + gboolean value) +{ + gtk_revealer_set_reveal_child ( + GTK_REVEALER (self->priv->revealer_volume), value); + gtk_revealer_set_reveal_child ( + GTK_REVEALER (self->priv->revealer_clock), !value); +} diff --git a/shell/clock.h b/shell/clock.h index f21ff17..a0803e8 100644 --- a/shell/clock.h +++ b/shell/clock.h @@ -56,4 +56,7 @@ GType maynard_clock_get_type (void) G_GNUC_CONST; GtkWidget * maynard_clock_new (void); +void maynard_clock_show_volume (MaynardClock *self, + gboolean value); + #endif /* __MAYNARD_CLOCK_H__ */ diff --git a/shell/gtk-shell.c b/shell/gtk-shell.c index 040dbc7..133f3ba 100644 --- a/shell/gtk-shell.c +++ b/shell/gtk-shell.c @@ -67,6 +67,7 @@ struct desktop { guint hide_panel_idle_id; gboolean grid_visible; + gboolean volume_visible; }; static gboolean panel_window_enter_cb (GtkWidget *widget, @@ -213,6 +214,16 @@ launcher_grid_create (struct desktop *desktop) desktop->launcher_grid = launcher_grid; } +static void +volume_changed_cb (MaynardClock *clock, + gdouble value, + const gchar *icon_name, + struct desktop *desktop) +{ + maynard_panel_set_volume_icon_name ( + MAYNARD_PANEL (desktop->panel->window), icon_name); +} + static GtkWidget * clock_create (struct desktop *desktop) { @@ -224,6 +235,9 @@ clock_create (struct desktop *desktop) clock->window = maynard_clock_new(); + g_signal_connect (clock->window, "volume-changed", + G_CALLBACK (volume_changed_cb), desktop); + gdk_window = gtk_widget_get_window(clock->window); clock->surface = gdk_wayland_window_get_wl_surface(gdk_window); @@ -232,6 +246,18 @@ clock_create (struct desktop *desktop) desktop->clock = clock; } +static void +volume_toggled_cb (GtkWidget *widget, + struct desktop *desktop) +{ + desktop->volume_visible = !desktop->volume_visible; + + maynard_clock_show_volume (MAYNARD_CLOCK (desktop->clock->window), + desktop->volume_visible); + maynard_panel_show_volume_previous (MAYNARD_PANEL (desktop->panel->window), + desktop->volume_visible); +} + static gboolean panel_window_enter_cb (GtkWidget *widget, GdkEventCrossing *event, @@ -278,7 +304,11 @@ leave_panel_idle_cb (gpointer data) MAYNARD_VERTICAL_CLOCK_WIDTH - MAYNARD_PANEL_WIDTH - width, 0); maynard_panel_set_expand(MAYNARD_PANEL(desktop->panel->window), - FALSE); + FALSE); + + maynard_clock_show_volume (MAYNARD_CLOCK (desktop->clock->window), FALSE); + maynard_panel_show_volume_previous (MAYNARD_PANEL (desktop->panel->window), FALSE); + desktop->volume_visible = FALSE; return FALSE; } @@ -325,6 +355,8 @@ panel_create(struct desktop *desktop) g_signal_connect(panel->window, "app-menu-toggled", G_CALLBACK(launcher_grid_toggle), desktop); + g_signal_connect(panel->window, "volume-toggled", + G_CALLBACK(volume_toggled_cb), desktop); desktop->initial_panel_timeout_id = g_timeout_add_seconds(2, panel_hide_timeout_cb, desktop); @@ -495,6 +527,7 @@ main(int argc, char *argv[]) wl_display_roundtrip (desktop->display); desktop->grid_visible = FALSE; + desktop->volume_visible = FALSE; css_setup(desktop); panel_create(desktop); diff --git a/shell/panel.c b/shell/panel.c index 95c287b..4b9605a 100644 --- a/shell/panel.c +++ b/shell/panel.c @@ -29,6 +29,7 @@ enum { APP_MENU_TOGGLED, + VOLUME_TOGGLED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0 }; @@ -38,6 +39,10 @@ struct MaynardPanelPrivate { GtkWidget *revealer_buttons; /* for the top buttons */ GtkWidget *revealer_clock; /* for the vertical clock */ + + gboolean volume_showing; + GtkWidget *volume_button; + gchar *volume_icon_name; }; G_DEFINE_TYPE(MaynardPanel, maynard_panel, GTK_TYPE_WINDOW) @@ -48,6 +53,8 @@ maynard_panel_init (MaynardPanel *self) self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MAYNARD_PANEL_TYPE, MaynardPanelPrivate); + + self->priv->volume_icon_name = g_strdup ("audio-volume-high-symbolic"); } static gboolean @@ -74,6 +81,13 @@ app_menu_button_clicked_cb (GtkButton *button, } static void +volume_button_clicked_cb (GtkButton *button, + MaynardPanel *self) +{ + g_signal_emit (self, signals[VOLUME_TOGGLED], 0); +} + +static void maynard_panel_constructed (GObject *object) { MaynardPanel *self = MAYNARD_PANEL (object); @@ -138,11 +152,21 @@ maynard_panel_constructed (GObject *object) gtk_box_pack_start (GTK_BOX (buttons_box), image, FALSE, FALSE, 0); /* sound button */ - image = gtk_image_new_from_icon_name ("audio-volume-high-symbolic", + ebox = gtk_event_box_new (); + gtk_box_pack_end (GTK_BOX (buttons_box), ebox, FALSE, FALSE, 0); + button = gtk_button_new_from_icon_name (self->priv->volume_icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); - gtk_style_context_add_class (gtk_widget_get_style_context (image), + gtk_style_context_add_class (gtk_widget_get_style_context (button), "maynard-audio"); - gtk_box_pack_start (GTK_BOX (buttons_box), image, FALSE, FALSE, 0); + gtk_style_context_remove_class (gtk_widget_get_style_context (button), + "button"); + gtk_style_context_remove_class (gtk_widget_get_style_context (button), + "image-button"); + g_signal_connect (button, "clicked", + G_CALLBACK (volume_button_clicked_cb), self); + gtk_container_add (GTK_CONTAINER (ebox), button); + widget_connect_enter_signal (self, ebox); + self->priv->volume_button = button; /* revealer for the vertical clock */ self->priv->revealer_clock = gtk_revealer_new (); @@ -176,6 +200,18 @@ maynard_panel_constructed (GObject *object) /* done */ self->priv->hidden = FALSE; + self->priv->volume_showing = TRUE; +} + +static void +maynard_panel_dispose (GObject *object) +{ + MaynardPanel *self = MAYNARD_PANEL (object); + + g_free (self->priv->volume_icon_name); + self->priv->volume_icon_name = NULL; + + G_OBJECT_CLASS (maynard_panel_parent_class)->dispose (object); } static void @@ -185,11 +221,16 @@ maynard_panel_class_init (MaynardPanelClass *klass) GParamSpec *param_spec; object_class->constructed = maynard_panel_constructed; + object_class->dispose = maynard_panel_dispose; signals[APP_MENU_TOGGLED] = g_signal_new ("app-menu-toggled", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[VOLUME_TOGGLED] = g_signal_new ("volume-toggled", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, + NULL, G_TYPE_NONE, 0); + g_type_class_add_private (object_class, sizeof (MaynardPanelPrivate)); } @@ -207,3 +248,40 @@ maynard_panel_set_expand (MaynardPanel *self, gtk_revealer_set_reveal_child (GTK_REVEALER (self->priv->revealer_buttons), expand); gtk_revealer_set_reveal_child (GTK_REVEALER (self->priv->revealer_clock), !expand); } + +static void +set_volume_icon (MaynardPanel *self, + const gchar *icon_name) +{ + GtkWidget *image; + + image = gtk_image_new_from_icon_name (icon_name, + GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_button_set_image (GTK_BUTTON (self->priv->volume_button), + image); +} + +void +maynard_panel_show_volume_previous (MaynardPanel *self, + gboolean status) +{ + const gchar *icon_name = self->priv->volume_icon_name; + + if (status) + icon_name = "go-previous-symbolic"; + + self->priv->volume_showing = !status; + + set_volume_icon (self, icon_name); +} + +void +maynard_panel_set_volume_icon_name (MaynardPanel *self, + const gchar *icon_name) +{ + g_free (self->priv->volume_icon_name); + self->priv->volume_icon_name = g_strdup (icon_name); + + if (self->priv->volume_showing) + set_volume_icon (self, icon_name); +} diff --git a/shell/panel.h b/shell/panel.h index 861f509..5278e89 100644 --- a/shell/panel.h +++ b/shell/panel.h @@ -56,4 +56,9 @@ GtkWidget * maynard_panel_new (void); void maynard_panel_set_expand (MaynardPanel *self, gboolean expand); +void maynard_panel_show_volume_previous (MaynardPanel *self, gboolean status); + +void maynard_panel_set_volume_icon_name (MaynardPanel *self, + const gchar *icon_name); + #endif /* __MAYNARD_PANEL_H__ */ diff --git a/shell/style.css b/shell/style.css index 477a4f2..4c2088c 100644 --- a/shell/style.css +++ b/shell/style.css @@ -11,7 +11,7 @@ .maynard-audio { background-color: #b4b4b4; color: white; - padding: 16px; + padding: 13px; } .maynard-apps { |
