Commit ed503568 authored by Jonny Lamb's avatar Jonny Lamb
Browse files

panel,clock: implement setting volume by showing a scale over the clock

parent d04d8be6
......@@ -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;
};
......@@ -42,6 +54,76 @@ maynard_clock_init (MaynardClock *self)
MaynardClockPrivate);
}
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,
......@@ -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);
}
......@@ -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__ */
......@@ -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);
......
......@@ -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
......@@ -73,6 +80,13 @@ app_menu_button_clicked_cb (GtkButton *button,
g_signal_emit (self, signals[APP_MENU_TOGGLED], 0);
}
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)
{
......@@ -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);
}
......@@ -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__ */
......@@ -11,7 +11,7 @@
.maynard-audio {
background-color: #b4b4b4;
color: white;
padding: 16px;
padding: 13px;
}
.maynard-apps {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment