3.12.12
[nijm-empathy.git] / libempathy-gtk / empathy-dialpad-widget.c
blob6c85c7971e6eb58016185afec364a6a844921864
1 /*
2 * Copyright (C) 2011 Collabora Ltd.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301 USA
19 * Authors: Danielle Madeley <danielle.madeley@collabora.co.uk>
22 #include "config.h"
23 #include "empathy-dialpad-widget.h"
25 #include "empathy-dialpad-button.h"
27 G_DEFINE_TYPE (EmpathyDialpadWidget, empathy_dialpad_widget, GTK_TYPE_BOX);
29 enum /* signals */
31 START_TONE,
32 STOP_TONE,
34 NUM_SIGNALS
37 static guint signals[NUM_SIGNALS] = { 0, };
39 struct _EmpathyDialpadWidgetPrivate
41 GtkWidget *entry;
43 /* gchar representing the button (like '7') -> GtkButton */
44 GHashTable *buttons;
47 static void
48 empathy_dialpad_widget_dispose (GObject *object)
50 EmpathyDialpadWidget *self = EMPATHY_DIALPAD_WIDGET (object);
51 void (*chain_up) (GObject *) =
52 ((GObjectClass *) empathy_dialpad_widget_parent_class)->dispose;
54 g_hash_table_unref (self->priv->buttons);
56 if (chain_up != NULL)
57 chain_up (object);
60 static void
61 empathy_dialpad_widget_class_init (EmpathyDialpadWidgetClass *klass)
63 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
65 gobject_class->dispose = empathy_dialpad_widget_dispose;
67 signals[START_TONE] = g_signal_new ("start-tone",
68 G_TYPE_FROM_CLASS (klass),
69 G_SIGNAL_RUN_LAST,
70 0, NULL, NULL,
71 g_cclosure_marshal_generic,
72 G_TYPE_NONE,
73 1, G_TYPE_UINT);
75 signals[STOP_TONE] = g_signal_new ("stop-tone",
76 G_TYPE_FROM_CLASS (klass),
77 G_SIGNAL_RUN_LAST,
78 0, NULL, NULL,
79 g_cclosure_marshal_generic,
80 G_TYPE_NONE,
81 1, G_TYPE_UINT);
83 g_type_class_add_private (gobject_class,
84 sizeof (EmpathyDialpadWidgetPrivate));
87 static gboolean
88 dtmf_dialpad_button_pressed_cb (EmpathyDialpadButton *button,
89 GdkEventButton *event,
90 EmpathyDialpadWidget *self)
92 GtkEntryBuffer *buffer = gtk_entry_get_buffer (GTK_ENTRY (self->priv->entry));
93 TpDTMFEvent tone;
94 const gchar *label;
96 tone = empathy_dialpad_button_get_event (button);
97 label = empathy_dialpad_button_get_label (button);
99 g_signal_emit (self, signals[START_TONE], 0, tone);
101 gtk_entry_buffer_insert_text (buffer, -1, label, -1);
102 gtk_editable_set_position (GTK_EDITABLE (self->priv->entry), -1);
104 return FALSE;
107 static gboolean
108 dtmf_dialpad_button_released_cb (EmpathyDialpadButton *button,
109 GdkEventButton *event,
110 EmpathyDialpadWidget *self)
112 TpDTMFEvent tone;
114 tone = empathy_dialpad_button_get_event (button);
116 g_signal_emit (self, signals[STOP_TONE], 0, tone);
118 return FALSE;
121 static void
122 empathy_dialpad_widget_init (EmpathyDialpadWidget *self)
124 GtkWidget *grid;
125 int i;
127 struct {
128 const gchar *label;
129 const gchar *sublabel;
130 TpDTMFEvent event;
131 } dtmfbuttons[] = { { "1", "", TP_DTMF_EVENT_DIGIT_1 },
132 { "2", "abc", TP_DTMF_EVENT_DIGIT_2 },
133 { "3", "def", TP_DTMF_EVENT_DIGIT_3 },
134 { "4", "ghi", TP_DTMF_EVENT_DIGIT_4 },
135 { "5", "jkl", TP_DTMF_EVENT_DIGIT_5 },
136 { "6", "mno", TP_DTMF_EVENT_DIGIT_6 },
137 { "7", "pqrs", TP_DTMF_EVENT_DIGIT_7 },
138 { "8", "tuv", TP_DTMF_EVENT_DIGIT_8 },
139 { "9", "wxyz", TP_DTMF_EVENT_DIGIT_9 },
140 { "#", "", TP_DTMF_EVENT_HASH },
141 { "0", "", TP_DTMF_EVENT_DIGIT_0 },
142 { "*", "", TP_DTMF_EVENT_ASTERISK },
143 { NULL, } };
145 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_DIALPAD_WIDGET,
146 EmpathyDialpadWidgetPrivate);
148 gtk_orientable_set_orientation (GTK_ORIENTABLE (self),
149 GTK_ORIENTATION_VERTICAL);
150 gtk_box_set_spacing (GTK_BOX (self), 3);
152 self->priv->entry = gtk_entry_new ();
153 gtk_editable_set_editable (GTK_EDITABLE (self->priv->entry), FALSE);
155 gtk_box_pack_start (GTK_BOX (self), self->priv->entry, FALSE, FALSE, 3);
157 grid = gtk_grid_new ();
158 gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
159 gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
161 self->priv->buttons = g_hash_table_new (NULL, NULL);
163 for (i = 0; dtmfbuttons[i].label != NULL; i++)
165 GtkWidget *button;
167 button = empathy_dialpad_button_new (dtmfbuttons[i].label,
168 dtmfbuttons[i].sublabel, dtmfbuttons[i].event);
170 gtk_grid_attach (GTK_GRID (grid), button, i % 3, i / 3,
171 1, 1);
173 g_signal_connect (G_OBJECT (button), "button-press-event",
174 G_CALLBACK (dtmf_dialpad_button_pressed_cb), self);
175 g_signal_connect (G_OBJECT (button), "button-release-event",
176 G_CALLBACK (dtmf_dialpad_button_released_cb), self);
178 g_hash_table_insert (self->priv->buttons,
179 GUINT_TO_POINTER (dtmfbuttons[i].label[0]), button);
182 gtk_box_pack_start (GTK_BOX (self), grid, FALSE, FALSE, 3);
184 /* show everything but the packing box */
185 gtk_widget_show_all (GTK_WIDGET (self));
186 gtk_widget_hide (GTK_WIDGET (self));
189 GtkWidget *
190 empathy_dialpad_widget_new (void)
192 return g_object_new (EMPATHY_TYPE_DIALPAD_WIDGET, NULL);
195 void
196 empathy_dialpad_widget_press_key (EmpathyDialpadWidget *self,
197 gchar key)
199 EmpathyDialpadButton *button;
201 button = g_hash_table_lookup (self->priv->buttons, GUINT_TO_POINTER (key));
203 if (button == NULL)
204 return;
206 /* gtk_widget_activate() just does the button-pressed animation, it doesn't
207 * fire the callbacks so we do it manually. */
208 dtmf_dialpad_button_pressed_cb (button, NULL, self);
209 gtk_widget_activate (GTK_WIDGET (button));
210 dtmf_dialpad_button_released_cb (button, NULL, self);