1 /** \file settings_sampler.c
2 * \brief Widget to control sampler settings
3 *
4 * \author Bas Wassink <b.wassink@ziggo.nl>
5 */
6
7 /*
8 * $VICERES SamplerDevice
9 * $VICERES SamplerGain
10 * $VICERES SampleName
11 */
12
13 /*
14 * This file is part of VICE, the Versatile Commodore Emulator.
15 * See README for copyright notice.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 * 02111-1307 USA.
31 *
32 */
33
34 #include "vice.h"
35
36 #include <gtk/gtk.h>
37
38 #include "widgethelpers.h"
39 #include "debug_gtk3.h"
40 #include "resources.h"
41 #include "sampler.h"
42 #include "openfiledialog.h"
43
44 #include "settings_sampler.h"
45
46
47 /** \brief Function to retrieve the list of sampler input devices
48 */
49 static sampler_device_t *(*devices_getter)(void) = NULL;
50
51
52 /** \brief Reference to the text entry
53 *
54 * Used by the "browse" button callback to set the new file name and trigger
55 * a resource update
56 */
57 static GtkWidget *entry_widget = NULL;
58
59
60 /** \brief Reference to the "browse" button
61 */
62 static GtkWidget *browse_button = NULL;
63
64
65 /** \brief Handler for the "changed" event of the devices combo box
66 *
67 * \param[in] combo combo box with devices
68 * \param[in] user_data extra data (unused)
69 */
on_device_changed(GtkComboBoxText * combo,gpointer user_data)70 static void on_device_changed(GtkComboBoxText *combo, gpointer user_data)
71 {
72 int index = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
73
74 debug_gtk3("setting SamplerDevice to %d.", index);
75 resources_set_int("SamplerDevice", index);
76
77 /* this assumes the "media file input" is always first in the list */
78 gtk_widget_set_sensitive(entry_widget, index == 0);
79 gtk_widget_set_sensitive(browse_button, index == 0);
80 }
81
82
83 /** \brief Handler for the "value-changed" event of the gain slider
84 *
85 * \param[in] scale gain slider
86 * \param[in] user_data extra data (unused)
87 */
on_gain_changed(GtkScale * scale,gpointer user_data)88 static void on_gain_changed(GtkScale *scale, gpointer user_data)
89 {
90 int value = (int)gtk_range_get_value(GTK_RANGE(scale));
91
92 debug_gtk3("setting SamplerGain to %d.", value);
93 resources_set_int("SamplerGain", value);
94 }
95
96
97 /** \brief Handler for the "changed" event of the text entry box
98 *
99 * \param[in] entry input file text box
100 * \param[in] user_data extra data (unused)
101 */
on_entry_changed(GtkEntry * entry,gpointer user_data)102 static void on_entry_changed(GtkEntry *entry, gpointer user_data)
103 {
104 const char *text;
105
106 text = gtk_entry_get_text(entry);
107 debug_gtk3("setting SampleName to '%s'.", text);
108 resources_set_string("SampleName", text);
109 }
110
111
112 /** \brief Handler for the "clicked" event of the "browse" button
113 *
114 * \param[in] widget browse button
115 * \param[in] user_data extra data (unused)
116 */
on_browse_clicked(GtkWidget * widget,gpointer user_data)117 static void on_browse_clicked(GtkWidget *widget, gpointer user_data)
118 {
119 gchar *filename;
120
121 filename = vice_gtk3_open_file_dialog("Select input file", NULL, NULL, NULL);
122 if (filename != NULL) {
123 gtk_entry_set_text(GTK_ENTRY(entry_widget), filename);
124 g_free(filename);
125 }
126 }
127
128
129 /** \brief Create combo box for the devices list
130 *
131 * \return GtkComboBoxText
132 */
create_device_widget(void)133 static GtkWidget *create_device_widget(void)
134 {
135 GtkWidget *combo;
136 sampler_device_t *devices;
137 int current;
138 int i;
139
140 resources_get_int("SamplerDevice", ¤t);
141
142 combo = gtk_combo_box_text_new();
143 if (devices_getter != NULL) {
144 devices = devices_getter();
145 } else {
146 return combo;
147 }
148 for (i = 0; devices[i].name != NULL; i++) {
149 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo),
150 devices[i].name, devices[i].name);
151 if (i == current) {
152 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
153 }
154 }
155
156 g_signal_connect(combo, "changed", G_CALLBACK(on_device_changed), NULL);
157 return combo;
158 }
159
160
161 /** \brief Create slider for the gain
162 *
163 * \return GtkScale
164 */
create_gain_widget(void)165 static GtkWidget *create_gain_widget(void)
166 {
167 GtkWidget *scale;
168 GtkWidget *label;
169 int value;
170 int i;
171
172 label = gtk_label_new("Sampler gain");
173 g_object_set(label, "margin-left",16, NULL);
174
175 scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL,
176 0.0, 200.0, 25.0);
177 gtk_scale_set_digits(GTK_SCALE(scale), 0);
178
179 /* add tick marks */
180 for (i = 0; i < 200; i += 25) {
181 gtk_scale_add_mark(GTK_SCALE(scale), (gdouble)i, GTK_POS_BOTTOM, NULL);
182 }
183
184
185 if (resources_get_int("SamplerGain", &value) >= 0) {
186 gtk_range_set_value(GTK_RANGE(scale), (gdouble)value);
187 } else {
188 gtk_range_set_value(GTK_RANGE(scale), 100.0);
189 }
190
191 g_signal_connect(scale, "value-changed", G_CALLBACK(on_gain_changed), NULL);
192
193 gtk_widget_show_all(scale);
194 return scale;
195 }
196
197
198 /** \brief Create text entry for the input file name
199 *
200 * \return GtkEntry
201 */
create_input_entry(void)202 static GtkWidget *create_input_entry(void)
203 {
204 GtkWidget *entry;
205 const char *text;
206
207 resources_get_string("SampleName", &text);
208
209 entry = gtk_entry_new();
210 if (text != NULL) {
211 gtk_entry_set_text(GTK_ENTRY(entry), text);
212 }
213
214 g_signal_connect(entry, "changed", G_CALLBACK(on_entry_changed), NULL);
215 return entry;
216 }
217
218
219 /** \brief Create the "browse" button
220 *
221 * \return GtkButton
222 */
create_input_button(void)223 static GtkWidget *create_input_button(void)
224 {
225 GtkWidget *button;
226
227 button = gtk_button_new_with_label("Browse ...");
228 g_signal_connect(button, "clicked", G_CALLBACK(on_browse_clicked), NULL);
229 return button;
230 }
231
232
233 /** \brief Set the function to retrieve the input devices list
234 *
235 * \param[in] func pointer to function to retrieve devices list
236 */
settings_sampler_set_devices_getter(sampler_device_t * (func)(void))237 void settings_sampler_set_devices_getter(sampler_device_t *(func)(void))
238 {
239 devices_getter = func;
240 }
241
242
243 /** \brief Create widget to control sampler settings
244 *
245 * \param[in] parent parent widget
246 *
247 * \return GtkGrid
248 */
settings_sampler_widget_create(GtkWidget * parent)249 GtkWidget *settings_sampler_widget_create(GtkWidget *parent)
250 {
251 GtkWidget *grid;
252 GtkWidget *label;
253 GtkWidget *combo;
254 int index;
255
256 grid = uihelpers_create_grid_with_label("Sampler settings", 3);
257 gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
258
259 /* sampler device list */
260 label = gtk_label_new("Sampler device");
261 gtk_widget_set_halign(label, GTK_ALIGN_START);
262 g_object_set(label, "margin-left", 16, NULL);
263 gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
264 combo = create_device_widget();
265 gtk_grid_attach(GTK_GRID(grid), combo, 1, 1, 2, 1);
266
267 /* sampler gain */
268 label = gtk_label_new("Sampler gain");
269 gtk_widget_set_halign(label, GTK_ALIGN_START);
270 g_object_set(label, "margin-left", 16, NULL);
271 gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1);
272 gtk_grid_attach(GTK_GRID(grid), create_gain_widget(), 1, 2, 2, 1);
273
274 /* sampler input file text entry and browse button */
275 label = gtk_label_new("Sampler media file");
276 gtk_widget_set_halign(label, GTK_ALIGN_START);
277 g_object_set(label, "margin-left", 16, NULL);
278 gtk_grid_attach(GTK_GRID(grid), label, 0, 3, 1, 1);
279 entry_widget = create_input_entry();
280 gtk_widget_set_hexpand(entry_widget, TRUE);
281 gtk_grid_attach(GTK_GRID(grid), entry_widget, 1, 3, 1, 1);
282 browse_button = create_input_button();
283 gtk_grid_attach(GTK_GRID(grid), browse_button, 2, 3, 1, 1);
284
285 /* update sensitivity of entry and button */
286 index = gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
287
288 gtk_widget_set_sensitive(entry_widget, index == 0);
289 gtk_widget_set_sensitive(browse_button, index == 0);
290
291 gtk_widget_show_all(grid);
292 return grid;
293 }
294