1 /* waves_dialog.c:  dialog for waves deformation filters
2  *
3  * Copyright (C) 2002 Patrice St-Gelais
4  *         patrstg@users.sourceforge.net
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include "img_process_dialog.h"
22 #include "hf_wrapper.h"
23 #include "waves_dialog.h"
24 #include "dialog_utilities.h"
25 #include "../icons/sine_w.xpm"
26 #include "../icons/sine_concave_w.xpm"
27 #include "../icons/concave_w.xpm"
28 #include "../icons/horizontal.xpm"
29 #include "../icons/vertical.xpm"
30 #include "../icons/sine_conc_2_3_w.xpm"
31 #include "../icons/triangle_w.xpm"
32 #include "../icons/square_w.xpm"
33 // #include "../icons/circular_w.xpm"
34 
35 //	Private prototypes
36 static void sine_upd (GtkWidget *wdg, gpointer data) ;
37 static void concave_upd (GtkWidget *wdg, gpointer data) ;
38 static void sine_concave_upd (GtkWidget *wdg, gpointer data) ;
39 static void sine_concave_2_3_upd (GtkWidget *wdg, gpointer data) ;
40 static void triangle_upd (GtkWidget *wdg, gpointer data) ;
41 static void square_upd (GtkWidget *wdg, gpointer data) ;
42 
43 static void vertical_upd (GtkWidget *wdg, gpointer data) ;
44 static void horizontal_upd (GtkWidget *wdg, gpointer data) ;
45 // static void circular_upd (GtkWidget *wdg, gpointer data) ;
46 
47 //	NBWAVES #defined in waves.h
48 command_item_struct w_shapes[NBWAVES] = {
49 { "Waves", "Sine", "Sine wave",
50 	0, (gchar **) sine_w_xpm, GDK_LEFT_PTR, sine_upd,NULL, NULL,TRUE },
51 { "Waves", "Concave X*X", "Negative curvature wave X*X",
52 	0, (gchar **) concave_w_xpm, GDK_LEFT_PTR, concave_upd,NULL, NULL,FALSE },
53 { "Waves", "+Sine-Concave", "Growing wave = sine, decreasing = negative curvature X*X",
54 	0, (gchar **) sine_concave_w_xpm, GDK_LEFT_PTR, sine_concave_upd,NULL, NULL,FALSE },
55 { "Waves", "+Sine 2/3, -Concave 1/3", "Growing wave = sine 2/3, decreasing = X*X 1/3",
56 	0, (gchar **) sine_conc_2_3_w_xpm, GDK_LEFT_PTR, sine_concave_2_3_upd,NULL, NULL,FALSE },
57 { "Waves", "Triangle", "Triangular wave",
58 	0, (gchar **) triangle_w_xpm, GDK_LEFT_PTR, triangle_upd,NULL, NULL,FALSE },
59 { "Waves", "Square", "Square wave",
60 	0, (gchar **) square_w_xpm, GDK_LEFT_PTR, square_upd,NULL, NULL,FALSE }
61 };
62 
63 //	NBAXIS #defined in waves.h
64 command_item_struct w_axis[NBAXIS] = {
65 { "Deformation axis", "Vertical", "Vertical",
66 	0, (gchar **) vertical_xpm, GDK_LEFT_PTR, vertical_upd,NULL, NULL,TRUE },
67 { "Deformation axis", "Horizontal", "Horizontal",
68 	0, (gchar **) horizontal_xpm, GDK_LEFT_PTR, horizontal_upd,NULL, NULL,FALSE }
69 // { "Deformation axis", "Circular", "Circular",
70 //	0, (gchar **) circular_w_xpm, GDK_LEFT_PTR, circular_upd,NULL, NULL,FALSE }
71 };
72 
wave_calc(hf_wrapper_struct * hfw)73 void wave_calc(hf_wrapper_struct *hfw) {
74 //	Convenience function, recalculates and displays the HF
75 //	--> Eventually do a test to calculate only if the "direct update' checkbox is checked
76 	if (hfw->if_calculated)
77 		return;
78 	waves_apply(hfw->hf_struct,
79 		hfw->hf_options->img->wav_shapes,
80 		hfw->hf_options->img->nb_wav,
81 		hfw->hf_options->img->wav_data);
82 	begin_pending_record(hfw,"Waves",accept_fn,reset_fn);
83 	if (hfw->hf_options->img->wav_accept)
84 		gtk_widget_set_sensitive(GTK_WIDGET(hfw->hf_options->img->wav_accept),TRUE);
85 	hfw->if_calculated = TRUE;
86 	draw_hf(hfw);
87 }
88 
wave_upd(GtkWidget * button,gpointer data,gint wave_shape)89 void wave_upd(GtkWidget *button, gpointer data, gint wave_shape) {
90 	gint current_page;
91 	wave_struct *ws;
92 	hf_wrapper_struct *hfw;
93 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
94 	//	Nothing to do if we are just unactivating the button
95 		return;
96 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
97 //	Find the current notebook page
98 	current_page = gtk_notebook_get_current_page
99 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
100 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
101 //	No change...
102 	if ((ws->shape) == wave_shape)
103 		return ;
104 //	Update the field
105 	ws->shape = wave_shape;
106 	hfw->if_calculated = FALSE;
107 	wave_calc(hfw);
108 }
109 
sine_upd(GtkWidget * wdg,gpointer data)110 static void sine_upd (GtkWidget *wdg, gpointer data) {
111 	wave_upd (wdg,data,SINE_WAVE);
112 }
concave_upd(GtkWidget * wdg,gpointer data)113 static void concave_upd (GtkWidget *wdg, gpointer data) {
114 	wave_upd (wdg,data,CONCAVE_WAVE);
115 }
sine_concave_upd(GtkWidget * wdg,gpointer data)116 static void sine_concave_upd (GtkWidget *wdg, gpointer data) {
117 	wave_upd (wdg,data,SINE_CONCAVE_WAVE);
118 }
sine_concave_2_3_upd(GtkWidget * wdg,gpointer data)119 static void sine_concave_2_3_upd (GtkWidget *wdg, gpointer data) {
120 	wave_upd (wdg,data,SINE_CONCAVE_2_3_WAVE);
121 }
triangle_upd(GtkWidget * wdg,gpointer data)122 static void triangle_upd (GtkWidget *wdg, gpointer data) {
123 	wave_upd (wdg,data, TRIANGLE_WAVE);
124 }
square_upd(GtkWidget * wdg,gpointer data)125 static void square_upd (GtkWidget *wdg, gpointer data) {
126 	wave_upd (wdg,data, SQUARE_WAVE);
127 }
128 
axis_upd(GtkWidget * button,gpointer data,gint axis)129 void axis_upd(GtkWidget *button, gpointer data, gint axis) {
130 	gint current_page;
131 	wave_struct *ws;
132 	hf_wrapper_struct *hfw;
133 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
134 	//	Nothing to do if we are just unactivating the button
135 		return;
136 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
137 //	Find the current notebook page
138 	current_page = gtk_notebook_get_current_page
139 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
140 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
141 //	No change...
142 	if ((ws->axis) == axis)
143 		return ;
144 //	Update the field
145 	ws->axis = axis;
146 	hfw->if_calculated = FALSE;
147 //	Recalculate and display the HF
148 	wave_calc(hfw);
149 }
150 
vertical_upd(GtkWidget * wdg,gpointer data)151 static void vertical_upd (GtkWidget *wdg, gpointer data) {
152 	axis_upd (wdg,data,VERTICAL_WAVE);
153 }
horizontal_upd(GtkWidget * wdg,gpointer data)154 static void horizontal_upd (GtkWidget *wdg, gpointer data) {
155 	axis_upd (wdg,data, HORIZONTAL_WAVE);
156 }
157 /*
158 static void circular_upd (GtkWidget *wdg, gpointer data) {
159 	axis_upd (wdg,data, CIRCULAR_WAVE);
160 }
161 */
162 
order_upd(GtkWidget * wdg,gpointer data)163 void order_upd (GtkWidget *wdg, gpointer data) {
164 	gint current_page;
165 	wave_struct *ws;
166 	hf_wrapper_struct *hfw;
167 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
168 //	Find the current notebook page
169 	current_page = gtk_notebook_get_current_page
170 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
171 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
172 //	No change...
173 	if ((ws->order) == (gint) GTK_ADJUSTMENT(wdg)->value)
174 		return ;
175 	ws->order = (gint) GTK_ADJUSTMENT(wdg)->value;
176 	hfw->if_calculated = FALSE;
177 	wave_calc(hfw);
178 }
179 
angle_upd(GtkWidget * wdg,gpointer data)180 void angle_upd (GtkWidget *wdg, gpointer data) {
181 	gint current_page;
182 	wave_struct *ws;
183 	hf_wrapper_struct *hfw;
184 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
185 //	Find the current notebook page
186 	current_page = gtk_notebook_get_current_page
187 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
188 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
189 //	No change...
190 	if ((ws->angle) == (gint) GTK_ADJUSTMENT(wdg)->value)
191 		return ;
192 	ws->angle = (gint) GTK_ADJUSTMENT(wdg)->value;
193 	hfw->if_calculated = FALSE;
194 	wave_calc(hfw);
195 }
196 
period_upd(GtkWidget * wdg,gpointer data)197 void period_upd (GtkWidget *wdg, gpointer data) {
198 	gint current_page;
199 	wave_struct *ws;
200 	hf_wrapper_struct *hfw;
201 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
202 //	Find the current notebook page
203 	current_page = gtk_notebook_get_current_page
204 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
205 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
206 //	No change...
207 	if ((ws->period) == (gint) GTK_ADJUSTMENT(wdg)->value)
208 		return ;
209 	ws->period = (gint) GTK_ADJUSTMENT(wdg)->value;
210 	hfw->if_calculated = FALSE;
211 	wave_calc(hfw);
212 }
213 
amplitude_upd(GtkWidget * wdg,gpointer data)214 void amplitude_upd (GtkWidget *wdg, gpointer data) {
215 	gint current_page;
216 	wave_struct *ws;
217 	hf_wrapper_struct *hfw;
218 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
219 	if (!hfw->hf_options->img->wav_to_calc)
220 		return;
221 //	Find the current notebook page
222 	current_page = gtk_notebook_get_current_page
223 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
224 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
225 //	No change...
226 	if ((ws->amplitude) == (gint) GTK_ADJUSTMENT(wdg)->value)
227 		return ;
228 	ws->amplitude = (gint) GTK_ADJUSTMENT(wdg)->value;
229 	hfw->if_calculated = FALSE;
230 	wave_calc(hfw);
231 }
232 
randomness_upd(GtkWidget * wdg,gpointer data)233 void randomness_upd (GtkWidget *wdg, gpointer data) {
234 	gint current_page;
235 	wave_struct *ws;
236 	hf_wrapper_struct *hfw;
237 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
238 //	Find the current notebook page
239 	current_page = gtk_notebook_get_current_page
240 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
241 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
242 //	No change...
243 	if ((ws->randomness) == (gint) GTK_ADJUSTMENT(wdg)->value)
244 		return ;
245 	ws->randomness = (gint) GTK_ADJUSTMENT(wdg)->value;
246 	hfw->if_calculated = FALSE;
247 	wave_calc(hfw);
248 }
249 
phase_upd(GtkWidget * wdg,gpointer data)250 void phase_upd (GtkWidget *wdg, gpointer data) {
251 	gint current_page;
252 	wave_struct *ws;
253 	hf_wrapper_struct *hfw;
254 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
255 //	Find the current notebook page
256 	current_page = gtk_notebook_get_current_page
257 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
258 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
259 //	No change...
260 	if ((ws->phase) == (gint) GTK_ADJUSTMENT(wdg)->value)
261 		return ;
262 	ws->phase = (gint) GTK_ADJUSTMENT(wdg)->value;
263 	hfw->if_calculated = FALSE;
264 	wave_calc(hfw);
265 }
266 
set_axis(GtkWidget * tb,gint axis)267 void set_axis(GtkWidget *tb, gint axis) {
268 //	Sets the axis toolbar to "axis" value
269 //	Important:  order-dependent!
270 //	Don't mess the toolbar structure without modifying this function!
271 	GtkToolbarChild *child;
272 	switch (axis) {
273 		case VERTICAL_WAVE:
274 			child = (GtkToolbarChild *) g_list_nth_data(GTK_TOOLBAR(tb)->children,0);
275 			break;
276 		case HORIZONTAL_WAVE:
277 			child = (GtkToolbarChild *) g_list_nth_data(GTK_TOOLBAR(tb)->children,1);
278 			break;
279 		case CIRCULAR_WAVE:
280 			child = (GtkToolbarChild *) g_list_nth_data(GTK_TOOLBAR(tb)->children,2);
281 			break;
282 		default:		// VERTICAL_WAVE
283 			child = (GtkToolbarChild *) g_list_nth_data(GTK_TOOLBAR(tb)->children,0);
284 	}
285 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( child->widget), TRUE);
286 }
287 
change_wave_seed(GtkWidget * entry,gpointer data)288 static gint change_wave_seed(GtkWidget *entry, gpointer data) {
289 	gint current_page;
290 	wave_struct *ws;
291 	hf_wrapper_struct *hfw;
292 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
293 //	Find the current notebook page
294 	current_page = gtk_notebook_get_current_page
295 			(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
296 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data,current_page);
297 
298 // printf("ORDER: %d; SHAPE: %d; AXIS: %d; ANGLE: %d; PERIOD: %d; AMPLITUDE: %d; PHASE: %d; RANDOMNESS: %d; SEED: %d\n",
299 // ws->order, ws->shape, ws->axis, ws->angle, ws->period, ws->amplitude, ws->phase, ws->randomness, ws->seed);
300 
301 	ws->seed = (unsigned int) atoi((char *)gtk_entry_get_text(GTK_ENTRY(entry)));
302 
303 	hfw->if_calculated = FALSE;
304 	wave_calc(hfw);
305 	return FALSE;
306 }
307 
wave_page_new(img_dialog_struct * img,gint axis,GtkWidget * tools_window,GtkTooltips * tooltips,gpointer data)308 void wave_page_new(	img_dialog_struct *img,
309 				gint axis,
310 				GtkWidget *tools_window,
311 				GtkTooltips *tooltips,
312 				gpointer data) {
313 
314 	//	Creating a new wave page dialog in "img->wav_notebook"
315 	GtkWidget *vbox, *hbox, *table;
316 	wave_page_struct *page;
317 	wave_struct *ws;
318 	gchar *buf;
319 	toolbar_struct *tb;
320 	if (img->nb_wav==99) {
321 		my_msg(_("Maximum page reached (99)"),WARNING);
322 		return;
323 	}
324 
325 	vbox = gtk_vbox_new(FALSE,0);
326 	gtk_widget_show(GTK_WIDGET(vbox));
327 
328 	page = (wave_page_struct *) x_malloc(sizeof(wave_page_struct), "wave_page_struct");
329 	img->nb_wav++;
330 	img->wav_pages = g_list_append(img->wav_pages,(gpointer) page);
331 	ws = wave_new(SINE_WAVE, VERTICAL_WAVE, img->nb_wav);
332 	img->wav_data = g_list_append(img->wav_data,ws);
333 	page->notebook_page = vbox;
334 
335 	buf = (gchar *) malloc(5);
336 	sprintf(buf,"%d",img->nb_wav);
337 	gtk_notebook_append_page (GTK_NOTEBOOK(img->wav_notebook),
338 		vbox, gtk_label_new(buf));
339 	gtk_notebook_set_current_page(GTK_NOTEBOOK(img->wav_notebook),
340 		gtk_notebook_page_num(GTK_NOTEBOOK(img->wav_notebook),
341 			page->notebook_page));
342 
343 	hbox = gtk_hbox_new(FALSE,0);
344 	gtk_widget_show(GTK_WIDGET(hbox));
345 	define_label_in_box ("Order", hbox, FALSE, TRUE, DEF_PAD);
346  	page->adj_order = gtk_adjustment_new (img->nb_wav, 0.0, 100.0, 1.0, 5.0, 0.0);
347 	gtk_signal_connect (GTK_OBJECT (page->adj_order), "value_changed",
348 		GTK_SIGNAL_FUNC (order_upd), data);
349 	page->order_spinner =   gtk_spin_button_new (GTK_ADJUSTMENT(page->adj_order), 0, 0);
350 	gtk_widget_show(page->order_spinner);
351  	gtk_box_pack_start (GTK_BOX (hbox), page->order_spinner, FALSE, TRUE, 0);
352 	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, DEF_PAD);
353 
354 	hbox = gtk_hbox_new(FALSE,0);
355 	gtk_widget_show(GTK_WIDGET(hbox));
356 	define_label_in_box ("Shape", hbox, FALSE, TRUE, DEF_PAD);
357 	tb = toolbar_new(NBWAVES, w_shapes,
358 		tooltips,
359 		tools_window,
360 		data,
361 		GTK_ORIENTATION_HORIZONTAL,
362 		GTK_TOOLBAR_ICONS,
363 		TRUE);
364 	gtk_box_pack_start(GTK_BOX(hbox), tb->toolbarwdg, FALSE, FALSE, 0);
365 	page->shape_toolbar = tb->toolbarwdg;
366 	x_free(tb);
367 
368 	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, DEF_PAD);
369 
370 	hbox = gtk_hbox_new(FALSE,0);
371 	gtk_widget_show(GTK_WIDGET(hbox));
372 	define_label_in_box ("Deformation axis", hbox, FALSE, TRUE, DEF_PAD);
373 	tb = toolbar_new(NBAXIS, w_axis,
374 		tooltips,
375 		tools_window,
376 		data,
377 		GTK_ORIENTATION_HORIZONTAL,
378 		GTK_TOOLBAR_ICONS,
379 		TRUE);
380 	gtk_box_pack_start(GTK_BOX(hbox), tb->toolbarwdg, FALSE, FALSE, 0);
381 	page->axis_toolbar = tb->toolbarwdg;
382 	x_free(tb);
383 
384 	set_axis(page->axis_toolbar, axis);
385 
386 	gtk_box_pack_start_defaults (GTK_BOX (vbox), hbox);
387 
388 	gtk_box_pack_start(GTK_BOX(vbox),
389 		seed_dialog_new(data, ws->seed,
390 		change_wave_seed),FALSE,TRUE,DEF_PAD);
391 
392 	table = gtk_table_new(2, 6, FALSE);
393 	gtk_widget_show(GTK_WIDGET(table));
394 
395 	gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, DEF_PAD);
396 
397 	define_label_in_table("Amplitude", table, 0,1, 0, 1, DEF_PAD);
398  	page->adj_amplitude = gtk_adjustment_new (0, 0.0, 100.0, 1.0, 1.0, 0.0);
399 	page->amplitude_slider = define_scale_in_table(page->adj_amplitude, table, 1,2,0,1, 0, DEF_PAD);
400 	optimize_on_mouse_click (page->amplitude_slider, data);
401 	gtk_signal_connect (GTK_OBJECT (page->adj_amplitude), "value_changed",
402 		GTK_SIGNAL_FUNC (amplitude_upd), data);
403 
404 	define_label_in_table("Random var.", table, 0,1, 1, 2, DEF_PAD);
405  	page->adj_randomness = gtk_adjustment_new (0, 0.0, 100.0, 1.0, 1.0, 0.0);
406 	page->randomness_slider = define_scale_in_table(page->adj_randomness, table, 1,2,1,2, 0, DEF_PAD);
407 	optimize_on_mouse_click (page->randomness_slider, data);
408 	gtk_signal_connect (GTK_OBJECT (page->adj_randomness), "value_changed",
409 		GTK_SIGNAL_FUNC (randomness_upd), data);
410 
411 	define_label_in_table("Period", table, 0, 1, 2, 3, DEF_PAD);
412  	page->adj_period = gtk_adjustment_new (5, 1.0, 10.0, 1.0, 1.0, 0.0);
413 	page->period_slider = define_scale_in_table(page->adj_period, table, 1,2,2,3, 0, DEF_PAD);
414 	optimize_on_mouse_click (page->period_slider, data);
415 	gtk_signal_connect (GTK_OBJECT (page->adj_period), "value_changed",
416 		GTK_SIGNAL_FUNC (period_upd), data);
417 
418 	define_label_in_table("Phase", table, 0,1,3,4,DEF_PAD);
419  	page->adj_phase = gtk_adjustment_new (0, 0.0, 100.0, 1.0, 1.0, 0.0);
420 	page->phase_slider = define_scale_in_table(page->adj_phase, table, 1,2,3,4, 0, DEF_PAD);
421 	optimize_on_mouse_click (page->phase_slider, data);
422 	gtk_signal_connect (GTK_OBJECT (page->adj_phase), "value_changed",
423 		GTK_SIGNAL_FUNC (phase_upd), data);
424 
425 	define_label_in_table("Angle", table, 0, 1, 4, 5, DEF_PAD);
426  	page->adj_angle = gtk_adjustment_new (0, 0.0, 360.0, 1.0, 1.0, 0.0);
427 	page->angle_slider = define_scale_in_table(page->adj_angle, table, 1, 2, 4, 5, 0, DEF_PAD);
428 	optimize_on_mouse_click (page->angle_slider, data);
429 	gtk_signal_connect (GTK_OBJECT (page->adj_angle), "value_changed",
430 		GTK_SIGNAL_FUNC (angle_upd), data);
431 
432 	hbox = gtk_hbox_new(FALSE,DEF_PAD);
433 	gtk_widget_show(GTK_WIDGET(hbox));
434 
435 	rotate_buttons_new(hbox, (gpointer) page->adj_angle);
436 	gtk_table_attach (GTK_TABLE (table), align_widget(hbox, 0.5, 0.5), 1, 2, 5, 6,
437 		GTK_FILL, GTK_FILL, 0, 0);
438 }
439 
add_new_wave(GtkWidget * button,gpointer data)440 void add_new_wave(GtkWidget *button, gpointer data) {
441 	hf_wrapper_struct *hfw;
442 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
443 	wave_page_new(	hfw->hf_options->img,
444 				VERTICAL_WAVE,
445 				hfw->hf_options->tools_window,
446 				hfw->hf_options->tooltips,
447 				data);
448 }
449 
wave_page_free(wave_page_struct * wps)450 void wave_page_free (wave_page_struct *wps) {
451 	if (!wps)
452 		return;
453 	x_free(wps);
454 }
455 
456 /* Remove a page from the notebook */
457 //... inspired from the Gtk notebook example
delete_current_wave(GtkButton * button,gpointer data)458 void delete_current_wave( GtkButton   *button, gpointer data)
459 {
460     	gint page;
461 	wave_page_struct *wp;
462 	wave_struct *ws;
463 	hf_wrapper_struct *hfw;
464 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
465 
466     	page = gtk_notebook_get_current_page(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook));
467     	gtk_notebook_remove_page (hfw->hf_options->img->wav_notebook, page);
468 
469 	wp = (wave_page_struct *) g_list_nth_data(hfw->hf_options->img->wav_pages,page);
470 	hfw->hf_options->img->wav_pages =
471 		g_list_remove(hfw->hf_options->img->wav_pages, (gpointer) wp);
472 	hfw->hf_options->img->nb_wav--;
473 	wave_page_free(wp);
474 
475 	ws = (wave_struct *) g_list_nth_data(hfw->hf_options->img->wav_data, page);
476 	hfw->hf_options->img->wav_data =
477 		g_list_remove(hfw->hf_options->img->wav_data, (gpointer) ws);
478 	wave_free(ws);
479 
480     	/* Need to refresh the widget --
481      	This forces the widget to redraw itself. */
482     	gtk_widget_draw(GTK_WIDGET(hfw->hf_options->img->wav_notebook), NULL);
483 	wave_calc(hfw);
484 }
485 
set_wave_defaults(img_dialog_struct * img)486 void set_wave_defaults(img_dialog_struct *img) {
487 	//	Sets all the amplitudes to 0%
488 	GList *node, *node_data;
489 	wave_struct *ws;
490 	node_data = img->wav_data;
491 	img->wav_to_calc = FALSE;
492 	for (node = img->wav_pages; node; node=node->next) {
493 	//	Got some trouble with signals ordering here,
494 	//	must bring the amplitude to 0 before the adjustment scale,
495 	//	otherwise the amplitude for the 1st page is not modified
496 		ws = (wave_struct *) node_data->data;
497 		ws->amplitude=0;
498 		gtk_adjustment_set_value(
499 		   GTK_ADJUSTMENT(((wave_page_struct *) (node->data))->adj_amplitude),0);
500 		node_data = node_data->next;
501 	}
502 	gtk_notebook_set_page(GTK_NOTEBOOK(img->wav_notebook),0);
503 	img->wav_to_calc = TRUE;
504 }
505 
wave_dialog_new(gpointer data)506 GtkWidget * wave_dialog_new(gpointer data) {
507 
508 	GtkWidget *notebook,*button, *hbox, *vbox;
509 	GtkWidget *dialog;
510 	hf_wrapper_struct *hfw;
511 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
512 
513 	dialog = options_frame_new("Waves");
514 
515 	//	Main dialog box
516 	vbox = gtk_vbox_new(FALSE,0);
517 	gtk_widget_show(GTK_WIDGET(vbox));
518 	gtk_container_add( GTK_CONTAINER(dialog), vbox);
519 
520 	/* Create a new notebook, place the position of the tabs */
521  	notebook = gtk_notebook_new ();
522     	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
523 	gtk_box_pack_start_defaults(GTK_BOX(vbox),notebook);
524     	gtk_widget_show(notebook);
525 
526 	hfw->hf_options->img->wav_notebook = GTK_NOTEBOOK(notebook);
527 
528 	//	Add the 2 default pages, 1 for vertical wave, other for lateral
529 	wave_page_new( hfw->hf_options->img, VERTICAL_WAVE,
530 			hfw->hf_options->tools_window, hfw->hf_options->tooltips, data);
531 
532 	wave_page_new( hfw->hf_options->img, HORIZONTAL_WAVE,
533 			hfw->hf_options->tools_window, hfw->hf_options->tooltips, data);
534 
535 	gtk_notebook_set_page(GTK_NOTEBOOK(hfw->hf_options->img->wav_notebook),0);
536 
537 	hbox = gtk_hbox_new(FALSE,DEF_PAD);
538 	gtk_widget_show(GTK_WIDGET(hbox));
539 
540 	button = gtk_button_new_with_label(_("New"));
541 	gtk_widget_show(GTK_WIDGET(button));
542 	gtk_signal_connect (GTK_OBJECT (button), "clicked",
543 	       (GtkSignalFunc) add_new_wave, data);
544 	gtk_box_pack_start (GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
545 
546 	button = gtk_button_new_with_label(_("Destroy"));
547 	gtk_widget_show(GTK_WIDGET(button));
548 	gtk_signal_connect (GTK_OBJECT (button), "clicked",
549 	       (GtkSignalFunc) delete_current_wave, data);
550 	gtk_box_pack_start (GTK_BOX(hbox), button, FALSE, FALSE, DEF_PAD);
551 
552   	gtk_box_pack_start (GTK_BOX (vbox), align_widget(hbox,0.5,0.5), FALSE, FALSE, DEF_PAD);
553 
554 	gtk_box_pack_start (GTK_BOX (vbox), reset_accept_buttons_new (data, &hfw->hf_options->img->wav_accept), FALSE, FALSE, DEF_PAD);
555 
556 	return dialog;
557 }
558 
waves_callb(GtkWidget * wdg,gpointer data)559 void waves_callb(GtkWidget *wdg, gpointer data) {
560 	hf_wrapper_struct *hfw;
561 	hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data;
562 	if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) {
563 		accept_callb(wdg,data);
564 		return;
565 	}
566 	if (!hfw->hf_options->img->wav_dialog) {
567 		hfw->hf_options->img->wav_dialog = wave_dialog_new(data);
568 		gtk_container_add(GTK_CONTAINER(hfw->hf_options->img->img_dialog),
569 			hfw->hf_options->img->wav_dialog );
570 	//	This callback makes sure that the transformations are not reapplied
571 	//	when we come back in this dialog (I don't know why "set_defaults..." alone
572 	//	doesn't do the job - some notebook pages are still active - 2002.04.17)
573 	//	Probably some strange things are happening with the signals order.
574 		gtk_signal_connect(GTK_OBJECT (hfw->hf_options->img->wav_dialog ), "show",
575 			GTK_SIGNAL_FUNC (reset_callb), data);
576 	}
577 	if (hfw->hf_options->img->current_subdialog)
578 		gtk_widget_hide(hfw->hf_options->img->current_subdialog);
579 	hfw->hf_options->img->current_subdialog = hfw->hf_options->img->wav_dialog;
580 //	set_wave_defaults(hfw->hf_options->img);
581 	hfw->hf_options->img->set_fn = (gpointer) set_wave_defaults;
582 	hfw->hf_options->img->accept_wdg = hfw->hf_options->img->wav_accept;
583 	gtk_widget_show(hfw->hf_options->img->current_subdialog);
584 }
585