1 /*
2 Waveform seekbar plugin for the DeaDBeeF audio player
3
4 Copyright (C) 2014 Christian Boxdörfer <christian.boxdoerfer@posteo.de>
5
6 Based on sndfile-tools waveform by Erik de Castro Lopo.
7 waveform.c - v1.04
8 Copyright (C) 2007-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
9 Copyright (C) 2012 Robin Gareus <robin@gareus.org>
10 Copyright (C) 2013 driedfruit <driedfruit@mindloop.net>
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <stdlib.h>
30 #include <fcntl.h>
31 #include <gtk/gtk.h>
32
33 #include <deadbeef/deadbeef.h>
34
35 #include "config.h"
36 #include "waveform.h"
37 #include "config_dialog.h"
38
39 #if !GTK_CHECK_VERSION(2,14,0)
40 #define gtk_widget_get_window(widget) ((widget)->window)
41 #define gtk_dialog_get_content_area(dialog) (dialog->vbox)
42 #define gtk_dialog_get_action_area(dialog) (dialog->action_area)
43 #endif
44
45 #if !GTK_CHECK_VERSION(2,18,0)
46 void
gtk_widget_get_allocation(GtkWidget * widget,GtkAllocation * allocation)47 gtk_widget_get_allocation (GtkWidget *widget, GtkAllocation *allocation) {
48 (allocation)->x = widget->allocation.x;
49 (allocation)->y = widget->allocation.y;
50 (allocation)->width = widget->allocation.width;
51 (allocation)->height = widget->allocation.height;
52 }
53 #define gtk_widget_set_can_default(widget, candefault) {if (candefault) GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT); else GTK_WIDGET_UNSET_FLAGS(widget, GTK_CAN_DEFAULT);}
54 #endif
55
56 #pragma GCC diagnostic push
57 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
58 void
on_button_config(GtkMenuItem * menuitem,gpointer user_data)59 on_button_config (GtkMenuItem *menuitem, gpointer user_data)
60 {
61 GtkWidget *waveform_properties;
62 GtkWidget *config_dialog;
63 GtkWidget *vbox01;
64 GtkWidget *color_label;
65 GtkWidget *color_frame;
66 GtkWidget *color_table;
67 GtkWidget *color_background_label;
68 GtkWidget *background_color;
69 GtkWidget *color_waveform_label;
70 GtkWidget *foreground_color;
71 GtkWidget *color_rms_label;
72 GtkWidget *foreground_rms_color;
73 GtkWidget *color_progressbar_label;
74 GtkWidget *progressbar_color;
75 GtkWidget *downmix_to_mono;
76 GtkWidget *log_scale;
77 GtkWidget *display_rms;
78 GtkWidget *display_ruler;
79 GtkWidget *style_label;
80 GtkWidget *style_frame;
81 GtkWidget *vbox02;
82 GtkWidget *render_method_spikes;
83 GtkWidget *render_method_bars;
84 GtkWidget *shade_waveform;
85 GtkWidget *fill_waveform;
86 GtkWidget *soundcloud_style;
87 GtkWidget *dialog_action_area13;
88 GtkWidget *applybutton1;
89 GtkWidget *cancelbutton1;
90 GtkWidget *okbutton1;
91 waveform_properties = gtk_dialog_new ();
92 gtk_window_set_title (GTK_WINDOW (waveform_properties), "Waveform Properties");
93 gtk_window_set_type_hint (GTK_WINDOW (waveform_properties), GDK_WINDOW_TYPE_HINT_DIALOG);
94
95 config_dialog = gtk_dialog_get_content_area (GTK_DIALOG (waveform_properties));
96 gtk_widget_show (config_dialog);
97
98 vbox01 = gtk_vbox_new (FALSE, 8);
99 gtk_widget_show (vbox01);
100 gtk_box_pack_start (GTK_BOX (config_dialog), vbox01, FALSE, FALSE, 0);
101 gtk_container_set_border_width (GTK_CONTAINER (vbox01), 12);
102
103 color_label = gtk_label_new (NULL);
104 gtk_label_set_markup (GTK_LABEL (color_label),"<b>Colors</b>");
105 gtk_widget_show (color_label);
106
107 color_frame = gtk_frame_new ("Colors");
108 gtk_frame_set_label_widget ((GtkFrame *)color_frame, color_label);
109 gtk_frame_set_shadow_type ((GtkFrame *)color_frame, GTK_SHADOW_IN);
110 gtk_widget_show (color_frame);
111 gtk_box_pack_start (GTK_BOX (vbox01), color_frame, TRUE, FALSE, 0);
112
113 color_table = gtk_table_new (2, 4, TRUE);
114 gtk_widget_show (color_table);
115 gtk_container_add (GTK_CONTAINER (color_frame), color_table);
116 gtk_table_set_col_spacings ((GtkTable *) color_table, 8);
117 gtk_container_set_border_width (GTK_CONTAINER (color_table), 6);
118
119 color_background_label = gtk_label_new ("Background");
120 gtk_widget_show (color_background_label);
121 gtk_table_attach_defaults ((GtkTable *) color_table, color_background_label, 0,1,0,1);
122
123 color_waveform_label = gtk_label_new ("Waveform");
124 gtk_widget_show (color_waveform_label);
125 gtk_table_attach_defaults ((GtkTable *) color_table, color_waveform_label, 1,2,0,1);
126
127 color_rms_label = gtk_label_new ("RMS");
128 gtk_widget_show (color_rms_label);
129 gtk_table_attach_defaults ((GtkTable *) color_table, color_rms_label, 2,3,0,1);
130
131 color_progressbar_label = gtk_label_new ("Progressbar");
132 gtk_widget_show (color_progressbar_label);
133 gtk_table_attach_defaults ((GtkTable *) color_table, color_progressbar_label, 3,4,0,1);
134
135 background_color = gtk_color_button_new ();
136 gtk_color_button_set_use_alpha ((GtkColorButton *)background_color, TRUE);
137 gtk_widget_show (background_color);
138 gtk_table_attach_defaults ((GtkTable *) color_table, background_color, 0,1,1,2);
139
140 foreground_color = gtk_color_button_new ();
141 gtk_color_button_set_use_alpha ((GtkColorButton *)foreground_color, TRUE);
142 gtk_widget_show (foreground_color);
143 gtk_table_attach_defaults ((GtkTable *) color_table, foreground_color, 1,2,1,2);
144
145 foreground_rms_color = gtk_color_button_new ();
146 gtk_color_button_set_use_alpha ((GtkColorButton *)foreground_rms_color, TRUE);
147 gtk_widget_show (foreground_rms_color);
148 gtk_table_attach_defaults ((GtkTable *) color_table, foreground_rms_color, 2,3,1,2);
149
150 progressbar_color = gtk_color_button_new ();
151 gtk_color_button_set_use_alpha ((GtkColorButton *)progressbar_color, TRUE);
152 gtk_widget_show (progressbar_color);
153 gtk_table_attach_defaults ((GtkTable *) color_table, progressbar_color, 3,4,1,2);
154
155 style_label = gtk_label_new (NULL);
156 gtk_label_set_markup (GTK_LABEL (style_label),"<b>Style</b>");
157 gtk_widget_show (style_label);
158
159 style_frame = gtk_frame_new ("Style");
160 gtk_frame_set_label_widget ((GtkFrame *)style_frame, style_label);
161 gtk_frame_set_shadow_type ((GtkFrame *)style_frame, GTK_SHADOW_IN);
162 gtk_widget_show (style_frame);
163 gtk_box_pack_start (GTK_BOX (vbox01), style_frame, FALSE, FALSE, 0);
164
165 vbox02 = gtk_vbox_new (FALSE, 6);
166 gtk_widget_show (vbox02);
167 gtk_container_add (GTK_CONTAINER (style_frame), vbox02);
168
169 render_method_spikes = gtk_radio_button_new_with_label (NULL, "Spikes");
170 gtk_widget_show (render_method_spikes);
171 gtk_box_pack_start (GTK_BOX (vbox02), render_method_spikes, TRUE, TRUE, 0);
172
173 render_method_bars = gtk_radio_button_new_with_label_from_widget ((GtkRadioButton *)render_method_spikes, "Bars");
174 gtk_widget_show (render_method_bars);
175 gtk_box_pack_start (GTK_BOX (vbox02), render_method_bars, TRUE, TRUE, 0);
176
177 fill_waveform = gtk_check_button_new_with_label ("Fill waveform");
178 gtk_widget_show (fill_waveform);
179 gtk_box_pack_start (GTK_BOX (vbox02), fill_waveform, TRUE, TRUE, 0);
180
181 soundcloud_style = gtk_check_button_new_with_label ("Soundcloud style");
182 gtk_widget_show (soundcloud_style);
183 gtk_box_pack_start (GTK_BOX (vbox02), soundcloud_style, TRUE, TRUE, 0);
184
185 shade_waveform = gtk_check_button_new_with_label ("Shade waveform");
186 gtk_widget_show (shade_waveform);
187 gtk_box_pack_start (GTK_BOX (vbox02), shade_waveform, TRUE, TRUE, 0);
188
189 downmix_to_mono = gtk_check_button_new_with_label ("Downmix to mono");
190 gtk_widget_show (downmix_to_mono);
191 gtk_box_pack_start (GTK_BOX (vbox01), downmix_to_mono, FALSE, FALSE, 0);
192
193 log_scale = gtk_check_button_new_with_label ("Logarithmic scale");
194 gtk_widget_show (log_scale);
195 gtk_box_pack_start (GTK_BOX (vbox01), log_scale, FALSE, FALSE, 0);
196
197 display_rms = gtk_check_button_new_with_label ("Display RMS");
198 gtk_widget_show (display_rms);
199 gtk_box_pack_start (GTK_BOX (vbox01), display_rms, FALSE, FALSE, 0);
200
201 display_ruler = gtk_check_button_new_with_label ("Display Ruler");
202 gtk_widget_show (display_ruler);
203 gtk_box_pack_start (GTK_BOX (vbox01), display_ruler, FALSE, FALSE, 0);
204
205 dialog_action_area13 = gtk_dialog_get_action_area (GTK_DIALOG (waveform_properties));
206 gtk_widget_show (dialog_action_area13);
207 gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area13), GTK_BUTTONBOX_END);
208
209 applybutton1 = gtk_button_new_from_stock ("gtk-apply");
210 gtk_widget_show (applybutton1);
211 gtk_dialog_add_action_widget (GTK_DIALOG (waveform_properties), applybutton1, GTK_RESPONSE_APPLY);
212 gtk_widget_set_can_default (applybutton1, TRUE);
213
214 cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
215 gtk_widget_show (cancelbutton1);
216 gtk_dialog_add_action_widget (GTK_DIALOG (waveform_properties), cancelbutton1, GTK_RESPONSE_CANCEL);
217 gtk_widget_set_can_default (cancelbutton1, TRUE);
218
219 okbutton1 = gtk_button_new_from_stock ("gtk-ok");
220 gtk_widget_show (okbutton1);
221 gtk_dialog_add_action_widget (GTK_DIALOG (waveform_properties), okbutton1, GTK_RESPONSE_OK);
222 gtk_widget_set_can_default (okbutton1, TRUE);
223
224 gtk_color_button_set_color (GTK_COLOR_BUTTON (background_color), &CONFIG_BG_COLOR);
225 gtk_color_button_set_color (GTK_COLOR_BUTTON (foreground_color), &CONFIG_FG_COLOR);
226 gtk_color_button_set_color (GTK_COLOR_BUTTON (progressbar_color), &CONFIG_PB_COLOR);
227 gtk_color_button_set_color (GTK_COLOR_BUTTON (foreground_rms_color), &CONFIG_FG_RMS_COLOR);
228 gtk_color_button_set_alpha (GTK_COLOR_BUTTON (background_color), CONFIG_BG_ALPHA);
229 gtk_color_button_set_alpha (GTK_COLOR_BUTTON (foreground_color), CONFIG_FG_ALPHA);
230 gtk_color_button_set_alpha (GTK_COLOR_BUTTON (progressbar_color), CONFIG_PB_ALPHA);
231 gtk_color_button_set_alpha (GTK_COLOR_BUTTON (foreground_rms_color), CONFIG_FG_RMS_ALPHA);
232
233 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (downmix_to_mono), CONFIG_MIX_TO_MONO);
234 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (log_scale), CONFIG_LOG_ENABLED);
235 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (display_rms), CONFIG_DISPLAY_RMS);
236 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (display_ruler), CONFIG_DISPLAY_RULER);
237 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (shade_waveform), CONFIG_SHADE_WAVEFORM);
238 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (soundcloud_style), CONFIG_SOUNDCLOUD_STYLE);
239 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill_waveform), CONFIG_FILL_WAVEFORM);
240
241 gtk_widget_set_sensitive (display_rms, !CONFIG_SOUNDCLOUD_STYLE);
242
243 switch (CONFIG_RENDER_METHOD) {
244 case SPIKES:
245 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (render_method_spikes), TRUE);
246 break;
247 case BARS:
248 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (render_method_bars), TRUE);
249 break;
250 }
251
252 for (;;) {
253 int response = gtk_dialog_run (GTK_DIALOG (waveform_properties));
254 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) {
255 gtk_color_button_get_color (GTK_COLOR_BUTTON (background_color), &CONFIG_BG_COLOR);
256 gtk_color_button_get_color (GTK_COLOR_BUTTON (foreground_color), &CONFIG_FG_COLOR);
257 gtk_color_button_get_color (GTK_COLOR_BUTTON (progressbar_color), &CONFIG_PB_COLOR);
258 gtk_color_button_get_color (GTK_COLOR_BUTTON (foreground_rms_color), &CONFIG_FG_RMS_COLOR);
259 CONFIG_BG_ALPHA = gtk_color_button_get_alpha (GTK_COLOR_BUTTON (background_color));
260 CONFIG_FG_ALPHA = gtk_color_button_get_alpha (GTK_COLOR_BUTTON (foreground_color));
261 CONFIG_PB_ALPHA = gtk_color_button_get_alpha (GTK_COLOR_BUTTON (progressbar_color));
262 CONFIG_FG_RMS_ALPHA = gtk_color_button_get_alpha (GTK_COLOR_BUTTON (foreground_rms_color));
263 CONFIG_MIX_TO_MONO = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (downmix_to_mono));
264 CONFIG_LOG_ENABLED = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (log_scale));
265 CONFIG_DISPLAY_RMS = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (display_rms));
266 CONFIG_DISPLAY_RULER = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (display_ruler));
267 CONFIG_SHADE_WAVEFORM = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (shade_waveform));
268 CONFIG_SOUNDCLOUD_STYLE = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (soundcloud_style));
269 CONFIG_FILL_WAVEFORM = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill_waveform));
270 gtk_widget_set_sensitive (display_rms, !CONFIG_SOUNDCLOUD_STYLE);
271 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (render_method_spikes)) == TRUE) {
272 CONFIG_RENDER_METHOD = SPIKES;
273 }
274 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (render_method_bars)) == TRUE) {
275 CONFIG_RENDER_METHOD = BARS;
276 }
277 save_config ();
278 deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0);
279 }
280 if (response == GTK_RESPONSE_APPLY) {
281 continue;
282 }
283 break;
284 }
285 gtk_widget_destroy (waveform_properties);
286 return;
287 }
288 #pragma GCC diagnostic pop
289
290