1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2009 Bastien Nocera
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
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28
#include <glib/gi18n-lib.h>
30
#include <canberra-gtk.h>
31
#include <pulse/pulseaudio.h>
33
#include "gvc-combo-box.h"
34
#include "gvc-mixer-stream.h"
35
#include "gvc-mixer-card.h"
37
#define GVC_COMBO_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_COMBO_BOX, GvcComboBoxPrivate))
39
struct GvcComboBoxPrivate
49
GtkSizeGroup *size_group;
72
static guint signals [LAST_SIGNAL] = { 0, };
74
static void gvc_combo_box_class_init (GvcComboBoxClass *klass);
75
static void gvc_combo_box_init (GvcComboBox *combo_box);
76
static void gvc_combo_box_finalize (GObject *object);
78
G_DEFINE_TYPE (GvcComboBox, gvc_combo_box, GTK_TYPE_HBOX)
81
gvc_combo_box_set_size_group (GvcComboBox *combo_box,
85
g_return_if_fail (GVC_IS_COMBO_BOX (combo_box));
87
combo_box->priv->size_group = group;
88
combo_box->priv->symmetric = symmetric;
90
if (combo_box->priv->size_group != NULL) {
91
gtk_size_group_add_widget (combo_box->priv->size_group,
92
combo_box->priv->start_box);
94
if (combo_box->priv->symmetric) {
95
gtk_size_group_add_widget (combo_box->priv->size_group,
96
combo_box->priv->end_box);
99
gtk_widget_queue_draw (GTK_WIDGET (combo_box));
103
gvc_combo_box_set_property (GObject *object,
108
GvcComboBox *self = GVC_COMBO_BOX (object);
112
gtk_label_set_text_with_mnemonic (GTK_LABEL (self->priv->label), g_value_get_string (value));
114
case PROP_BUTTON_LABEL:
115
gtk_button_set_label (GTK_BUTTON (self->priv->button), g_value_get_string (value));
117
case PROP_SHOW_BUTTON:
118
gtk_widget_set_visible (self->priv->button, g_value_get_boolean (value));
121
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
127
gvc_combo_box_get_property (GObject *object,
132
GvcComboBox *self = GVC_COMBO_BOX (object);
136
g_value_set_string (value,
137
gtk_label_get_text (GTK_LABEL (self->priv->label)));
139
case PROP_BUTTON_LABEL:
140
g_value_set_string (value,
141
gtk_button_get_label (GTK_BUTTON (self->priv->button)));
143
case PROP_SHOW_BUTTON:
144
g_value_set_boolean (value,
145
gtk_widget_get_visible (self->priv->button));
148
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
154
gvc_combo_box_class_init (GvcComboBoxClass *klass)
156
GObjectClass *object_class = G_OBJECT_CLASS (klass);
158
object_class->finalize = gvc_combo_box_finalize;
159
object_class->set_property = gvc_combo_box_set_property;
160
object_class->get_property = gvc_combo_box_get_property;
162
g_object_class_install_property (object_class,
164
g_param_spec_string ("label",
166
"The combo box label",
168
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
169
g_object_class_install_property (object_class,
171
g_param_spec_boolean ("show-button",
173
"Whether to show the button",
175
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
176
g_object_class_install_property (object_class,
178
g_param_spec_string ("button-label",
180
"The button's label",
182
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
184
g_signal_new ("changed",
185
G_TYPE_FROM_CLASS (klass),
187
G_STRUCT_OFFSET (GvcComboBoxClass, changed),
189
g_cclosure_marshal_VOID__STRING,
190
G_TYPE_NONE, 1, G_TYPE_STRING);
191
signals [BUTTON_CLICKED] =
192
g_signal_new ("button-clicked",
193
G_TYPE_FROM_CLASS (klass),
195
G_STRUCT_OFFSET (GvcComboBoxClass, button_clicked),
197
g_cclosure_marshal_VOID__VOID,
198
G_TYPE_NONE, 0, G_TYPE_NONE);
200
g_type_class_add_private (klass, sizeof (GvcComboBoxPrivate));
204
gvc_combo_box_set_profiles (GvcComboBox *combo_box,
205
const GList *profiles)
209
g_return_if_fail (GVC_IS_COMBO_BOX (combo_box));
210
g_return_if_fail (combo_box->priv->set_called == FALSE);
212
for (l = profiles; l != NULL; l = l->next) {
213
GvcMixerCardProfile *p = l->data;
215
gtk_list_store_insert_with_values (GTK_LIST_STORE (combo_box->priv->model),
218
COL_NAME, p->profile,
219
COL_HUMAN_NAME, p->human_profile,
222
combo_box->priv->set_called = TRUE;
226
gvc_combo_box_set_ports (GvcComboBox *combo_box,
231
g_return_if_fail (GVC_IS_COMBO_BOX (combo_box));
232
g_return_if_fail (combo_box->priv->set_called == FALSE);
234
for (l = ports; l != NULL; l = l->next) {
235
GvcMixerStreamPort *p = l->data;
237
gtk_list_store_insert_with_values (GTK_LIST_STORE (combo_box->priv->model),
241
COL_HUMAN_NAME, p->human_port,
244
combo_box->priv->set_called = TRUE;
248
gvc_combo_box_set_active (GvcComboBox *combo_box,
254
cont = gtk_tree_model_get_iter_first (combo_box->priv->model, &iter);
255
while (cont != FALSE) {
258
gtk_tree_model_get (combo_box->priv->model, &iter,
261
if (g_strcmp0 (name, id) == 0) {
262
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box->priv->combobox), &iter);
265
gtk_tree_model_iter_next (combo_box->priv->model, &iter);
267
g_warning ("Could not find id '%s' in combo box", id);
271
on_combo_box_changed (GtkComboBox *widget,
272
GvcComboBox *combo_box)
277
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter) == FALSE) {
278
g_warning ("Could not find an active profile or port");
282
gtk_tree_model_get (combo_box->priv->model, &iter,
285
g_signal_emit (combo_box, signals[CHANGED], 0, profile);
290
on_combo_box_button_clicked (GtkButton *button,
291
GvcComboBox *combo_box)
293
g_signal_emit (combo_box, signals[BUTTON_CLICKED], 0);
297
gvc_combo_box_init (GvcComboBox *combo_box)
303
GtkCellRenderer *renderer;
305
combo_box->priv = GVC_COMBO_BOX_GET_PRIVATE (combo_box);
307
combo_box->priv->model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLS,
311
combo_box->priv->label = gtk_label_new (NULL);
312
gtk_misc_set_alignment (GTK_MISC (combo_box->priv->label),
317
frame = gtk_frame_new (NULL);
318
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
319
gtk_container_add (GTK_CONTAINER (combo_box), frame);
321
combo_box->priv->drop_box = box = gtk_hbox_new (FALSE, 6);
322
combo_box->priv->combobox = gtk_combo_box_new_with_model (combo_box->priv->model);
323
renderer = gtk_cell_renderer_text_new ();
324
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box->priv->combobox),
326
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo_box->priv->combobox),
328
"text", COL_HUMAN_NAME);
330
/* Make sure that the combo box isn't too wide when human names are overly long,
331
* but that we can still read the full length of it */
332
g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
333
g_object_set (G_OBJECT (combo_box->priv->combobox), "popup-fixed-width", FALSE, NULL);
335
combo_box->priv->start_box = sbox = gtk_hbox_new (FALSE, 6);
336
gtk_box_pack_start (GTK_BOX (box), sbox, FALSE, FALSE, 0);
338
gtk_box_pack_start (GTK_BOX (sbox), combo_box->priv->label, FALSE, FALSE, 0);
340
gtk_box_pack_start (GTK_BOX (box), combo_box->priv->combobox, TRUE, TRUE, 0);
342
combo_box->priv->button = gtk_button_new_with_label ("APPLICATION BUG");
343
gtk_widget_set_no_show_all (combo_box->priv->button, TRUE);
344
gtk_box_pack_start (GTK_BOX (box), combo_box->priv->button, FALSE, FALSE, 0);
347
combo_box->priv->end_box = ebox = gtk_hbox_new (FALSE, 6);
348
gtk_box_pack_start (GTK_BOX (box), ebox, FALSE, FALSE, 0);
350
if (combo_box->priv->size_group != NULL) {
351
gtk_size_group_add_widget (combo_box->priv->size_group, sbox);
353
if (combo_box->priv->symmetric) {
354
gtk_size_group_add_widget (combo_box->priv->size_group, ebox);
358
gtk_container_add (GTK_CONTAINER (frame), combo_box->priv->drop_box);
359
gtk_widget_show_all (frame);
361
gtk_label_set_mnemonic_widget (GTK_LABEL (combo_box->priv->label),
362
combo_box->priv->combobox);
364
g_signal_connect (G_OBJECT (combo_box->priv->combobox), "changed",
365
G_CALLBACK (on_combo_box_changed), combo_box);
366
g_signal_connect (G_OBJECT (combo_box->priv->button), "clicked",
367
G_CALLBACK (on_combo_box_button_clicked), combo_box);
371
gvc_combo_box_finalize (GObject *object)
373
GvcComboBox *combo_box;
375
g_return_if_fail (object != NULL);
376
g_return_if_fail (GVC_IS_COMBO_BOX (object));
378
combo_box = GVC_COMBO_BOX (object);
380
g_return_if_fail (combo_box->priv != NULL);
382
g_object_unref (combo_box->priv->model);
383
combo_box->priv->model = NULL;
385
G_OBJECT_CLASS (gvc_combo_box_parent_class)->finalize (object);
389
gvc_combo_box_new (const char *label)
392
combo_box = g_object_new (GVC_TYPE_COMBO_BOX,
395
return GTK_WIDGET (combo_box);